37 Commits

Author SHA1 Message Date
Stanko K.R. 693415bc71 Rename request options to authentication options 2026-03-25 17:26:49 +01:00
Stanko K.R. 017bcc9ce1 Polish up Passkey interface
- Fix indentation
- Split awkward initializer into separate methods
- Rename credentials to passkeys
- Simplify authenticator registry loading
- Flatten nested errors under ActionPack::WebAuthn
- Set passkey current params only requests that use it
- Inline anemic methods
- Replace custom validation with ActiveModel::Validation
- Rename identity to holder in Passkey
- Rename credentials to passkeys in JS
- Extract framework library out of controllers
- Pass params hashes down to ActionPack
- Attempt to simplify public interface
- Push data decoding down to the classes representing the data
- Introduce has_passkeys
- Add CBOR bigint support
- Rename ActionPack::WebAuthn::Passkey to ActionPack::Passkey
- Add create_passkey_button helper
- Rename public-key to creation-options
- Add sign_in_with_passkey_button helper
- Dispatch events for the whole Passkey lifecycle
- Add ED25519 support
- Prevent crash on missing meta tag
- Validate resident key options
- Don't clobber existing ActionPack config options
- Validate cryptographic params
- Move CurrentWebAuthnRequest into ActionPack::Passkey
- Use ActiveModel::Attributes for Options objects
- Implement expiring challanges
- Add lifecycle events
- Extract param helpers into Request
- Add passkey_creation_options and passkey_request_options helpers
- Add create_passkey_challenge to make it easier to override the create method if needed
- Prefix all view helpers with passkey_
- Auto-include ActionPack::Passkey::Holder
- Make the passkey challange url configurable
- Add a reminder about Passkeys to the magic link email
2026-03-18 11:51:10 +01:00
Stanko K.R. fbe9252db1 Auto-suggest name for new Passkeys
- Use plain client data json everywhere
- Expose AAGUID and backed_up on Credentials
- Make attestation verifiers configurable
- Auto-suggest names for passkeys and show icons
2026-03-18 11:49:59 +01:00
Stanko K.R. da69039476 Implement Passkey authentication 2026-03-18 11:49:23 +01:00
Rosa Gutierrez 614527e9c2 Add JSON format support to signup flow for native API clients
The magic link verification endpoint now returns `requires_signup_completion`
to indicate whether the client needs to collect a name and complete signup.
The signup completion endpoint now supports JSON responses with the account ID.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:41:37 +01:00
Stanko Krtalić eceb6c9b43 Add self-service account deletion (#2246)
* Add self-service account deletion

* Disable access to cancelled accounts & implement Stripe interactions

* Add tests

* Fix failing tests

* Remove cancelled accounts from lists

* Fix incorrect redirect

* Use _path instead of _url for consistency

* Don't track how far the inicieration job got

We still want the step tracking so that the job can be interrupted. But, since the scope is idempotent, we don't need to track how far it got.

* Specify the exact time when the data will be deleted

* Fix crash due to unadvancable cursor

* Rename up_for_incineration to due_for_incineration

* Regenrate the schema

* Fix incorrect path check

* Migrate the SQLite schema

* Only show the cancel button on cancellable accounts

* Check that a subscirption method exists before calling it

* Ignore job failures due to missing records when an account gets deleted

* Skip sending notifications on cancelled accounts

* Use collbacks to integrate

* Add a blank line between queue_as and discard_on

* Break checks into methods

* Inline methods

* Rename Account::IncinerateJob

* Run migrations

* Migrate SQLite
2026-01-12 14:21:05 +01:00
Stanko K.R. ca388c2b84 Replace handle_ naming 2025-12-19 19:21:58 +01:00
Stanko K.R. 52d57c4681 Tidy up session_token 2025-12-19 19:21:57 +01:00
Stanko K.R. e0270c6c49 Clean up interfaces
I talked to the mobile team, and to keep things simple we agreed to send
the token via a cookie.
2025-12-19 19:21:57 +01:00
Stanko K.R. 1a1f4a077b Simplify auth logic 2025-12-19 19:21:57 +01:00
Stanko K.R. c0a0786539 Return the session cookie
We had a call about this. In short, we could reuse access tokens but then the user would see access tokens for every mobile device they have without any indication as to what is going on. So, since this really is just logging in instead of an integration which seems to be the primary purpose of access tokens, we can just use our regular session cookie for authentication.
2025-12-19 19:21:57 +01:00
Stanko K.R. 54ceb4df7c Remove email address and users from magic link response
The identity endpoint can be used to fetch that information
2025-12-19 19:21:57 +01:00
Fernando Olivares 093240c6f7 Return email and users too 2025-12-19 19:21:57 +01:00
Fernando Olivares 7644bb7411 Allow JSON requests submitting a magic link code 2025-12-19 19:21:57 +01:00
Stanko K.R. abaed12124 Prohibit access to magic links unless an email address 2025-12-11 19:17:39 +01:00
Stanko K.R. b6edb93c47 Pin sign in attempts to the current session
This makes it way more difficult to brute-force a magic link.

Original implementation by udiudi. Ref: https://github.com/udiudi/fizzy/pull/1/files

Discussion: https://github.com/basecamp/fizzy/discussions/1981

Co-Authored-By: Udi <udi@udi.codes>
2025-12-11 19:05:54 +01:00
Jason Zimdars 349c617aea Minor copy edit 2025-12-03 12:18:22 -06:00
Kevin McConnell 184a827965 Show alert message on login when rate limited
When the auth-related controllers hit rate limits they set an alert in
the flash. But we weren't displaying the flash on the public layout, so
those were never seen.

Changed to surface the alert. But also change the "Try another code"
message to be shake-only instead, to match the current behaviour.
2025-12-03 11:29:42 +00:00
Stanko K.R. 2311efd03e Make sign up Magic Links work across devices
Previously if someone started signing in on their phone, but finished it on their laptop, they'd end up on the menu screen with no account. Bu tracking the purpose of a Magic Link we can always direct the user to sign up if they requested a magic link through sign up. This also makes the logic for changing the copy in the email more robust.
2025-11-29 12:36:00 +01:00
Stanko K.R. 8fa9566c07 Update sign up 2025-11-17 09:12:40 -05:00
Mike Dalessio 89d1299ec0 Fix authentication on "untenanted" controllers
trying out the name "disallow_account_scope" for this, but I don't
think it's quite right yet.
2025-11-17 09:11:47 -05:00
Mike Dalessio 086a9ceada Revert some auth pieces of "Account.sole → Current.account" 2025-11-17 09:11:45 -05:00
Mike Dalessio d41d50d52b Account.sole → Current.account
and some other de-tenant changes, including removing the controller
tenanting concerns
2025-11-17 09:11:40 -05:00
Stanko K.R. 875515b51d Skip the menu screen if there is just one account 2025-11-04 17:52:31 +01:00
Stanko Krtalić 98755844a1 Remove the internal API
* Bind sessions to identities
* Remove references to the identity token
* Move email changes to identity
* Move account menu into a turbo-frame
* Create tenants from a tenanted route
2025-10-31 16:26:08 +01:00
Jason Zimdars 5652e5699f Update design, logo, and copy 2025-10-31 16:26:08 +01:00
Stanko K.R. 201c3e27d3 Update tests for the Internal API 2025-10-31 16:26:08 +01:00
Stanko K.R. 79b012f319 Add Join Codes 2025-10-31 16:24:30 +01:00
Stanko K.R. c8843360fe Clean up and simplify magic links 2025-10-31 16:23:38 +01:00
Stanko K.R. 5cef4ffeb0 Add sign in flow using magic links 2025-10-31 16:22:12 +01:00
Mike Dalessio 2630e4bd74 Extract 37id and QB controllers, models, and tests 2025-09-13 16:03:02 -04:00
Mike Dalessio 8e13ce5b78 Drop Current.account and just use Account.sole
I had reintroduced this in dacb53b8 after David removed it in
6bbf68a4, but now I agree we don't need it.

Also, fix a CORS error when trying to redirect a user to an untenanted
path after login (see
https://fizzy.37signals.com/5986089/collections/2/cards/1032).
2025-07-20 13:00:09 -04:00
Mike Dalessio e69023993c Make sure users can't login from launchpad if they're deactivated
Just in case the SignalId::User deletion failed.
2025-07-15 18:47:38 -04:00
Mike Dalessio fa1c5f7279 Remove session controller actions other than delete
and do some general cleanup around sessions controllers and the
sign_in_as test helper
2025-07-02 15:03:28 -04:00
Mike Dalessio 2c18173f08 Trampoline the Launchpad auth redirect from a GET into a POST
to always route it to the writer.
2025-06-20 15:16:57 -04:00
Mike Dalessio dacb53b8b1 Launchpad login works for existing 37id identities 2025-06-20 15:16:56 -04:00
Jason Zimdars 592c88e639 Add session transfer feature 2024-12-18 12:38:53 -06:00