methods/apple/server
For AI agents: see llms.txt for the complete documentation index. Markdown versions are available by adding .md to a page URL or requesting Accept: text/markdown.
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;