OAuth-acceptable invites: let an invited user accept via Google/GitHub instead of passkey-only #1859
Replies: 1 comment
|
Related from the plugin side: I published emdash-better-auth (npm: To be clear about scope so this isn't mistaken for a fix for this exact request: it solves the general "sign in with Google/GitHub" surface, not the invite-accept flow you're describing. The invite path ( Where it might reduce the pressure here: once a person exists as a Since I'm already building on Better Auth (which ships |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Today an invite can only be accepted by registering a passkey. There is no way to invite a specific person by email and have them accept (and later sign in) with OAuth (Google/GitHub). For teams whose members prefer social login, the only workarounds are opening a whole email domain via
allowed_domains, or hand-inserting ausersrow into D1. Neither is per-email and UI-driven.I would like to propose OAuth-acceptable invites: if an invitee follows their invite link and signs in with a provider whose verified email matches the invited address, complete the invite (create the user, link the OAuth account) instead of requiring a passkey.
Current behavior (v0.25.1, Cloudflare Workers)
api/auth/invite/completecallsverifyRegistrationResponse+registerPasskey, and only then doescompleteInvite(...)create the user. There is no OAuth branch anywhere in the invite flow (accept/register-options/complete).user_exists: 409if one already exists), so an invited-but-not-completed person is not yet ausersrow.canSelfSignup, which checks theallowed_domainstable.api/admin/usersis GET-only;users/[id]is GET/PUT;enable/disable/send-recoveryare POSTs that all operate on existing users. There is no supported way to pre-create a user by email + role short of a direct D1INSERT.Net result: to let one specific person sign in with Google, you must either enable their whole email domain for self-signup, or write a
usersrow by hand.Why it matters
allowed_domainsis too coarse when you want one person from a shared company domain (for example a single contractor at@company.com) but not the whole company.Proposed behavior
On the invite-accept page, alongside "Register a passkey", offer the site's configured OAuth providers. If the invitee authenticates and the provider-verified email equals the invited email, complete the invite: create the user with the invited role and link the OAuth account. Optionally, let the inviter restrict which auth methods a given invite allows.
This keeps per-email control (it is still an explicit invite); it only widens how the invite can be accepted.
Alternatives considered
allowed_domainsself-signup: works, but is domain-wide and cannot scope to a single address.usersINSERT in D1: works (an existing row plus a matching verified OAuth email signs in fine), but needs database access, has no UI or API, and is easy to get wrong.Contributing
Happy to open a PR for this if the direction sounds right. My read is it would live in the invite accept flow plus the OAuth callback, gated on the provider-verified email matching the invited email, so per-email control is preserved.
Environment
authMode: passkey, withauthProviders: [google(), github()]configuredAll reactions