diff --git a/.changeset/three-dancers-hear.md b/.changeset/three-dancers-hear.md new file mode 100644 index 00000000000..dab81f5fe3f --- /dev/null +++ b/.changeset/three-dancers-hear.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Consolidate custom jwt and custom auth endpoint through common endpoint diff --git a/packages/thirdweb/src/wallets/in-app/core/authentication/authEndpoint.ts b/packages/thirdweb/src/wallets/in-app/core/authentication/authEndpoint.ts index 2b438732d44..7e4125cc1e6 100644 --- a/packages/thirdweb/src/wallets/in-app/core/authentication/authEndpoint.ts +++ b/packages/thirdweb/src/wallets/in-app/core/authentication/authEndpoint.ts @@ -1,34 +1,37 @@ import type { ThirdwebClient } from "../../../../client/client.js"; -import { getSessionHeaders } from "../../native/helpers/api/fetchers.js"; +import { getClientFetch } from "../../../../utils/fetch.js"; import { ROUTE_AUTH_ENDPOINT_CALLBACK } from "../../native/helpers/constants.js"; import { createErrorMessage } from "../../native/helpers/errors.js"; -import type { ClientScopedStorage } from "./client-scoped-storage.js"; +import type { Ecosystem } from "../wallet/types.js"; import type { AuthStoredTokenWithCookieReturnType } from "./types.js"; export async function authEndpoint(args: { payload: string; client: ThirdwebClient; - storage: ClientScopedStorage; + ecosystem?: Ecosystem; }): Promise { - const resp = await fetch(ROUTE_AUTH_ENDPOINT_CALLBACK, { + const clientFetch = getClientFetch(args.client, args.ecosystem); + + const res = await clientFetch(ROUTE_AUTH_ENDPOINT_CALLBACK, { method: "POST", headers: { - ...getSessionHeaders(), + "Content-Type": "application/json", }, body: JSON.stringify({ payload: args.payload, developerClientId: args.client.clientId, }), }); - if (!resp.ok) { - const error = await resp.json(); + + if (!res.ok) { + const error = await res.json(); throw new Error( `Custom auth endpoint authentication error: ${error.message}`, ); } try { - const { verifiedToken } = await resp.json(); + const { verifiedToken } = await res.json(); return { storedToken: verifiedToken }; } catch (e) { diff --git a/packages/thirdweb/src/wallets/in-app/core/authentication/guest.ts b/packages/thirdweb/src/wallets/in-app/core/authentication/guest.ts index 1417d15779b..3d2ee20da0a 100644 --- a/packages/thirdweb/src/wallets/in-app/core/authentication/guest.ts +++ b/packages/thirdweb/src/wallets/in-app/core/authentication/guest.ts @@ -29,25 +29,22 @@ export async function guestAuthenticate(args: { } const clientFetch = getClientFetch(args.client, args.ecosystem); - const authResult = await (async () => { - const path = getLoginCallbackUrl({ - authOption: "guest", - client: args.client, - ecosystem: args.ecosystem, - }); - const res = await clientFetch(`${path}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - sessionId, - }), - }); + const path = getLoginCallbackUrl({ + authOption: "guest", + client: args.client, + ecosystem: args.ecosystem, + }); + const res = await clientFetch(`${path}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + sessionId, + }), + }); - if (!res.ok) throw new Error("Failed to generate guest account"); + if (!res.ok) throw new Error("Failed to generate guest account"); - return (await res.json()) satisfies AuthStoredTokenWithCookieReturnType; - })(); - return authResult; + return (await res.json()) satisfies AuthStoredTokenWithCookieReturnType; } diff --git a/packages/thirdweb/src/wallets/in-app/core/authentication/jwt.ts b/packages/thirdweb/src/wallets/in-app/core/authentication/jwt.ts index 139c353b81e..d7b75e5b12f 100644 --- a/packages/thirdweb/src/wallets/in-app/core/authentication/jwt.ts +++ b/packages/thirdweb/src/wallets/in-app/core/authentication/jwt.ts @@ -1,19 +1,21 @@ import type { ThirdwebClient } from "../../../../client/client.js"; -import { getSessionHeaders } from "../../native/helpers/api/fetchers.js"; +import { getClientFetch } from "../../../../utils/fetch.js"; import { ROUTE_AUTH_JWT_CALLBACK } from "../../native/helpers/constants.js"; import { createErrorMessage } from "../../native/helpers/errors.js"; -import type { ClientScopedStorage } from "./client-scoped-storage.js"; +import type { Ecosystem } from "../wallet/types.js"; import type { AuthStoredTokenWithCookieReturnType } from "./types.js"; export async function customJwt(args: { jwt: string; client: ThirdwebClient; - storage: ClientScopedStorage; + ecosystem?: Ecosystem; }): Promise { - const resp = await fetch(ROUTE_AUTH_JWT_CALLBACK, { + const clientFetch = getClientFetch(args.client, args.ecosystem); + + const res = await clientFetch(ROUTE_AUTH_JWT_CALLBACK, { method: "POST", headers: { - ...getSessionHeaders(), + "Content-Type": "application/json", }, body: JSON.stringify({ jwt: args.jwt, @@ -21,13 +23,14 @@ export async function customJwt(args: { }), }); - if (!resp.ok) { - const error = await resp.json(); + if (!res.ok) { + const error = await res.json(); throw new Error(`JWT authentication error: ${error.message}`); } try { - const { verifiedToken } = await resp.json(); + const { verifiedToken } = await res.json(); + return { storedToken: verifiedToken }; } catch (e) { throw new Error( diff --git a/packages/thirdweb/src/wallets/in-app/native/helpers/api/fetchers.ts b/packages/thirdweb/src/wallets/in-app/native/helpers/api/fetchers.ts index e4ef3d6fd71..86e4e3f6373 100644 --- a/packages/thirdweb/src/wallets/in-app/native/helpers/api/fetchers.ts +++ b/packages/thirdweb/src/wallets/in-app/native/helpers/api/fetchers.ts @@ -19,7 +19,7 @@ const ECOSYSTEM_PARTNER_ID_HEADER = "x-ecosystem-partner-id"; let sessionNonce: Hex | undefined = undefined; -export function getSessionHeaders() { +function getSessionHeaders() { if (!sessionNonce) { sessionNonce = randomBytesHex(16); } diff --git a/packages/thirdweb/src/wallets/in-app/native/native-connector.ts b/packages/thirdweb/src/wallets/in-app/native/native-connector.ts index 16ac2358d15..57db63615cf 100644 --- a/packages/thirdweb/src/wallets/in-app/native/native-connector.ts +++ b/packages/thirdweb/src/wallets/in-app/native/native-connector.ts @@ -199,13 +199,13 @@ export class InAppNativeConnector implements InAppConnector { return customJwt({ jwt: params.jwt, client: this.client, - storage: this.storage, + ecosystem: this.ecosystem, }); case "auth_endpoint": return authEndpoint({ payload: params.payload, client: this.client, - storage: this.storage, + ecosystem: this.ecosystem, }); default: throw new Error(`Unsupported authentication type: ${strategy}`); diff --git a/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts b/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts index bb1f8473f97..69bc50c88fc 100644 --- a/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts +++ b/packages/thirdweb/src/wallets/in-app/web/lib/web-connector.ts @@ -4,8 +4,10 @@ import { webLocalStorage } from "../../../../utils/storage/webStorage.js"; import type { SocialAuthOption } from "../../../../wallets/types.js"; import type { Account } from "../../../interfaces/wallet.js"; import { getUserStatus } from "../../core/actions/get-enclave-user-status.js"; +import { authEndpoint } from "../../core/authentication/authEndpoint.js"; import { ClientScopedStorage } from "../../core/authentication/client-scoped-storage.js"; import { guestAuthenticate } from "../../core/authentication/guest.js"; +import { customJwt } from "../../core/authentication/jwt.js"; import { getLinkedProfilesInternal, linkAccount, @@ -268,8 +270,11 @@ export class InAppWebConnector implements InAppConnector { }); } - async loginWithAuthToken(authResult: AuthStoredTokenWithCookieReturnType) { - return this.auth.loginWithAuthToken(authResult); + async loginWithAuthToken( + authResult: AuthStoredTokenWithCookieReturnType, + recoveryCode?: string, + ) { + return this.auth.loginWithAuthToken(authResult, recoveryCode); } /** @@ -292,20 +297,22 @@ export class InAppWebConnector implements InAppConnector { client: this.client, ecosystem: this.ecosystem, }); + case "auth_endpoint": { + return authEndpoint({ + payload: args.payload, + client: this.client, + ecosystem: this.ecosystem, + }); + } case "jwt": - return this.auth.authenticateWithCustomJwt({ + return customJwt({ jwt: args.jwt, - encryptionKey: args.encryptionKey, + client: this.client, + ecosystem: this.ecosystem, }); case "passkey": { return this.passkeyAuth(args); } - case "auth_endpoint": { - return this.auth.authenticateWithCustomAuthEndpoint({ - payload: args.payload, - encryptionKey: args.encryptionKey, - }); - } case "iframe_email_verification": { return this.auth.authenticateWithIframe({ email: args.email, @@ -359,17 +366,10 @@ export class InAppWebConnector implements InAppConnector { ): Promise { const strategy = args.strategy; switch (strategy) { + case "auth_endpoint": case "jwt": { - return this.auth.loginWithCustomJwt({ - jwt: args.jwt, - encryptionKey: args.encryptionKey, - }); - } - case "auth_endpoint": { - return this.auth.loginWithCustomAuthEndpoint({ - payload: args.payload, - encryptionKey: args.encryptionKey, - }); + const authToken = await this.authenticate(args); + return await this.loginWithAuthToken(authToken, args.encryptionKey); } case "iframe_email_verification": { return this.auth.loginWithIframe({