fix(apple)!: align profile claims with identity tokens

This commit is contained in:
Taesu
2026-10-16 09:59:00 +09:00
parent 2c7833fad6
commit ad73455231
3 changed files with 41 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@better-auth/core": minor
---
Apple profile callbacks now accept unverified email claims and web sign-in profiles without native-only fields. Profile mappings must handle omitted private-email status, user status, and pictures.
@@ -1,8 +1,8 @@
import { createHash } from "node:crypto";
import type { JWK } from "jose";
import { exportJWK, generateKeyPair, SignJWT } from "jose";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { exportJWK, generateKeyPair, SignJWT, UnsecuredJWT } from "jose";
import { assertType, beforeEach, describe, expect, it, vi } from "vitest";
import type { GenericEndpointContext } from "../types";
vi.mock("@better-fetch/fetch", () => ({
@@ -12,6 +12,7 @@ vi.mock("@better-fetch/fetch", () => ({
import { betterFetch } from "@better-fetch/fetch";
import { verifyProviderIdToken } from "../oauth2";
import type { AppleProfile } from "./apple";
import { apple } from "./apple";
const mockedBetterFetch = vi.mocked(betterFetch);
@@ -169,3 +170,32 @@ describe("apple id_token verification", () => {
expect(seenPlatform).toBe("ios");
});
});
/**
* @see https://developer.apple.com/documentation/signinwithapplejs/authorizationi/id_token
*/
it.each([
[true, true],
[false, false],
["true", true],
["false", false],
] as const)(
"accepts email_verified=%s without native-only claims",
async (emailVerified, expected) => {
const profile = {
sub: "apple-user-123",
name: "",
email_verified: emailVerified,
};
assertType<AppleProfile>(profile);
assertType<AppleProfile>({ ...profile, is_private_email: "true" });
const provider = apple({ clientId: "service.example.app" });
const result = await provider.getUserInfo({
idToken: new UnsecuredJWT(profile).encode(),
});
expect(result?.user.emailVerified).toBe(expected);
expect(result?.data.name).toBe("");
},
);
+4 -4
View File
@@ -30,13 +30,13 @@ export interface AppleProfile {
* Sign in with Apple at Work & School users, and this claim is "false" or
* false for those users.
*/
email_verified: true | "true";
email_verified: boolean | "true" | "false";
/**
* A string or Boolean value that indicates whether the email that the user
* shares is the proxy address. The value can either be a string ("true" or
* "false") or a Boolean (true or false).
*/
is_private_email: boolean;
is_private_email?: boolean | "true" | "false";
/**
* An Integer value that indicates whether the user appears to be a real
* person. Use the value of this claim to mitigate fraud. The possible
@@ -45,7 +45,7 @@ export interface AppleProfile {
* in iOS 14 and later, macOS 11 and later, watchOS 7 and later, tvOS 14
* and later. The claim isn’t present or supported for web-based apps.
*/
real_user_status: number;
real_user_status?: number;
/**
* The user’s full name in the format provided during the authorization
* process.
@@ -54,7 +54,7 @@ export interface AppleProfile {
/**
* The URL to the user's profile picture.
*/
picture: string;
picture?: string;
user?: AppleNonConformUser | undefined;
}