diff --git a/docs/guides/auth/hook.md b/docs/guides/auth/hook.md index 50e9764..aa61898 100644 --- a/docs/guides/auth/hook.md +++ b/docs/guides/auth/hook.md @@ -31,7 +31,7 @@ sequenceDiagram User->>+IdP: Authenticate IdP->>-Auth: Authentication success (claims) - Auth->>+Hook: beforeLogin(claims, idpConfigName) + Auth->>+Hook: beforeLogin({ claims, idpConfigName, env }) Hook->>DB: Custom logic (e.g., create user) DB->>Hook: Result Hook->>-Auth: Success / Error @@ -93,8 +93,41 @@ The hook handler receives the following arguments: | Argument | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------ | -| **claims** | object | The claims returned by the Identity Provider (e.g., email, name). | +| **claims** | object | The claims returned by the Identity Provider (e.g., email, name). For Built-in IdP federated logins, also carries [`federated_identity`](#federated-identity-claims). | | **idpConfigName** | string | The name of the IdP configuration that authenticated the user. | +| **env** | object | Environment variables defined in `defineConfig({ env })` (the same values available via `context.env` in resolvers). | + +## Federated Identity Claims + +When a user signs in through a [Built-in IdP](/guides/auth/integration/built-in-idp) OAuth provider (Google or Microsoft), the upstream provider's profile is forwarded to the hook on `claims.federated_identity`. A common use is to populate the user record from the provider's profile during [JIT provisioning](#example-jit-user-provisioning). + +`claims.federated_identity` is `undefined` for any non-federated login (for example, password logins or external IdP flows), so guard before reading it. + +| Field | Type | Description | +| ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **provider** | `"google" \| "microsoft"` | The upstream OAuth provider that federated the login. | +| **claims** | object | Profile claims from the provider's ID token. Commonly present claims (`name`, `given_name`, `family_name`, `picture`, `locale`) are available; any other claim the provider issues is forwarded as-is. | + +Claim availability varies by provider. For example, Microsoft does not issue `picture`. + +```typescript +hooks: { + beforeLogin: { + handler: async ({ claims }) => { + const federated = claims.federated_identity; + if (federated?.provider === "google") { + // Populate the user record from the upstream profile + const avatarUrl = federated.claims.picture; + } + }, + invoker: "hook-invoker", + }, +} +``` + +:::tip +`claims.federated_identity` is a login-flow signal available only inside the `beforeLogin` hook. It is not part of the app-facing session token. Persist whatever your app needs into your own TailorDB type during the hook. +::: ## Example: JIT User Provisioning diff --git a/docs/guides/auth/integration/built-in-idp.md b/docs/guides/auth/integration/built-in-idp.md index cc178fd..f69c031 100644 --- a/docs/guides/auth/integration/built-in-idp.md +++ b/docs/guides/auth/integration/built-in-idp.md @@ -328,6 +328,8 @@ The Built-in IdP supports "Sign in with Google", allowing users to authenticate 4. If the user does not yet exist, a new IdP user is automatically created using the Google account's email address (without a password) 5. The user is signed in and redirected to the application +If you configure a [`beforeLogin` hook](/guides/auth/hook#federated-identity-claims), the Google account's profile (such as `picture`, `name`, `given_name`, `family_name`, and `locale`) is available to it on `claims.federated_identity`, so you can populate your user record from the provider's profile. + :::tip Users created via Google OAuth do not have a password set. They can only sign in using Google. To enable password-based login for these users, use the `_sendPasswordResetEmail` mutation to set an initial password. ::: @@ -379,6 +381,8 @@ The Built-in IdP supports "Sign in with Microsoft", allowing users to authentica 4. If the user does not yet exist, a new IdP user is automatically created using the Microsoft account's preferred username (UPN) (without a password) 5. The user is signed in and redirected to the application +If you configure a [`beforeLogin` hook](/guides/auth/hook#federated-identity-claims), the Microsoft account's profile (such as `name`, `given_name`, and `family_name`) is available to it on `claims.federated_identity`. Microsoft does not issue `picture`. + :::tip Users created via Microsoft OAuth do not have a password set. They can only sign in using Microsoft. :::