mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-20 20:26:55 -05:00
fix(apple)!: align profile claims with identity tokens
This commit is contained in:
@@ -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("");
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user