* feat: add possibility of adding WebAuthn security keys to use as 2FA
This adds a basic UI for enabling WebAuthn 2FA. We did a little refactor
to the Settings page for editing the 2FA methods – now it will list the
methods that are available to the user (TOTP and WebAuthn) and from
there they'll be able to add or remove any of them.
Also, it's worth mentioning that for enabling WebAuthn it's required to
have TOTP enabled, so the first time that you go to the 2FA Settings
page, you'll be asked to set it up.
This work was inspired by the one donde by Github in their platform, and
despite it could be approached in different ways, we decided to go with
this one given that we feel that this gives a great UX.
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* feat: add request for WebAuthn as second factor at login if enabled
This commits adds the feature for using WebAuthn as a second factor for
login when enabled.
If users have WebAuthn enabled, now a page requesting for the use of a
WebAuthn credential for log in will appear, although a link redirecting
to the old page for logging in using a two-factor code will also be
present.
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* feat: add possibility of deleting WebAuthn Credentials
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* feat: disable WebAuthn when an Admin disables 2FA for a user
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* feat: remove ability to disable TOTP leaving only WebAuthn as 2FA
Following examples form other platforms like Github, we decided to make
Webauthn 2FA secondary to 2FA with TOTP, so that we removed the
possibility of removing TOTP authentication only, leaving users with
just WEbAuthn as 2FA. Instead, users will have to click on 'Disable 2FA'
in order to remove second factor auth.
The reason for WebAuthn being secondary to TOPT is that in that way,
users will still be able to log in using their code from their phone's
application if they don't have their security keys with them – or maybe
even lost them.
* We had to change a little the flow for setting up TOTP, given that now
it's possible to setting up again if you already had TOTP, in order to
let users modify their authenticator app – given that now it's not
possible for them to disable TOTP and set it up again with another
authenticator app.
So, basically, now instead of storing the new `otp_secret` in the
user, we store it in the session until the process of set up is
finished.
This was because, as it was before, when users clicked on 'Edit' in
the new two-factor methods lists page, but then went back without
finishing the flow, their `otp_secret` had been changed therefore
invalidating their previous authenticator app, making them unable to
log in again using TOTP.
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* refactor: fix eslint errors
The PR build was failing given that linting returning some errors.
This commit attempts to fix them.
* refactor: normalize i18n translations
The build was failing given that i18n translations files were not
normalized.
This commits fixes that.
* refactor: avoid having the webauthn gem locked to a specific version
* refactor: use symbols for routes without '/'
* refactor: avoid sending webauthn disabled email when 2FA is disabled
When an admins disable 2FA for users, we were sending two mails
to them, one notifying that 2FA was disabled and the other to notify
that WebAuthn was disabled.
As the second one is redundant since the first email includes it, we can
remove it and send just one email to users.
* refactor: avoid creating new env variable for webauthn_origin config
* refactor: improve flash error messages for webauthn pages
Co-authored-by: Facundo Padula <facundo.padula@cedarcode.com>
* Fix client-side username validation at registration
It used the Account::USERNAME_RE regexp which is for *remote* users,
local user validation is stricter. Also take into account max username length.
* Add client-side form validation for password change
* Add client-side form validation to dedicated registration form
Previous changes only applied to the /about page, not the dedicated form on
/auth
* Add HTML-level validation of username in sign-up form
* Make required fields with incorrect values more visible
* Enable HTML form validation for the registration form
* Mark agreement checkbox as required client-side
* Add minimum length to password
* Add client-side password confirmation validation
- Change audio files to not be stripped of metadata
- Automatically extract cover art from audio if it exists
- Add `thumbnail` parameter to `POST /api/v1/media`, `POST /api/v2/media` and `PUT /api/v1/media/:id`
- Add `icon` to represent it in attachments in ActivityPub
- Fix `preview_url` containing URL of missing missing image when there is no thumbnail instead of null
- Fix duration of audio not being displayed on public pages until the file is loaded
* Fix header button changing header size in settings pages
* Make form buttons look more like a part of the form in settings pages
- Put buttons closer, using same distance as between inputs
- Make buton font size a bit smaller to blend a bit more
- Add the class button to button tags for consisent styling
- Fix audio attachments not being represented in OpenGraph tags
- Fix audio being represented as "1 image" in OpenGraph descriptions
- Fix video metadata being overwritten by paperclip-av-transcoder
- Fix embedded player not using Mastodon's UI
- Fix audio/video progress bars not moving smoothly
- Fix audio/video buffered bars not displaying correctly
* Display appropriate error when performing unpermitted operation on custom emoji
Fixes#13897
* Remove links to custom emoji actions not performable by moderators
* Fix some account avatars on public pages having incorrect size
* Remove outdated and overridden width and height attributes
* Remove more hardcoded width/height attributes
Change `account_link_to` to use an image tag rather than some
inline CSS. Dropped the `size` parameter in the process, but it wasn't
used for anything except the default value of 36px.
Dropped CSS rules that were always overriden, and defaulted to 36px width
and height instead.
* Move .back-button inline styles to CSS file
All occurrences of the back-button CSS class used the same inline
CSS rules, so moved them over to the CSS file
* Fix “Add new domain block” button using inline CSS
* Replace common pattern of inline-styled button boxes by a CSS class
In particular, switching from `float: left/right` to a flexbox with
`justify-content: space-between`. This implied changing the order of
a few HTML tags and adding an empty `div` in one case.
Also removed a `margin-bottom` rule that wasn't needed due to the
margins of surrounding elements.
* Move account admin view inline CSS to CSS file
* Move some inline styles to CSS files
* Move default_account_display_name span to fix useless tags with duplicate id
* Change handling of public pages spoiler text from inline CSS to dataset attribute
* Use the `dir` HTML attribute instead of inline CSS
* Move status action bar inline CSS to CSS file
* Hide logo resources from CSS file, not inline CSS
Fixes#11601
* Move translation prompt styling from inline CSS to CSS file
* Move “invited by” styling on registration form from inline to CSS file
* Use the progress tag to display poll results in JS fallback
* Fix poll results JS-less fallback when the user has voted for an option
* Change account public page “moved” notice to use img tags instead of inline CSS
* Move OTP hint inline CSS to SCSS file
* Hide JS-less fallback vote progressbars from accessibility tools
Co-authored-by: Eugen Rochko <eugen@zeonfederated.com>
This is achieved by sending a DELETE request to
/settings/profile/pictures/{avatar,header} via a link that is part of
the upload form's hint of the respective picture.
* Fix “Email changed” notification sometimes having wrong e-mail
Fixes#6778
The root of the issue is that `send_devise_notification` was called before
the changes were properly commited to the database, causing the mailer to
pick previous values if running too early.
Devise's documentation provides guidance on how to handle that[1][2], however,
I have found it to not be working, as the following happens, in that order:
- `send_devise_notification` is called for the `email_changed` notification.
In that case, `changed?` is false and `saved_changes?` is true, so
if we use the former, we have the same issue.
- the `after_commit` hook is called
- `send_devise_notification` is called for the `confirmation_instructions`
notification.
In that case, `changed?` is still false, and `saved_changes?` still true,
so if we use the latter, that second notification email is simply not
going to be sent (as we would be queuing the notification *after*
executing the after_commit hook).
This is because it may be called from either an `after_update` or
`after_commit` hook, the difference not being a call to `save` but the
transaction actually being committed to the database. This may arguably
be a bug in Devise, or Devise's notification.
The proposed workaround is inspired by Devise's documentation but checks
whether a transaction is open to make the call whether to immediately
send the notification or defer it to the `after_commit` hook.
[1]: https://www.rubydoc.info/github/plataformatec/devise/Devise%2FModels%2FAuthenticatable:send_devise_notification
[2]: 406915cb78/lib/devise/models/authenticatable.rb (L133-L194)
* Fix cases when sending notifications without changing the model
* Defer sending if and only if in transaction including current record
This commit redesign the polls and increases characters limit for the
options from 25 to 50 characters, giving pollsters more freedom.
Summarizing, the redesign is making the polls more adaptive for upcoming
changes to the options characters limit: the bar, or a "chart", is now
displayed separately from the option itself; vote check mark is moved
next to the option text, making the percentages take less space. Option
lengths are taken into account and text is wrapped to multiple lines
if necessary to avoid overflow.
If the “Why do you want to join?” textarea is left empty and the entered params
do not validate, the textarea isn't shown again, unlike other fields.
This commit fixes that by populating an empty `UserInviteRequest` when needed.
This adds "Show thread" button to the status view which is used in
profiles. The logic to display the button is mimicking logic in
web app available at app/javascript/mastodon/components/status.js#L439.
* The little change in components CSS required to remove enforced
underline for all links on public pages on our button.
* Return last_status_at as date, not datetime
* Fix relative timestamp for dates when delay is inferior to 1 day
* Also fix public directory
* Fix error when last_status_at isn't set