Chrissi

Hi guys, I have a question about the userforms module - is there a way to disable the ability to add the “file upload” field? Like remove it from the list of options for field type.

andante

looks like the list of types comes from here: https://github.com/silverstripe/silverstripe-userforms/blob/1b193b5ce4ec047677bb41ba220b23e2c6982d6d/code/Extension/UserFormFieldEditorExtension.php#L76 so your best bet might be to extend EditableFormField and override the getEditableFieldClasses() classes to exclude upload field

Show 1 attachment(s)
code/Extension/UserFormFieldEditorExtension.php:76

        $fieldClasses = singleton(EditableFormField::class)->getEditableFieldClasses();
Hide attachment content
andante
  1. Silverstripe\Whatever\Namespace\UploadField:
  2. hidden: true
Chrissi

Hi guys, I am dealing with quite a tough bug. I am wondering if anyone can help. I am trying to use the MFA/TOTP login module on SilverStripe 4.5. When I test it on my dev machine, everything is peachy. I can register, use my authenticator app, get a code, use it, and login. It all works great. I am using a docker setup which is theoretically identical to staging/production aside from SSL certificates/etc.

However, when I deploy this code to staging, nobody is able to complete the TOTP registration on the staging server. I am not missing the SS_MFA_SECRET_KEY, the module passes that point.

Adding more details as a thread since this is getting long.

Chrissi

The error we get is upon trying to register and enter the TOTP code for the first time. We consistently get an error displayed to the user “Provided code is not valid.“, as though we had mistyped the TOTP code. However, I’m quite certain we did not. We’ve tried many times, on several computers, from several people. It consistently throws this error about the code being invalid, but ONLY on the staging server. On my local development server it always works fine.

I’ve tried: • registering/logging in through several different user accounts • spoofing the staging server URL with my dev environment (as well as using a trusted self-signed cert for the URL), in case the domain made a difference. It does not. Dev environment still succeeds MFA registration. • changing the SS_MFA_SECRET_CODE • removing/re-adding the authenticator entry • running dev/build after any changes to anything, • refreshing the database from production on both dev and stage, etc • setting dev environment variable to ‘test’ (dev still succeeds) • entering the registration code into the authenticator app via the manual code, as well as the scanned barcode - still fails on stage and succeeds on dev This is really stumping me. At this point I can’t see any difference in the code or environment or platform or SSL or ANYTHING, between dev and stage, and still cannot reproduce the failure on my dev environment, and cannot get stage to succeed at MFA TOTP registration. This is beyond confusing. Anyone have any leads?

andante

make sure your times/locales or whatever are the same

andante

ive had that with lots of servers where the time my server had was different to the time of my device by enough to render the codes invalid

andante

also check the time on the db, and any other thing that might have a timestamp

andante

make sure they are all UTC or something, you know>

👍 (1)
Chrissi

Hmmmm, what the heck! 🤯 The MySQL clock appears to be about 5 minutes behind the server clock. Could that do it?

Chrissi

Or, wait. It just seems the server is 5 minutes behind, period. Not just MySQL.

Chrissi
  1. [reng@eocwebsite1 html]$ date
  2. Fri Jan 31 17:35:49 UTC 2020

SELECT NOW();: 2020-01-31 17:35:04

The real time ought to be 17:42 I think…

andante

Yep. That would do it. Because the codes are only valid for 60 seconds or so right?

Chrissi

Right. I have to admit I don’t entirely know how it invalidates the codes - are they generated based on the current time? So the time on my phone in the authenticator app, being different than the server time, would be providing invalid codes (from the server’s perspective)?

andante

If your phone says 17:42 but the server says 17:35, the codes wont match

Chrissi

That makes sense! THANK YOU so much!!! I don’t think I ever would have gotten that. It seems that’s the problem.

Chrissi

Now to try to fix it. Lol. We don’t own the staging server. I am not sure if I can re-sync the time somehow.

andante

Talk to the hosting company, let them know the problem. Maybe theres a universal time server you can sync to or whatever

Scopey

Note that the MySQL clock won't matter, it'll be the system clock on whatever server is running PHP

Scopey

So ssh into your server that runs php and check the clock with date

Scopey

Oh, you said the server is, not just mysql. Sorry for the noise!

Scopey

Cool to see people using this though 😎 . The MFA project was fun to work on

null

Saw your issue, immediately thought of the clocks 😄 Glad you got it sorted!

null

The shared secret is time dependent, so if it's more than a minute or so out of date, the code will either be incorrect or the window to enter it will be too short

null

Some server implementations compensate for this by allowing a few recent codes to be valid, but I'm not sure if the Silverstripe totp-authenticator does this

Scopey

We do, the library supports this by default out of the box

Scopey

Ah, actually, we don't set a window by default

Firesphere

The window has an error margin of 5 seconds by default in the library... not 5 minutes, for very obvious reasons

Chrissi

Thanks everyone!! I’m pretty dang sure it’s the server time throwing it off and am trying to get that fixed with the sever owners. 😄 I’m so glad this channel’s full of such helpful friendly people!

Firesphere

Best solution is making sure your server has NTPD and syncs regularly 🙂


Show less replies
Chrissi

I did $fields->insertAfter('ChildPages', Tab::create('PopularResources')); and that got me what I was looking for.

Chrissi

eg $fields->insertBefore('Root.Main', Tab::create('PopularResources')); -> ends up with ‘Popular resources’ text sitting at the bottom of the page

Chrissi

That does not seem to work. I end up with the tab name in text at the bottom of the main tab.

Chrissi

Do you have sample code? It’s not a FormFIeld, it’s a tab, so in the signature for insertBefore I have no $item to insert.

Chrissi

It’s a tab though… so not sure how to insert?

Chrissi

Can I re-order tabs for a page in the CMS? eg. in getCMSFields() I have $fields->findOrMakeTab('Root.PopularResources'); but this always puts it at the end, since other tabs are being created by extensions etc. Can I insert a tab in the middle of the tab list somehow?