From 0fe3590e16cc88c561ebd45cc43edee24e725fd3 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Sun, 31 May 2026 01:51:16 +0100 Subject: [PATCH] test(oauth-provider): adapt merged token/private-key-jwt tests to next's APIs (#9533) These test files auto-merged main's additions onto next's refactored test surface, producing runtime failures tsc could not catch: - token.test.ts called main's sync createRefreshAccessTokenRequest, which next renamed to the async refreshAccessTokenRequest; the calls now await it and the concurrent-rotation helper is async. - private-key-jwt-e2e.test.ts hit the merged-in #9578 gate: both the provider and RP test instances create the same default user, so the OAuth sign-in links to the RP's unverified local user and is blocked. The RP sets requireLocalEmailVerified: false so the test exercises private_key_jwt rather than the (separately covered) email-verification gate. - utils/basic-auth.test.ts is removed: next made basicToClientCredentials private, and its colon-preservation coverage now lives in core's basic-credentials.test.ts. Full oauth-provider suite green (24 files, 378 tests). --- .../src/private-key-jwt-e2e.test.ts | 2 + packages/oauth-provider/src/token.test.ts | 10 ++--- .../src/utils/basic-auth.test.ts | 39 ------------------- 3 files changed, 7 insertions(+), 44 deletions(-) delete mode 100644 packages/oauth-provider/src/utils/basic-auth.test.ts diff --git a/packages/oauth-provider/src/private-key-jwt-e2e.test.ts b/packages/oauth-provider/src/private-key-jwt-e2e.test.ts index 475e5eb5b5..ece7ea6654 100644 --- a/packages/oauth-provider/src/private-key-jwt-e2e.test.ts +++ b/packages/oauth-provider/src/private-key-jwt-e2e.test.ts @@ -124,6 +124,7 @@ describe("private_key_jwt e2e", async () => { account: { accountLinking: { trustedProviders: [providerId], + requireLocalEmailVerified: false, }, }, plugins: [ @@ -265,6 +266,7 @@ describe("private_key_jwt e2e", async () => { account: { accountLinking: { trustedProviders: [providerId], + requireLocalEmailVerified: false, }, }, plugins: [ diff --git a/packages/oauth-provider/src/token.test.ts b/packages/oauth-provider/src/token.test.ts index aa6f813392..b0a4fecb03 100644 --- a/packages/oauth-provider/src/token.test.ts +++ b/packages/oauth-provider/src/token.test.ts @@ -1044,7 +1044,7 @@ describe("oauth token - refresh_token", async () => { expect(tokens?.refresh_token).toBeDefined(); async function refresh(refreshToken: string) { - const { body, headers } = createRefreshAccessTokenRequest({ + const { body, headers } = await refreshAccessTokenRequest({ refreshToken, options: { clientId: oauthClient!.client_id, @@ -1102,7 +1102,7 @@ describe("oauth token - refresh_token", async () => { expect(tokens?.refresh_token).toBeDefined(); async function refresh(refreshToken: string) { - const { body, headers } = createRefreshAccessTokenRequest({ + const { body, headers } = await refreshAccessTokenRequest({ refreshToken, options: { clientId: oauthClient!.client_id, @@ -1180,7 +1180,7 @@ describe("oauth token - refresh_token", async () => { // Reusing the revoked refresh token must trip the family-invalidation // guard in handleRefreshTokenGrant (revoked flag → invalidate family). const { body: replayBody, headers: replayHeaders } = - createRefreshAccessTokenRequest({ + await refreshAccessTokenRequest({ refreshToken: tokens!.refresh_token!, options: { clientId: oauthClient.client_id, @@ -1218,8 +1218,8 @@ describe("oauth token - refresh_token", async () => { expect(tokens?.refresh_token).toBeDefined(); const parentToken = tokens!.refresh_token!; - const refresh = () => { - const { body, headers } = createRefreshAccessTokenRequest({ + const refresh = async () => { + const { body, headers } = await refreshAccessTokenRequest({ refreshToken: parentToken, options: { clientId: oauthClient!.client_id, diff --git a/packages/oauth-provider/src/utils/basic-auth.test.ts b/packages/oauth-provider/src/utils/basic-auth.test.ts deleted file mode 100644 index c10cb7f3b2..0000000000 --- a/packages/oauth-provider/src/utils/basic-auth.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { base64 } from "@better-auth/utils/base64"; -import { describe, expect, it } from "vitest"; - -import { basicToClientCredentials } from "./index"; - -function encodeBasic(clientId: string, clientSecret: string) { - const raw = `${clientId}:${clientSecret}`; - const encoded = base64.encode(new TextEncoder().encode(raw)); - return `Basic ${encoded}`; -} - -/** - * @see https://datatracker.ietf.org/doc/html/rfc7617#section-2 - */ -describe("basicToClientCredentials", () => { - it("preserves colons inside client_secret per RFC 7617", () => { - const clientId = "cid"; - const clientSecret = "pa:ss:word"; - - const result = basicToClientCredentials( - encodeBasic(clientId, clientSecret), - ); - - expect(result).toBeDefined(); - expect(result?.client_id).toBe(clientId); - expect(result?.client_secret).toBe(clientSecret); - }); - - it("keeps a trailing colon as part of client_secret", () => { - const clientId = "cid"; - const clientSecret = "secret:"; - - const result = basicToClientCredentials( - encodeBasic(clientId, clientSecret), - ); - - expect(result?.client_secret).toBe(clientSecret); - }); -});