methods/apple/server
The apple sign-in method, exported at
@convex-dev/auth/methods/apple/server.
Type Aliases
AppleOptions
type AppleOptions = object;
App-defined config for setting up the apple method.
Properties
AppleProfile
type AppleProfile = Infer<typeof vAppleProfile>;
SanitizedAppleUser
type SanitizedAppleUser = object;
Only the name parts are returned after sanitizing.
Properties
| Property | Type |
|---|---|
name | object |
name.firstName? | string |
name.lastName? | string |
Variables
vAppleProfile
const vAppleProfile: VObject<{
email?: string;
emailVerified: boolean;
id: string;
name?: string;
}, {
email: VString<string | undefined, "optional">;
emailVerified: VBoolean<boolean, "required">;
id: VString<string, "required">;
name: VString<string | undefined, "optional">;
}, "required", "id" | "email" | "name" | "emailVerified">;
The account profile that the apple method produces. Apple is OIDC, so
identity comes from validated id_token claims, with the name (when there
is one) coming from the callback instead. This is the exact shape the
mapping emits, so the app can validate against it precisely.
Functions
normalizeAppleProfile()
function normalizeAppleProfile(claims, user): object;
Map Apple's validated id_token claims, plus the sanitized name from a first authorization, to AppleProfile.
user is undefined on every sign-in after the first, which is why the
profile's name is optional. An app that wants to keep the name should
store it when it arrives and leave the stored one alone when it doesn't.
Parameters
| Parameter | Type |
|---|---|
claims | OidcClaims |
user | SanitizedAppleUser | undefined |
Returns
object
email?
optional email?: string;
emailVerified
emailVerified: boolean;
id
id: string;
name?
optional name?: string;
setupApple()
function setupApple<UsersTable>(core, options): object;
Built-in sign-in method for Apple ("Sign in with Apple"). Wire it up with the Apple oauth component:
const auth = setupConvexAuth({ component: components.auth });
export const { signOut, refreshSession, isAuthenticated } = auth;
export const { startSignInWithApple, completeSignInWithApple } = setupApple(auth, {
component: components.authApple,
allowedRedirectOrigins: ["https://app.example.com", "http://localhost:5173"],
}).attachUserCallbacks({ createUser: internal.users.createUserApple });
Setup:
- Install the component in convex.config.ts under
httpPrefix: "/oauth/apple", binding the Services ID, team id, key id, and.p8private key. - Register
<site-url>/oauth/apple/callbackas a return URL on the Services ID, along with theconvex.sitedomain it is on.
The httpPrefix alone determines the callback URL, on the deployment's
convex.site host. Apple has to accept that host as a return URL and
rejects localhost and IP addresses, so the deployment has to be publicly
reachable. The app the flow returns to is unaffected and can stay on
localhost.
Type Parameters
| Type Parameter |
|---|
UsersTable extends string |
Parameters
| Parameter | Type |
|---|---|
core | AuthCore<UsersTable> |
options | AppleOptions |
Returns
attachUserCallbacks()
attachUserCallbacks(callbacks): object;
Supply the app's user callbacks (see UserCallbacks for how their args must be declared) and get the functions of this method to export.
Parameters
| Parameter | Type |
|---|---|
callbacks | UserCallbacks<"apple", { email?: string; emailVerified: boolean; id: string; name?: string; }, UsersTable> |
Returns
object
completeSignInWithApple
completeSignInWithApple: RegisteredMutation<"public", {
code: string;
state: string;
}, Promise<
| {
status: "complete";
tokens: {
accessToken: string;
refreshToken: string;
refreshTokenExpiresAt: number;
userId: string;
};
}
| {
status: "error";
userError: {
error: "INVALID_CODE";
};
}>> = completeSignIn;
startSignInWithApple
startSignInWithApple: RegisteredMutation<"public", {
redirectTo: string;
}, Promise<{
redirect: string;
state: string;
}>> = startSignIn;