Skip to content

Update auth pages visually#6479

Open
sanne-san wants to merge 6 commits into
masterfrom
sanne-auth-pages
Open

Update auth pages visually#6479
sanne-san wants to merge 6 commits into
masterfrom
sanne-auth-pages

Conversation

@sanne-san

@sanne-san sanne-san commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Create new auth layout context that looks visually cleaner, and hides the header and footer
  • Transform all auth pages to use the new context. This includes:
    • Login page
    • Signup page
    • Password reset page
    • Password reset request page
    • Password reset request success page
    • Password reset error page
    • Activate account page
    • Verify 2FA page
    • Verify 2FA recovery code page
    • SSO login page
    • SSO provision notice page
    • SSO provision issue page
    • Invitation expired page
  • Tighten copy across auth pages to be more consistent and concise
  • Remove password conformation field from signup page
  • Extract password field to a new component with visibility toggle
  • Extract Plausible logo to a new component
  • Ensure first field on any page is in focus

Tests

  • Automated tests have been added

Changelog

  • Entry has been added to changelog

Documentation

  • Docs have been updated

Dark mode

  • The UI has been tested both in dark and light mode

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Preview environment👷🏼‍♀️🏗️
PR-6479

- Create new auth layout context that looks visually cleaner, and hides the header and footer
- Transform all auth pages to use the new context. This includes:
  - Login page
  - Signup page
  - Password reset page
  - Password reset request page
  - Password reset request success page
  - Password reset error page
  - Activate account page
  - Verify 2FA page
  - Verify 2FA recovery code page
  - SSO login page
  - SSO provision notice page
  - SSO provision issue page
  - Invitation expired page
- Tighten copy across auth pages to be more consistent and concise
- Remove password conformation field from signup page
- Extract password field to a new component with visibility toggle
- Extract Plausible logo to a new component
@sanne-san sanne-san requested a review from a team July 6, 2026 09:10
Comment thread lib/plausible_web/templates/auth/activate.html.heex
Comment on lines +326 to +332
oninput_js =
"this.value=this.value.replace(/[^0-9]/g, '');" <>
if assigns.autosubmit? do
" if (this.value.length >= #{assigns.length}) this.form.requestSubmit();"
else
""
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, non-blocking: With the autosubmit feature in Activate account feature, it's quite easy to hit the rate limiter, which leads to a frustrating "Rate limited. Go to homepage (actually lands you back on Activate account feature)" experience. Can we treat autosubmitting activation codes as a separate extra feature from the bulk of the changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@apata I reverted to the original behaviour, and I also changed the flow to an inline message instead of a separate page for a less frustrating experience:

CleanShot 2026-07-06 at 17 09 27@2x

Comment thread lib/plausible_web/templates/auth/password_reset_request_form.html.heex Outdated
@sanne-san sanne-san requested review from aerosol and apata July 6, 2026 15:35
post(conn, "/login", email: user.email, password: "wrong")
end)

assert logs =~ "[warning] [login] wrong password for #{user.email}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

)

assert html_response(response, 429) =~ "Too many activation attempts"
assert html_response(response, 200) =~

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for changing from 429 to 200?

@sanne-san sanne-san Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aerosol we switched the rate-limit from a full-page 429 error to an inline error on the /activate page itself for better UX (see this convo). Since inline errors are rendered as a normal form render rather than an error page, I thought the status is 200 instead of 429. Would you prefer if we keep 429 instead?

end
}
onclick="this.select();"
<div class={[@class, "flex flex-col gap-y-6 items-center"]}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This produces broken input length in settings

Image

render(conn, "activate.html",
error: "Incorrect activation code",
render_auth_page(conn, "activate.html",
error: "That code didn't work. Please try again.",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit inconsistent - we're rendering wrong activation code error inline, under the input, but now wrong 2FA code at login is indicated by the flash. Same with wrong recovery code.

</:footer>
</.focus_box>
<% else %>
<.styled_link method="delete" href="/me?redirect=/register">change email</.styled_link>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we deliberately dropping the confirmation dialog?

@sanne-san sanne-san Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah deliberate, at this point in the flow it's not really a destructive action. Clicking 'change email' and then being asked 'Deleting your account cannot be reversed. Are you sure?' sounds quite alarming for what's essentially 'let me fix a typo/use a different email'.

@RobertJoonas RobertJoonas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! 👏 Happy to see much less classname duplication and more extracted reusable components :)

else
{:error, :wrong_password} ->
Auth.log_failed_login_attempt("wrong password for #{email}")
Auth.log_failed_login_attempt("Incorrect password for #{email}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message is not exposed to the user so I would revert this change. There might be a Grafana graph somewhere that depends on the word "wrong".

Comment on lines +56 to +57
<%= if ee?() do %>
<%= on_ee do %>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the outer if block can be removed here.

Comment thread lib/plausible_web/router.ex Outdated
Comment on lines +414 to +420
scope alias: Live,
assigns: %{
connect_live_socket: true,
hide_header?: true,
hide_footer?: true,
disable_global_notices?: true
} do

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the new AuthLayoutContext is responsible for putting the :auth layout, what do you think if we move these layout-related assigns there too?

def on_mount(_arg, _params, _session, socket) do
  socket =
    assign(socket,
      hide_header?: true,
      hide_footer?: true,
      disable_global_notices?: true
    )

  {:cont, socket, layout: {PlausibleWeb.LayoutView, :auth}}
end

end)

assert logs =~ "[warning] [login] wrong password for #{user.email}"
assert logs =~ "[warning] [login] Incorrect password for #{user.email}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: this log is for internal use. Best to revert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants