@crossmint/client-sdk-auth 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CrossmintAuthClient.cjs +1 -12
- package/dist/CrossmintAuthClient.js +1 -12
- package/dist/chunk-22GIA4MK.js +1 -0
- package/dist/chunk-3K3UA645.js +1 -0
- package/dist/chunk-CK4JCQY6.cjs +1 -0
- package/dist/chunk-FTVKNCGF.cjs +1 -0
- package/dist/chunk-HU56N5SW.js +1 -0
- package/dist/chunk-NIH25R3L.js +1 -0
- package/dist/chunk-NYYORERK.cjs +1 -0
- package/dist/chunk-NZ2DAY24.cjs +1 -0
- package/dist/chunk-REIMEXVF.js +1 -0
- package/dist/chunk-U76ID4TS.js +0 -0
- package/dist/chunk-VDJHVTKI.cjs +1 -0
- package/dist/chunk-XHYLTO6W.cjs +1 -0
- package/dist/index.cjs +1 -29
- package/dist/index.js +1 -29
- package/dist/utils/constants.cjs +1 -8
- package/dist/utils/constants.js +1 -8
- package/dist/utils/cookies.cjs +1 -12
- package/dist/utils/cookies.js +1 -12
- package/dist/utils/index.cjs +1 -21
- package/dist/utils/index.js +1 -21
- package/dist/utils/jwt.cjs +1 -8
- package/dist/utils/jwt.js +1 -8
- package/package.json +4 -5
- package/dist/CrossmintAuthClient.cjs.map +0 -1
- package/dist/CrossmintAuthClient.js.map +0 -1
- package/dist/chunk-5JXPQKM4.js +0 -19
- package/dist/chunk-5JXPQKM4.js.map +0 -1
- package/dist/chunk-BGMXXFQ4.cjs +0 -19
- package/dist/chunk-BGMXXFQ4.cjs.map +0 -1
- package/dist/chunk-BMYZMMVR.js +0 -7
- package/dist/chunk-BMYZMMVR.js.map +0 -1
- package/dist/chunk-F45I5NLI.cjs +0 -46
- package/dist/chunk-F45I5NLI.cjs.map +0 -1
- package/dist/chunk-FEGDFSUW.cjs +0 -275
- package/dist/chunk-FEGDFSUW.cjs.map +0 -1
- package/dist/chunk-JPRRZPBL.js +0 -46
- package/dist/chunk-JPRRZPBL.js.map +0 -1
- package/dist/chunk-MLMLBCSI.js +0 -11
- package/dist/chunk-MLMLBCSI.js.map +0 -1
- package/dist/chunk-QY4RIGNM.cjs +0 -11
- package/dist/chunk-QY4RIGNM.cjs.map +0 -1
- package/dist/chunk-SGSYRRRS.js +0 -275
- package/dist/chunk-SGSYRRRS.js.map +0 -1
- package/dist/chunk-TIUX4OOQ.cjs +0 -7
- package/dist/chunk-TIUX4OOQ.cjs.map +0 -1
- package/dist/chunk-TOXKCKTY.js +0 -1
- package/dist/chunk-TOXKCKTY.js.map +0 -1
- package/dist/chunk-VQ3HTIQ3.cjs +0 -1
- package/dist/chunk-VQ3HTIQ3.cjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/utils/constants.cjs.map +0 -1
- package/dist/utils/constants.js.map +0 -1
- package/dist/utils/cookies.cjs.map +0 -1
- package/dist/utils/cookies.js.map +0 -1
- package/dist/utils/index.cjs.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/jwt.cjs.map +0 -1
- package/dist/utils/jwt.js.map +0 -1
- package/src/CrossmintAuthClient.test.ts +0 -416
- package/src/CrossmintAuthClient.ts +0 -294
- package/src/index.ts +0 -3
- package/src/utils/constants.ts +0 -1
- package/src/utils/cookies.test.ts +0 -44
- package/src/utils/cookies.ts +0 -13
- package/src/utils/index.ts +0 -3
- package/src/utils/jwt.ts +0 -6
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/CrossmintAuthClient.ts"],"sourcesContent":["import type { UseSignInData } from \"@farcaster/auth-kit\";\nimport {\n AUTH_SDK_ROOT_ENDPOINT,\n type AuthMaterialWithUser,\n CROSSMINT_API_VERSION,\n CrossmintAuth,\n CrossmintAuthenticationError,\n type CrossmintAuthOptions,\n type OAuthProvider,\n REFRESH_TOKEN_PREFIX,\n SESSION_PREFIX,\n} from \"@crossmint/common-sdk-auth\";\nimport type { Crossmint, CrossmintApiClient } from \"@crossmint/common-sdk-base\";\nimport { type CancellableTask, queueTask } from \"@crossmint/client-sdk-base\";\nimport { deleteCookie, getCookie, getJWTExpiration, setCookie, TIME_BEFORE_EXPIRING_JWT_IN_SECONDS } from \"./utils\";\n\ntype CrossmintAuthClientConfig = CrossmintAuthOptions & {\n callbacks?: CrossmintAuthClientCallbacks;\n logoutRoute?: string;\n};\n\nexport class CrossmintAuthClient extends CrossmintAuth {\n private callbacks: CrossmintAuthClientCallbacks;\n private refreshTask: CancellableTask | null = null;\n private refreshPromise: Promise<AuthMaterialWithUser> | null = null;\n private logoutRoute: string | null;\n\n private constructor(crossmint: Crossmint, apiClient: CrossmintApiClient, config: CrossmintAuthClientConfig = {}) {\n super(crossmint, apiClient, config);\n this.callbacks = config.callbacks ?? {};\n this.logoutRoute = config.logoutRoute ?? null;\n }\n\n public static from(crossmint: Crossmint, config: CrossmintAuthClientConfig = {}): CrossmintAuthClient {\n const authClient = new CrossmintAuthClient(crossmint, CrossmintAuth.defaultApiClient(crossmint), config);\n // In case an instance is created on the server, we can't refresh as this stores cookies\n if (typeof window !== \"undefined\") {\n authClient.handleRefreshAuthMaterial();\n }\n return authClient;\n }\n\n public async getUser() {\n try {\n const response = await this.apiClient.get(`api/${CROSSMINT_API_VERSION}/sdk/auth/user`, {\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n throw await response.text();\n }\n\n return await response.json();\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to fetch user: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public storeAuthMaterial(authMaterial: AuthMaterialWithUser) {\n setCookie(SESSION_PREFIX, authMaterial.jwt);\n setCookie(REFRESH_TOKEN_PREFIX, authMaterial.refreshToken.secret, authMaterial.refreshToken.expiresAt);\n }\n\n public async logout() {\n // Store the old refresh token to pass it to the logout route before deleting the cookies\n const oldRefreshToken = getCookie(REFRESH_TOKEN_PREFIX);\n\n // Even if there's a server error, we want to clear the cookies and we do it first to load faster\n deleteCookie(REFRESH_TOKEN_PREFIX);\n deleteCookie(SESSION_PREFIX);\n this.callbacks.onLogout?.();\n try {\n if (this.logoutRoute != null) {\n await this.logoutFromCustomRoute();\n } else if (oldRefreshToken != null) {\n await this.logoutFromDefaultRoute(oldRefreshToken);\n }\n } catch (error) {\n console.error(error);\n }\n }\n\n public async handleRefreshAuthMaterial(refreshTokenSecret?: string): Promise<void> {\n const refreshToken = refreshTokenSecret ?? getCookie(REFRESH_TOKEN_PREFIX);\n // If there is a custom refresh route, that endpoint will fetch the cookies itself\n if (refreshToken == null && this.refreshRoute == null) {\n return;\n }\n\n try {\n // Create new refresh promise if none exists\n if (this.refreshPromise == null) {\n this.refreshPromise = this.refreshAuthMaterial(refreshToken);\n }\n const authMaterial = await this.refreshPromise;\n\n // If a custom refresh route is set, storing in cookies is handled in the server\n if (this.refreshRoute == null) {\n this.storeAuthMaterial(authMaterial);\n }\n\n this.callbacks.onTokenRefresh?.(authMaterial);\n\n this.scheduleNextRefresh(authMaterial.jwt);\n } catch (error) {\n console.error(error);\n this.logout();\n } finally {\n this.refreshPromise = null;\n }\n }\n\n public async getOAuthUrl(provider: OAuthProvider) {\n try {\n const response = await this.apiClient.get(`${AUTH_SDK_ROOT_ENDPOINT}/social/${provider}/start`, {\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n throw await response.text();\n }\n\n const data = await response.json();\n return data.oauthUrl;\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to get OAuth URL for provider ${provider}: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public async sendEmailOtp(email: string) {\n try {\n const response = await this.apiClient.post(`${AUTH_SDK_ROOT_ENDPOINT}/otps/send`, {\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email }),\n });\n\n if (!response.ok) {\n throw await response.text();\n }\n\n return await response.json();\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to send email OTP: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public async confirmEmailOtp(email: string, emailId: string, token: string) {\n try {\n const queryParams = new URLSearchParams({\n email,\n signinAuthenticationMethod: \"email\",\n token,\n locale: \"en\",\n state: emailId,\n });\n\n const response = await this.apiClient.post(`${AUTH_SDK_ROOT_ENDPOINT}/authenticate?${queryParams}`, {\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n throw await response.text();\n }\n\n const resData = await response.json();\n return resData.oneTimeSecret;\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to confirm email OTP: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public async signInWithFarcaster(data: UseSignInData) {\n try {\n const queryParams = new URLSearchParams({\n signinAuthenticationMethod: \"farcaster\",\n callbackUrl: `${this.apiClient.baseUrl}/${AUTH_SDK_ROOT_ENDPOINT}/callback`,\n });\n\n const response = await this.apiClient.post(`${AUTH_SDK_ROOT_ENDPOINT}/authenticate?${queryParams}`, {\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n ...data,\n domain: data.signatureParams.domain,\n redirect: true,\n callbackUrl: `${this.apiClient.baseUrl}/${AUTH_SDK_ROOT_ENDPOINT}/callback`,\n }),\n });\n\n if (!response.ok) {\n throw await response.text();\n }\n\n const resData = await response.json();\n return resData.oneTimeSecret;\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to sign in with Farcaster: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public async signInWithSmartWallet(address: string) {\n try {\n const queryParams = new URLSearchParams({ signinAuthenticationMethod: \"evm\" });\n const response = await this.apiClient.post(\n `${AUTH_SDK_ROOT_ENDPOINT}/crypto_wallets/authenticate/start?${queryParams}`,\n {\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ walletAddress: address }),\n }\n );\n\n if (!response.ok) {\n throw await response.text();\n }\n\n return await response.json();\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to initiate smart wallet sign in: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n public async authenticateSmartWallet(address: string, signature: string) {\n try {\n const queryParams = new URLSearchParams({\n signinAuthenticationMethod: \"evm\",\n callbackUrl: `${this.apiClient.baseUrl}/${AUTH_SDK_ROOT_ENDPOINT}/callback`,\n });\n const response = await this.apiClient.post(\n `${AUTH_SDK_ROOT_ENDPOINT}/crypto_wallets/authenticate?${queryParams}`,\n {\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ walletAddress: address, signature }),\n }\n );\n\n if (!response.ok) {\n throw await response.text();\n }\n\n return await response.json();\n } catch (error) {\n throw new CrossmintAuthenticationError(\n `Failed to authenticate smart wallet: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n }\n }\n\n private async logoutFromCustomRoute(): Promise<Response> {\n if (!this.logoutRoute) {\n throw new Error(\"Custom logout route is not set\");\n }\n\n return await fetch(this.logoutRoute, { method: \"POST\" });\n }\n\n private scheduleNextRefresh(jwt: string): void {\n const jwtExpiration = getJWTExpiration(jwt);\n if (!jwtExpiration) {\n throw new Error(\"Invalid JWT\");\n }\n\n const currentTime = Date.now() / 1000;\n const timeToExpire = jwtExpiration - currentTime - TIME_BEFORE_EXPIRING_JWT_IN_SECONDS;\n\n if (timeToExpire > 0) {\n const endTime = Date.now() + timeToExpire * 1000;\n this.cancelScheduledRefresh();\n this.refreshTask = queueTask(() => this.handleRefreshAuthMaterial(), endTime);\n }\n }\n\n private cancelScheduledRefresh(): void {\n if (this.refreshTask) {\n this.refreshTask.cancel();\n this.refreshTask = null;\n }\n }\n}\n\ntype CrossmintAuthClientCallbacks = {\n onTokenRefresh?: (authMaterial: AuthMaterialWithUser) => void;\n onLogout?: () => void;\n};\n"],"mappings":"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","names":[]}
|
package/dist/chunk-TIUX4OOQ.cjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/utils/constants.ts
|
|
2
|
-
var TIME_BEFORE_EXPIRING_JWT_IN_SECONDS = 120;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.TIME_BEFORE_EXPIRING_JWT_IN_SECONDS = TIME_BEFORE_EXPIRING_JWT_IN_SECONDS;
|
|
7
|
-
//# sourceMappingURL=chunk-TIUX4OOQ.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/constants.ts"],"names":[],"mappings":";AAAO,IAAM,sCAAsC","sourcesContent":["export const TIME_BEFORE_EXPIRING_JWT_IN_SECONDS = 120;\n"]}
|
package/dist/chunk-TOXKCKTY.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=chunk-TOXKCKTY.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/chunk-VQ3HTIQ3.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";//# sourceMappingURL=chunk-VQ3HTIQ3.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,uBAAuB","sourcesContent":["export { createCrossmint } from \"@crossmint/common-sdk-base\";\nexport { CrossmintAuthClient as CrossmintAuth } from \"./CrossmintAuthClient\";\nexport * from \"./utils\";\n"]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { createCrossmint } from \"@crossmint/common-sdk-base\";\nexport { CrossmintAuthClient as CrossmintAuth } from \"./CrossmintAuthClient\";\nexport * from \"./utils\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,uBAAuB;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/utils/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/utils/jwt.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/utils/jwt.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import type { StatusAPIResponse } from "@farcaster/auth-kit";
|
|
3
|
-
import { type Crossmint, CrossmintApiClient } from "@crossmint/common-sdk-base";
|
|
4
|
-
import { AUTH_SDK_ROOT_ENDPOINT, type AuthMaterialWithUser } from "@crossmint/common-sdk-auth";
|
|
5
|
-
import { CrossmintAuthClient } from "./CrossmintAuthClient";
|
|
6
|
-
import * as cookiesUtils from "./utils/cookies";
|
|
7
|
-
import { getJWTExpiration } from "./utils";
|
|
8
|
-
import { queueTask } from "@crossmint/client-sdk-base";
|
|
9
|
-
|
|
10
|
-
vi.mock("@crossmint/common-sdk-base");
|
|
11
|
-
vi.mock("./utils/cookies");
|
|
12
|
-
vi.mock("./utils/jwt");
|
|
13
|
-
vi.mock("@crossmint/client-sdk-base");
|
|
14
|
-
|
|
15
|
-
describe("CrossmintAuthClient", () => {
|
|
16
|
-
let crossmintAuthClient: CrossmintAuthClient;
|
|
17
|
-
const mockCrossmint = { projectId: "test-project-id" };
|
|
18
|
-
const mockApiClient = {
|
|
19
|
-
baseUrl: "https://api.crossmint.com",
|
|
20
|
-
get: vi.fn(),
|
|
21
|
-
post: vi.fn(),
|
|
22
|
-
};
|
|
23
|
-
const mockCallbacks = {
|
|
24
|
-
onLogout: vi.fn(),
|
|
25
|
-
onTokenRefresh: vi.fn(),
|
|
26
|
-
};
|
|
27
|
-
const mockConfig = {
|
|
28
|
-
callbacks: mockCallbacks,
|
|
29
|
-
refreshRoute: "http://example.com/custom/refresh",
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
vi.resetAllMocks();
|
|
34
|
-
vi.mocked(CrossmintApiClient).mockReturnValue(mockApiClient as unknown as CrossmintApiClient);
|
|
35
|
-
crossmintAuthClient = CrossmintAuthClient.from(mockCrossmint as unknown as Crossmint, mockConfig);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
afterEach(() => {
|
|
39
|
-
vi.restoreAllMocks();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("from", () => {
|
|
43
|
-
it("should create a new CrossmintAuthClient instance with config", () => {
|
|
44
|
-
expect(crossmintAuthClient).toBeInstanceOf(CrossmintAuthClient);
|
|
45
|
-
expect(CrossmintApiClient).toHaveBeenCalledWith(mockCrossmint, expect.any(Object));
|
|
46
|
-
expect((crossmintAuthClient as any).callbacks).toEqual(mockConfig.callbacks);
|
|
47
|
-
expect((crossmintAuthClient as any).refreshRoute).toBe(mockConfig.refreshRoute);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe("getUser", () => {
|
|
52
|
-
it("should fetch user data", async () => {
|
|
53
|
-
const mockUserData = { id: "user123", email: "user@example.com" };
|
|
54
|
-
mockApiClient.get.mockResolvedValue({
|
|
55
|
-
json: () => Promise.resolve(mockUserData),
|
|
56
|
-
ok: true,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const result = await crossmintAuthClient.getUser();
|
|
60
|
-
|
|
61
|
-
expect(result).toEqual(mockUserData);
|
|
62
|
-
expect(mockApiClient.get).toHaveBeenCalledWith("api/2024-09-26/sdk/auth/user", expect.any(Object));
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
describe("storeAuthMaterial", () => {
|
|
67
|
-
it("should store auth material in cookies", () => {
|
|
68
|
-
const mockAuthMaterial: AuthMaterialWithUser = {
|
|
69
|
-
jwt: "mock.jwt.token",
|
|
70
|
-
refreshToken: { secret: "refresh-token", expiresAt: "2023-12-31T23:59:59Z" },
|
|
71
|
-
user: { id: "user123" },
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
crossmintAuthClient.storeAuthMaterial(mockAuthMaterial);
|
|
75
|
-
|
|
76
|
-
expect(cookiesUtils.setCookie).toHaveBeenCalledWith("crossmint-jwt", mockAuthMaterial.jwt);
|
|
77
|
-
expect(cookiesUtils.setCookie).toHaveBeenCalledWith(
|
|
78
|
-
"crossmint-refresh-token",
|
|
79
|
-
mockAuthMaterial.refreshToken.secret,
|
|
80
|
-
mockAuthMaterial.refreshToken.expiresAt
|
|
81
|
-
);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe("logout", () => {
|
|
86
|
-
beforeEach(() => {
|
|
87
|
-
mockApiClient.post.mockReset();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("should call logout endpoint, clear auth cookies and call onLogout callback", async () => {
|
|
91
|
-
const mockCallbacks = { onLogout: vi.fn() };
|
|
92
|
-
const mockRefreshToken = "mock-refresh-token";
|
|
93
|
-
vi.mocked(cookiesUtils.getCookie).mockReturnValue(mockRefreshToken);
|
|
94
|
-
crossmintAuthClient = CrossmintAuthClient.from(mockCrossmint as unknown as Crossmint, {
|
|
95
|
-
callbacks: mockCallbacks,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
await crossmintAuthClient.logout();
|
|
99
|
-
|
|
100
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
101
|
-
"api/2024-09-26/session/sdk/auth/logout",
|
|
102
|
-
expect.objectContaining({
|
|
103
|
-
headers: {
|
|
104
|
-
"Content-Type": "application/json",
|
|
105
|
-
},
|
|
106
|
-
body: JSON.stringify({
|
|
107
|
-
refresh: mockRefreshToken,
|
|
108
|
-
}),
|
|
109
|
-
})
|
|
110
|
-
);
|
|
111
|
-
expect(cookiesUtils.deleteCookie).toHaveBeenCalledWith("crossmint-refresh-token");
|
|
112
|
-
expect(cookiesUtils.deleteCookie).toHaveBeenCalledWith("crossmint-jwt");
|
|
113
|
-
expect(mockCallbacks.onLogout).toHaveBeenCalled();
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it("should call custom logout route when configured", async () => {
|
|
117
|
-
const mockCallbacks = { onLogout: vi.fn() };
|
|
118
|
-
const customLogoutRoute = "/custom/logout";
|
|
119
|
-
const fetchSpy = vi.spyOn(global, "fetch").mockResolvedValue(new Response());
|
|
120
|
-
|
|
121
|
-
crossmintAuthClient = CrossmintAuthClient.from(mockCrossmint as unknown as Crossmint, {
|
|
122
|
-
callbacks: mockCallbacks,
|
|
123
|
-
logoutRoute: customLogoutRoute,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
await crossmintAuthClient.logout();
|
|
127
|
-
|
|
128
|
-
expect(fetchSpy).toHaveBeenCalledWith(customLogoutRoute, { method: "POST" });
|
|
129
|
-
expect(mockApiClient.post).not.toHaveBeenCalled();
|
|
130
|
-
expect(cookiesUtils.deleteCookie).toHaveBeenCalledWith("crossmint-refresh-token");
|
|
131
|
-
expect(cookiesUtils.deleteCookie).toHaveBeenCalledWith("crossmint-jwt");
|
|
132
|
-
expect(mockCallbacks.onLogout).toHaveBeenCalled();
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
describe("handleRefreshAuthMaterial", () => {
|
|
137
|
-
const mockRefreshToken = "mock-refresh-token";
|
|
138
|
-
const mockAuthMaterial = {
|
|
139
|
-
jwt: "new.jwt.token",
|
|
140
|
-
refreshToken: { secret: "new-refresh-token", expiresAt: "2023-12-31T23:59:59Z" },
|
|
141
|
-
user: { id: "user123" },
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
beforeEach(() => {
|
|
145
|
-
vi.spyOn(crossmintAuthClient as any, "refreshAuthMaterial").mockResolvedValue(mockAuthMaterial);
|
|
146
|
-
vi.spyOn(crossmintAuthClient as any, "storeAuthMaterial").mockImplementation(() => {});
|
|
147
|
-
vi.mocked(getJWTExpiration).mockReturnValue(Date.now() / 1000 + 3600); // 1 hour from now
|
|
148
|
-
vi.mocked(queueTask).mockReturnValue({ cancel: vi.fn() } as any);
|
|
149
|
-
(crossmintAuthClient as any).refreshPromise = null;
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should refresh auth material and schedule next refresh", async () => {
|
|
153
|
-
crossmintAuthClient = CrossmintAuthClient.from(mockCrossmint as unknown as Crossmint, {
|
|
154
|
-
callbacks: mockCallbacks,
|
|
155
|
-
});
|
|
156
|
-
vi.spyOn(crossmintAuthClient as any, "refreshAuthMaterial").mockResolvedValue(mockAuthMaterial);
|
|
157
|
-
vi.spyOn(crossmintAuthClient as any, "storeAuthMaterial").mockImplementation(() => {});
|
|
158
|
-
|
|
159
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
160
|
-
|
|
161
|
-
expect(crossmintAuthClient["refreshAuthMaterial"]).toHaveBeenCalledWith(mockRefreshToken);
|
|
162
|
-
expect(crossmintAuthClient["storeAuthMaterial"]).toHaveBeenCalledWith(mockAuthMaterial);
|
|
163
|
-
expect(queueTask).toHaveBeenCalledWith(expect.any(Function), expect.any(Number));
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it("should not refresh when called twice in a row", async () => {
|
|
167
|
-
const promise1 = crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
168
|
-
const promise2 = crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
169
|
-
|
|
170
|
-
await Promise.all([promise1, promise2]);
|
|
171
|
-
|
|
172
|
-
expect(crossmintAuthClient["refreshAuthMaterial"]).toHaveBeenCalledTimes(1);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("should call onTokenRefresh callback if provided", async () => {
|
|
176
|
-
const mockCallback = vi.fn();
|
|
177
|
-
(crossmintAuthClient as any).callbacks.onTokenRefresh = mockCallback;
|
|
178
|
-
|
|
179
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
180
|
-
|
|
181
|
-
expect(mockCallback).toHaveBeenCalledWith(mockAuthMaterial);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it("should handle errors and call logout", async () => {
|
|
185
|
-
const mockError = new Error("Refresh failed");
|
|
186
|
-
vi.spyOn(crossmintAuthClient as any, "refreshAuthMaterial").mockRejectedValue(mockError);
|
|
187
|
-
vi.spyOn(crossmintAuthClient, "logout").mockImplementation(() => Promise.resolve());
|
|
188
|
-
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
189
|
-
|
|
190
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
191
|
-
|
|
192
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(mockError);
|
|
193
|
-
expect(crossmintAuthClient.logout).toHaveBeenCalled();
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it("should use cookie if no refresh token is provided", async () => {
|
|
197
|
-
vi.mocked(cookiesUtils.getCookie).mockReturnValue(mockRefreshToken);
|
|
198
|
-
|
|
199
|
-
await crossmintAuthClient.handleRefreshAuthMaterial();
|
|
200
|
-
|
|
201
|
-
expect(crossmintAuthClient["refreshAuthMaterial"]).toHaveBeenCalledWith(mockRefreshToken);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("should not refresh if no refresh token is available and no custom refresh route is set", async () => {
|
|
205
|
-
crossmintAuthClient = CrossmintAuthClient.from(mockCrossmint as unknown as Crossmint, {});
|
|
206
|
-
vi.spyOn(crossmintAuthClient as any, "refreshAuthMaterial").mockResolvedValue(mockAuthMaterial);
|
|
207
|
-
vi.mocked(cookiesUtils.getCookie).mockReturnValue(null as any);
|
|
208
|
-
|
|
209
|
-
await crossmintAuthClient.handleRefreshAuthMaterial();
|
|
210
|
-
|
|
211
|
-
expect(crossmintAuthClient["refreshAuthMaterial"]).not.toHaveBeenCalled();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it("should cancel previous refresh task before scheduling a new one", async () => {
|
|
215
|
-
const mockCancelTask = vi.fn();
|
|
216
|
-
(crossmintAuthClient as any).refreshTask = { cancel: mockCancelTask };
|
|
217
|
-
|
|
218
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
219
|
-
|
|
220
|
-
expect(mockCancelTask).toHaveBeenCalled();
|
|
221
|
-
expect(queueTask).toHaveBeenCalled();
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it("should not schedule refresh if JWT is invalid", async () => {
|
|
225
|
-
vi.mocked(getJWTExpiration).mockReturnValue(null as any);
|
|
226
|
-
|
|
227
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
228
|
-
|
|
229
|
-
expect(queueTask).not.toHaveBeenCalled();
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("should not schedule refresh if time to expire is negative", async () => {
|
|
233
|
-
vi.mocked(getJWTExpiration).mockReturnValue(Date.now() / 1000 - 3600); // 1 hour ago
|
|
234
|
-
|
|
235
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
236
|
-
|
|
237
|
-
expect(queueTask).not.toHaveBeenCalled();
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it("should not store auth material if custom refresh route is set", async () => {
|
|
241
|
-
const spyStoreAuthMaterial = vi.spyOn(crossmintAuthClient, "storeAuthMaterial");
|
|
242
|
-
|
|
243
|
-
await crossmintAuthClient.handleRefreshAuthMaterial(mockRefreshToken);
|
|
244
|
-
|
|
245
|
-
expect(crossmintAuthClient["refreshAuthMaterial"]).toHaveBeenCalledWith(mockRefreshToken);
|
|
246
|
-
expect(spyStoreAuthMaterial).not.toHaveBeenCalled();
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
describe("getOAuthUrl", () => {
|
|
251
|
-
it("should fetch OAuth URL for a given provider", async () => {
|
|
252
|
-
const mockProvider = "google";
|
|
253
|
-
const mockOAuthUrl = "https://oauth.example.com/auth";
|
|
254
|
-
mockApiClient.get.mockResolvedValue({
|
|
255
|
-
json: () => Promise.resolve({ oauthUrl: mockOAuthUrl }),
|
|
256
|
-
ok: true,
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
const result = await crossmintAuthClient.getOAuthUrl(mockProvider);
|
|
260
|
-
|
|
261
|
-
expect(result).toBe(mockOAuthUrl);
|
|
262
|
-
expect(mockApiClient.get).toHaveBeenCalledWith(
|
|
263
|
-
"api/2024-09-26/session/sdk/auth/social/google/start",
|
|
264
|
-
expect.any(Object)
|
|
265
|
-
);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
describe("sendEmailOtp", () => {
|
|
270
|
-
it("should send email OTP", async () => {
|
|
271
|
-
const mockEmail = "user@example.com";
|
|
272
|
-
const mockResponse = { success: true };
|
|
273
|
-
mockApiClient.post.mockResolvedValue({
|
|
274
|
-
json: () => Promise.resolve(mockResponse),
|
|
275
|
-
ok: true,
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
const result = await crossmintAuthClient.sendEmailOtp(mockEmail);
|
|
279
|
-
|
|
280
|
-
expect(result).toEqual(mockResponse);
|
|
281
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
282
|
-
"api/2024-09-26/session/sdk/auth/otps/send",
|
|
283
|
-
expect.objectContaining({
|
|
284
|
-
body: JSON.stringify({ email: mockEmail }),
|
|
285
|
-
})
|
|
286
|
-
);
|
|
287
|
-
});
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
describe("confirmEmailOtp", () => {
|
|
291
|
-
it("should confirm email OTP and return oneTimeSecret", async () => {
|
|
292
|
-
const mockEmail = "user@example.com";
|
|
293
|
-
const mockEmailId = "email-id-123";
|
|
294
|
-
const mockToken = "otp-token-456";
|
|
295
|
-
const mockOneTimeSecret = "one-time-secret-789";
|
|
296
|
-
mockApiClient.post.mockResolvedValue({
|
|
297
|
-
json: () => Promise.resolve({ oneTimeSecret: mockOneTimeSecret }),
|
|
298
|
-
ok: true,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
const result = await crossmintAuthClient.confirmEmailOtp(mockEmail, mockEmailId, mockToken);
|
|
302
|
-
|
|
303
|
-
expect(result).toBe(mockOneTimeSecret);
|
|
304
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
305
|
-
expect.stringContaining("api/2024-09-26/session/sdk/auth/authenticate"),
|
|
306
|
-
expect.any(Object)
|
|
307
|
-
);
|
|
308
|
-
});
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
describe("signInWithFarcaster", () => {
|
|
312
|
-
it("should sign in with Farcaster and return oneTimeSecret", async () => {
|
|
313
|
-
const mockFarcasterData = {
|
|
314
|
-
message: "mock-message",
|
|
315
|
-
signature: "mock-signature",
|
|
316
|
-
signatureParams: { domain: "example.com" },
|
|
317
|
-
};
|
|
318
|
-
const mockOneTimeSecret = "farcaster-one-time-secret-123";
|
|
319
|
-
mockApiClient.post.mockResolvedValue({
|
|
320
|
-
json: () => Promise.resolve({ oneTimeSecret: mockOneTimeSecret }),
|
|
321
|
-
ok: true,
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
const result = await crossmintAuthClient.signInWithFarcaster(mockFarcasterData as StatusAPIResponse);
|
|
325
|
-
|
|
326
|
-
expect(result).toBe(mockOneTimeSecret);
|
|
327
|
-
const expectedCallbackUrl = `https://api.crossmint.com/api/2024-09-26/session/sdk/auth/callback`;
|
|
328
|
-
const queryParams = new URLSearchParams({
|
|
329
|
-
signinAuthenticationMethod: "farcaster",
|
|
330
|
-
callbackUrl: expectedCallbackUrl,
|
|
331
|
-
});
|
|
332
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
333
|
-
expect.stringContaining(`api/2024-09-26/session/sdk/auth/authenticate?${queryParams}`),
|
|
334
|
-
expect.objectContaining({
|
|
335
|
-
body: JSON.stringify({
|
|
336
|
-
...mockFarcasterData,
|
|
337
|
-
domain: "example.com",
|
|
338
|
-
redirect: true,
|
|
339
|
-
callbackUrl: expectedCallbackUrl,
|
|
340
|
-
}),
|
|
341
|
-
headers: {
|
|
342
|
-
"Content-Type": "application/json",
|
|
343
|
-
},
|
|
344
|
-
})
|
|
345
|
-
);
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
describe("signInWithSmartWallet", () => {
|
|
350
|
-
it("should initiate smart wallet sign in", async () => {
|
|
351
|
-
const mockAddress = "0x1234567890abcdef";
|
|
352
|
-
const mockResponse = {
|
|
353
|
-
message: "Please sign this message",
|
|
354
|
-
nonce: "123456",
|
|
355
|
-
};
|
|
356
|
-
mockApiClient.post.mockResolvedValue({
|
|
357
|
-
json: () => Promise.resolve(mockResponse),
|
|
358
|
-
ok: true,
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
const result = await crossmintAuthClient.signInWithSmartWallet(mockAddress);
|
|
362
|
-
|
|
363
|
-
expect(result).toEqual(mockResponse);
|
|
364
|
-
const queryParams = new URLSearchParams({
|
|
365
|
-
signinAuthenticationMethod: "evm",
|
|
366
|
-
});
|
|
367
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
368
|
-
`api/2024-09-26/session/sdk/auth/crypto_wallets/authenticate/start?${queryParams}`,
|
|
369
|
-
expect.objectContaining({
|
|
370
|
-
body: JSON.stringify({ walletAddress: mockAddress }),
|
|
371
|
-
headers: {
|
|
372
|
-
"Content-Type": "application/json",
|
|
373
|
-
},
|
|
374
|
-
})
|
|
375
|
-
);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
describe("authenticateSmartWallet", () => {
|
|
380
|
-
it("should complete smart wallet authentication", async () => {
|
|
381
|
-
const mockAddress = "0x1234567890abcdef";
|
|
382
|
-
const mockSignature = "0xsignature123";
|
|
383
|
-
const mockResponse = {
|
|
384
|
-
success: true,
|
|
385
|
-
authMaterial: {
|
|
386
|
-
jwt: "mock.jwt.token",
|
|
387
|
-
refreshToken: { secret: "refresh-token" },
|
|
388
|
-
},
|
|
389
|
-
};
|
|
390
|
-
mockApiClient.post.mockResolvedValue({
|
|
391
|
-
json: () => Promise.resolve(mockResponse),
|
|
392
|
-
ok: true,
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
const result = await crossmintAuthClient.authenticateSmartWallet(mockAddress, mockSignature);
|
|
396
|
-
|
|
397
|
-
expect(result).toEqual(mockResponse);
|
|
398
|
-
const queryParams = new URLSearchParams({
|
|
399
|
-
signinAuthenticationMethod: "evm",
|
|
400
|
-
callbackUrl: `${mockApiClient.baseUrl}/${AUTH_SDK_ROOT_ENDPOINT}/callback`,
|
|
401
|
-
});
|
|
402
|
-
expect(mockApiClient.post).toHaveBeenCalledWith(
|
|
403
|
-
`api/2024-09-26/session/sdk/auth/crypto_wallets/authenticate?${queryParams}`,
|
|
404
|
-
expect.objectContaining({
|
|
405
|
-
body: JSON.stringify({
|
|
406
|
-
walletAddress: mockAddress,
|
|
407
|
-
signature: mockSignature,
|
|
408
|
-
}),
|
|
409
|
-
headers: {
|
|
410
|
-
"Content-Type": "application/json",
|
|
411
|
-
},
|
|
412
|
-
})
|
|
413
|
-
);
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
});
|