Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement UI for 2FA setup and verification #3541

Merged
merged 55 commits into from
Dec 6, 2023
Merged

Implement UI for 2FA setup and verification #3541

merged 55 commits into from
Dec 6, 2023

Conversation

zoldar
Copy link
Contributor

@zoldar zoldar commented Nov 21, 2023

Changes

This PR implements controller level logic and UI views for 2FA.

The setting section is hidden behind a feature flag so that the visibility of the feature can be enabled any time after production deployment.

Description of changes

When implemening UI, we have stuck to standard views as LV wouldn't improve user experience in any meaningful way.

The most important part is implementation of controller level logic for 2FA. Most of it is in AuthController and PlausibleWeb.TwoFactor. I have spiked a refactor extracting all things related to settings and user management from AuthController (creating another one, called UserController) but decided against doing it now as that would be too many things changing at once and 2FA implementation on its own is pretty big anyway.

The controller actions lean on Auth.TOTP API but they also layer logic related to session and cookie management on top. The moment the user with 2FA enabled logs in with their email and password, a dedicated session cookie is created for them (session_2fa), which records the fact that user has authenticated with first factor already but they haven't yet completed the second one. Only after the second factor is completed, the proper user session is setup on 2FA session is discarded. The lifetime of 2FA session is strictly limited to 5 minutes. If user does not verify their second factor within that timeframe, they will have to start over. This mechanism is meant to minimize risk of leaving half-authenticated session for extended period of time. The 2FA session is also invalidated the moment the user enters auth views outside second factor verification, including login. The session is stored in an encrypted cookie - a numerical user ID is stored there, so data is treated as sensitive.

Another 2FA aspect managed by auth controller is remembering trusted device. When a user checks "Trust this device for 30 days" when verifying the second factor (applies only to TOTP codes, not recovery ones), a separate cookie is created with expiry time 30 days in the future. This cookie is encrypted as well and contains TOTP token set at the time when the cookie was created. If the cookie is set and token inside it matches token stored for user, 2FA validation step is skipped after login even if 2FA is enabled. The cookie is cleared when 2FA is disabled or password is reset. It's cleared also when verifying 2FA without trusting (for instance, when running 2FA verification against another account in the same browser without setting trust checkbox).

TODO before deployment

  • extract migration adding totp_token and run it before deploying the rest

Tests

  • Automated tests have been added
  • This PR does not require tests

Changelog

  • Entry has been added to changelog
  • This PR does not make a user-facing change

Documentation

  • Docs have been updated
  • This change does not need a documentation update

Dark mode

  • The UI has been tested both in dark and light mode
  • This PR does not change the UI

@zoldar zoldar added the deploy-to-staging Special label that triggers a deploy to a staging environment label Nov 21, 2023
@zoldar zoldar force-pushed the feat/2fa-final branch 11 times, most recently from 8b844a4 to 8ef2857 Compare November 28, 2023 08:37
@zoldar zoldar changed the base branch from master to feat/2fa-prelude November 28, 2023 09:19
Base automatically changed from feat/2fa-prelude to master November 28, 2023 14:29
@zoldar zoldar force-pushed the feat/2fa-final branch 5 times, most recently from b155e63 to e86dc1e Compare November 29, 2023 12:55
@zoldar zoldar changed the title [WIP] Implement UI for 2FA setup and verification Implement UI for 2FA setup and verification Nov 29, 2023
@zoldar zoldar force-pushed the feat/2fa-final branch 2 times, most recently from 8ca7763 to 7a69af4 Compare November 30, 2023 08:11
@zoldar zoldar requested a review from a team November 30, 2023 08:50
@zoldar zoldar marked this pull request as ready for review November 30, 2023 08:50
@aerosol
Copy link
Member

aerosol commented Dec 4, 2023

Ouch, there's some conflicts to be dealt with

lib/plausible_web/components/generic.ex Outdated Show resolved Hide resolved
lib/plausible_web/two_factor.ex Outdated Show resolved Hide resolved
lib/plausible_web/two_factor.ex Outdated Show resolved Hide resolved
@zoldar zoldar merged commit da0fa6c into master Dec 6, 2023
5 checks passed
@zoldar zoldar deleted the feat/2fa-final branch December 6, 2023 11:01
@zoldar zoldar mentioned this pull request Dec 6, 2023
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deploy-to-staging Special label that triggers a deploy to a staging environment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants