diff --git a/.changeset/paypal-profile-types.md b/.changeset/paypal-profile-types.md new file mode 100644 index 0000000000..2ccfde63a6 --- /dev/null +++ b/.changeset/paypal-profile-types.md @@ -0,0 +1,5 @@ +--- +"@better-auth/core": minor +--- + +PayPal profile callbacks now accept identities without personal profile permissions. Missing email verification defaults to `false`; profile mappings must handle omitted names, email, and verification claims. diff --git a/packages/core/src/social-providers/paypal.test.ts b/packages/core/src/social-providers/paypal.test.ts index dd396bddbb..344e7a4d46 100644 --- a/packages/core/src/social-providers/paypal.test.ts +++ b/packages/core/src/social-providers/paypal.test.ts @@ -1,6 +1,6 @@ import { betterFetch } from "@better-fetch/fetch"; import { SignJWT } from "jose"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { assertType, beforeEach, describe, expect, it, vi } from "vitest"; import type { PayPalProfile } from "./paypal"; import { paypal } from "./paypal"; @@ -209,4 +209,25 @@ describe("paypal.getUserInfo", () => { expect(result).toBeNull(); }); + + /** + * @see https://www.postman.com/paypal/paypal-public-api-workspace/request/p607bjm/user-info + */ + it("accepts PayPal user info without personal profile permissions", async () => { + const data = { user_id: "paypal-user", sub: "paypal-subject" }; + assertType(data); + mockedBetterFetch.mockResolvedValueOnce(userInfoResponse(data)); + + const result = await paypal(options).getUserInfo({ + accessToken: "paypal-access-token", + }); + + expect(result?.data).toEqual(data); + expect(result?.user).toEqual({ + name: undefined, + email: undefined, + image: undefined, + emailVerified: false, + }); + }); }); diff --git a/packages/core/src/social-providers/paypal.ts b/packages/core/src/social-providers/paypal.ts index 722ad91f90..3b12b02953 100644 --- a/packages/core/src/social-providers/paypal.ts +++ b/packages/core/src/social-providers/paypal.ts @@ -16,13 +16,13 @@ import { export interface PayPalProfile { sub?: string | undefined; user_id: string; - name: string; - given_name: string; - family_name: string; + name?: string; + given_name?: string; + family_name?: string; middle_name?: string | undefined; picture?: string | undefined; - email: string; - email_verified: boolean; + email?: string; + email_verified?: boolean; gender?: string | undefined; birthdate?: string | undefined; zoneinfo?: string | undefined; @@ -215,7 +215,7 @@ export const paypal = (options: PayPalOptions) => { name: userInfo.name, email: userInfo.email, image: userInfo.picture, - emailVerified: userInfo.email_verified, + emailVerified: userInfo.email_verified ?? false, ...userMap, }, data: userInfo,