@puzzle-ui/fullstack 0.0.0-stage → 0.5.0
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/README.md +558 -2
- package/dist/LICENSE +21 -0
- package/dist/auth/client/auth.css +206 -0
- package/dist/auth/client/experience.cjs +340 -0
- package/dist/auth/client/experience.cjs.map +1 -0
- package/dist/auth/client/experience.d.cts +67 -0
- package/dist/auth/client/experience.d.ts +67 -0
- package/dist/auth/client/experience.js +340 -0
- package/dist/auth/client/experience.js.map +1 -0
- package/dist/auth/client/index.cjs +234 -0
- package/dist/auth/client/index.cjs.map +1 -0
- package/dist/auth/client/index.d.cts +48 -0
- package/dist/auth/client/index.d.ts +48 -0
- package/dist/auth/client/index.js +216 -0
- package/dist/auth/client/index.js.map +1 -0
- package/dist/auth/client/messages.cjs +80 -0
- package/dist/auth/client/messages.cjs.map +1 -0
- package/dist/auth/client/messages.d.cts +92 -0
- package/dist/auth/client/messages.d.ts +92 -0
- package/dist/auth/client/messages.js +79 -0
- package/dist/auth/client/messages.js.map +1 -0
- package/dist/auth/client/passkeys.cjs +43 -0
- package/dist/auth/client/passkeys.cjs.map +1 -0
- package/dist/auth/client/passkeys.d.cts +23 -0
- package/dist/auth/client/passkeys.d.ts +23 -0
- package/dist/auth/client/passkeys.js +40 -0
- package/dist/auth/client/passkeys.js.map +1 -0
- package/dist/auth/client/react.cjs +859 -0
- package/dist/auth/client/react.cjs.map +1 -0
- package/dist/auth/client/react.d.cts +72 -0
- package/dist/auth/client/react.d.ts +72 -0
- package/dist/auth/client/react.js +850 -0
- package/dist/auth/client/react.js.map +1 -0
- package/dist/auth/next/index.cjs +40 -0
- package/dist/auth/next/index.cjs.map +1 -0
- package/dist/auth/next/index.d.cts +12 -0
- package/dist/auth/next/index.d.ts +12 -0
- package/dist/auth/next/index.js +38 -0
- package/dist/auth/next/index.js.map +1 -0
- package/dist/auth/server/health.cjs +51 -0
- package/dist/auth/server/health.cjs.map +1 -0
- package/dist/auth/server/health.d.cts +15 -0
- package/dist/auth/server/health.d.ts +15 -0
- package/dist/auth/server/health.js +51 -0
- package/dist/auth/server/health.js.map +1 -0
- package/dist/auth/server/index.cjs +108 -0
- package/dist/auth/server/index.cjs.map +1 -0
- package/dist/auth/server/index.d.cts +22 -0
- package/dist/auth/server/index.d.ts +22 -0
- package/dist/auth/server/index.js +88 -0
- package/dist/auth/server/index.js.map +1 -0
- package/dist/auth/server/lifecycle.cjs +126 -0
- package/dist/auth/server/lifecycle.cjs.map +1 -0
- package/dist/auth/server/lifecycle.d.cts +20 -0
- package/dist/auth/server/lifecycle.d.ts +20 -0
- package/dist/auth/server/lifecycle.js +126 -0
- package/dist/auth/server/lifecycle.js.map +1 -0
- package/dist/auth/server/mfa.cjs +682 -0
- package/dist/auth/server/mfa.cjs.map +1 -0
- package/dist/auth/server/mfa.d.cts +90 -0
- package/dist/auth/server/mfa.d.ts +90 -0
- package/dist/auth/server/mfa.js +673 -0
- package/dist/auth/server/mfa.js.map +1 -0
- package/dist/auth/server/session.cjs +58 -0
- package/dist/auth/server/session.cjs.map +1 -0
- package/dist/auth/server/session.d.cts +14 -0
- package/dist/auth/server/session.d.ts +14 -0
- package/dist/auth/server/session.js +53 -0
- package/dist/auth/server/session.js.map +1 -0
- package/dist/auth/shared/index.cjs +0 -0
- package/dist/auth/shared/index.d.cts +64 -0
- package/dist/auth/shared/index.d.ts +64 -0
- package/dist/auth/shared/index.js +1 -0
- package/dist/auth/tanstack/index.cjs +34 -0
- package/dist/auth/tanstack/index.cjs.map +1 -0
- package/dist/auth/tanstack/index.d.cts +7 -0
- package/dist/auth/tanstack/index.d.ts +7 -0
- package/dist/auth/tanstack/index.js +32 -0
- package/dist/auth/tanstack/index.js.map +1 -0
- package/package.json +108 -4
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const require_passkeys = require("./passkeys.cjs");
|
|
4
|
+
const require_react = require("./react.cjs");
|
|
5
|
+
const require_experience = require("./experience.cjs");
|
|
6
|
+
const require_messages = require("./messages.cjs");
|
|
7
|
+
// src/auth/client/index.ts
|
|
8
|
+
var AuthClientError = class extends Error {
|
|
9
|
+
status;
|
|
10
|
+
code;
|
|
11
|
+
constructor(input) {
|
|
12
|
+
super(input.message);
|
|
13
|
+
this.name = "AuthClientError";
|
|
14
|
+
this.status = input.status;
|
|
15
|
+
this.code = input.code;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
19
|
+
const normalizeBasePath = (value) => {
|
|
20
|
+
const basePath = value ?? "/api/auth";
|
|
21
|
+
if (!basePath.startsWith("/") || basePath.startsWith("//") || basePath.includes("?") || basePath.includes("#")) throw new TypeError("AuthClient basePath must be an absolute path.");
|
|
22
|
+
return basePath.replace(/\/+$/, "");
|
|
23
|
+
};
|
|
24
|
+
const getError = (response, payload) => {
|
|
25
|
+
const value = isRecord(payload) ? payload.error : void 0;
|
|
26
|
+
return new AuthClientError({
|
|
27
|
+
status: response.status,
|
|
28
|
+
code: value?.code ?? "AUTH_REQUEST_FAILED",
|
|
29
|
+
message: value?.message ?? "The authentication request failed."
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
const parseJson = async (response) => {
|
|
33
|
+
try {
|
|
34
|
+
return await response.json();
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const createAuthClient = (options = {}) => {
|
|
40
|
+
const basePath = normalizeBasePath(options.basePath);
|
|
41
|
+
const fetcher = options.fetcher ?? fetch;
|
|
42
|
+
const credentials = options.credentials ?? "same-origin";
|
|
43
|
+
const passkeys = options.passkeys ?? require_passkeys.createPasskeyBrowserHelpers();
|
|
44
|
+
let snapshot = {
|
|
45
|
+
status: "loading",
|
|
46
|
+
user: null
|
|
47
|
+
};
|
|
48
|
+
const request = async (path, input) => {
|
|
49
|
+
const method = input?.method ?? "POST";
|
|
50
|
+
const headers = new Headers();
|
|
51
|
+
if (input?.body !== void 0) headers.set("Content-Type", "application/json");
|
|
52
|
+
const response = await fetcher(`${basePath}${path}`, {
|
|
53
|
+
method,
|
|
54
|
+
credentials,
|
|
55
|
+
headers,
|
|
56
|
+
...input?.body === void 0 ? {} : { body: JSON.stringify(input.body) }
|
|
57
|
+
});
|
|
58
|
+
const payload = await parseJson(response);
|
|
59
|
+
if (!response.ok) throw getError(response, payload);
|
|
60
|
+
return payload;
|
|
61
|
+
};
|
|
62
|
+
const post = (path, body) => request(path, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body
|
|
65
|
+
});
|
|
66
|
+
const get = (path) => request(path, { method: "GET" });
|
|
67
|
+
const getSnapshot = async () => {
|
|
68
|
+
const result = await get("/state");
|
|
69
|
+
snapshot = {
|
|
70
|
+
status: result.status,
|
|
71
|
+
user: result.user ?? null,
|
|
72
|
+
...result.mfa ? { mfa: result.mfa } : {}
|
|
73
|
+
};
|
|
74
|
+
return snapshot;
|
|
75
|
+
};
|
|
76
|
+
const refreshSnapshot = async () => getSnapshot();
|
|
77
|
+
const signIn = async (input) => {
|
|
78
|
+
await post("/sign-in", input);
|
|
79
|
+
return refreshSnapshot();
|
|
80
|
+
};
|
|
81
|
+
const register = async (input) => {
|
|
82
|
+
await post("/register", input);
|
|
83
|
+
return refreshSnapshot();
|
|
84
|
+
};
|
|
85
|
+
const signOut = async () => {
|
|
86
|
+
await post("/sign-out");
|
|
87
|
+
snapshot = {
|
|
88
|
+
status: "unauthenticated",
|
|
89
|
+
user: null
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
const verifyMfaTotp = async (code) => {
|
|
93
|
+
await post("/mfa/sign-in/totp", { code });
|
|
94
|
+
return refreshSnapshot();
|
|
95
|
+
};
|
|
96
|
+
const verifyMfaRecoveryCode = async (code) => {
|
|
97
|
+
await post("/mfa/sign-in/recovery-code", { code });
|
|
98
|
+
return refreshSnapshot();
|
|
99
|
+
};
|
|
100
|
+
const signInWithPasskey = async () => {
|
|
101
|
+
const started = await post("/mfa/passkey/sign-in/start");
|
|
102
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
103
|
+
await post("/mfa/passkey/sign-in/finish", { response });
|
|
104
|
+
return refreshSnapshot();
|
|
105
|
+
};
|
|
106
|
+
const verifyMfaWithPasskey = async () => {
|
|
107
|
+
const started = await post("/mfa/passkey/challenge/start");
|
|
108
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
109
|
+
await post("/mfa/passkey/challenge/finish", { response });
|
|
110
|
+
return refreshSnapshot();
|
|
111
|
+
};
|
|
112
|
+
const beginTotpEnrollment = async (currentPassword, label) => post("/mfa/totp/enrollment/start", {
|
|
113
|
+
currentPassword,
|
|
114
|
+
...label === void 0 ? {} : { label }
|
|
115
|
+
});
|
|
116
|
+
const verifyTotpEnrollment = async (factorId, code) => post("/mfa/totp/enrollment/finish", {
|
|
117
|
+
factorId,
|
|
118
|
+
code
|
|
119
|
+
});
|
|
120
|
+
const registerPasskey = async (currentPassword, label) => {
|
|
121
|
+
const started = await post("/mfa/passkey/enrollment/start", {
|
|
122
|
+
currentPassword,
|
|
123
|
+
...label === void 0 ? {} : { label }
|
|
124
|
+
});
|
|
125
|
+
const response = await passkeys.startRegistration(started.options);
|
|
126
|
+
return post("/mfa/passkey/enrollment/finish", { response });
|
|
127
|
+
};
|
|
128
|
+
const beginRequiredTotpEnrollment = async (label) => post("/mfa/enrollment/required/totp/start", { ...label === void 0 ? {} : { label } });
|
|
129
|
+
const verifyRequiredTotpEnrollment = async (factorId, code) => {
|
|
130
|
+
const result = await post("/mfa/enrollment/required/totp/finish", {
|
|
131
|
+
factorId,
|
|
132
|
+
code
|
|
133
|
+
});
|
|
134
|
+
await refreshSnapshot();
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
const registerRequiredPasskey = async (label) => {
|
|
138
|
+
const started = await post("/mfa/enrollment/required/passkey/start", { ...label === void 0 ? {} : { label } });
|
|
139
|
+
const response = await passkeys.startRegistration(started.options);
|
|
140
|
+
const completed = await post("/mfa/enrollment/required/passkey/finish", { response });
|
|
141
|
+
await refreshSnapshot();
|
|
142
|
+
return completed;
|
|
143
|
+
};
|
|
144
|
+
const listMfaFactors = () => get("/mfa/factors");
|
|
145
|
+
const removeMfaFactor = async (factorId, currentPassword) => {
|
|
146
|
+
await post("/mfa/factors/remove", {
|
|
147
|
+
factorId,
|
|
148
|
+
currentPassword
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const regenerateRecoveryCodes = (currentPassword) => post("/mfa/recovery-codes/regenerate", { currentPassword });
|
|
152
|
+
const beginStepUp = async () => {
|
|
153
|
+
await post("/mfa/step-up/start");
|
|
154
|
+
return refreshSnapshot();
|
|
155
|
+
};
|
|
156
|
+
const verifyStepUpTotp = async (code) => {
|
|
157
|
+
await post("/mfa/step-up/totp", { code });
|
|
158
|
+
return refreshSnapshot();
|
|
159
|
+
};
|
|
160
|
+
const verifyStepUpRecoveryCode = async (code) => {
|
|
161
|
+
await post("/mfa/step-up/recovery-code", { code });
|
|
162
|
+
return refreshSnapshot();
|
|
163
|
+
};
|
|
164
|
+
const verifyStepUpWithPasskey = async () => {
|
|
165
|
+
const started = await post("/mfa/step-up/passkey/start");
|
|
166
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
167
|
+
await post("/mfa/step-up/passkey/finish", { response });
|
|
168
|
+
return refreshSnapshot();
|
|
169
|
+
};
|
|
170
|
+
const requestEmailVerification = () => post("/email/verification/request");
|
|
171
|
+
const verifyEmail = (token) => post("/email/verification/verify", { token });
|
|
172
|
+
const requestPasswordReset = (email) => post("/password/reset/request", { email });
|
|
173
|
+
const resetPassword = (token, newPassword) => post("/password/reset/finish", {
|
|
174
|
+
token,
|
|
175
|
+
newPassword
|
|
176
|
+
});
|
|
177
|
+
const changePassword = async (currentPassword, newPassword) => {
|
|
178
|
+
const result = await post("/password/change", {
|
|
179
|
+
currentPassword,
|
|
180
|
+
newPassword
|
|
181
|
+
});
|
|
182
|
+
await refreshSnapshot();
|
|
183
|
+
return result;
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
register,
|
|
187
|
+
getSnapshot,
|
|
188
|
+
signIn,
|
|
189
|
+
signOut,
|
|
190
|
+
verifyMfaTotp,
|
|
191
|
+
verifyMfaRecoveryCode,
|
|
192
|
+
signInWithPasskey,
|
|
193
|
+
verifyMfaWithPasskey,
|
|
194
|
+
beginTotpEnrollment,
|
|
195
|
+
verifyTotpEnrollment,
|
|
196
|
+
beginRequiredTotpEnrollment,
|
|
197
|
+
verifyRequiredTotpEnrollment,
|
|
198
|
+
registerPasskey,
|
|
199
|
+
registerRequiredPasskey,
|
|
200
|
+
listMfaFactors,
|
|
201
|
+
removeMfaFactor,
|
|
202
|
+
regenerateRecoveryCodes,
|
|
203
|
+
beginStepUp,
|
|
204
|
+
verifyStepUpTotp,
|
|
205
|
+
verifyStepUpRecoveryCode,
|
|
206
|
+
verifyStepUpWithPasskey,
|
|
207
|
+
isPasskeySupported: passkeys.isSupported,
|
|
208
|
+
requestEmailVerification,
|
|
209
|
+
verifyEmail,
|
|
210
|
+
requestPasswordReset,
|
|
211
|
+
resetPassword,
|
|
212
|
+
changePassword
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
exports.AuthClientError = AuthClientError;
|
|
216
|
+
exports.AuthExperience = require_experience.AuthExperience;
|
|
217
|
+
exports.AuthProvider = require_react.AuthProvider;
|
|
218
|
+
exports.AuthScreen = require_react.AuthScreen;
|
|
219
|
+
exports.MfaChallengeForm = require_react.MfaChallengeForm;
|
|
220
|
+
exports.MfaSettings = require_react.MfaSettings;
|
|
221
|
+
exports.SignInForm = require_react.SignInForm;
|
|
222
|
+
exports.SignUpForm = require_react.SignUpForm;
|
|
223
|
+
exports.createAuthClient = createAuthClient;
|
|
224
|
+
exports.createPasskeyBrowserHelpers = require_passkeys.createPasskeyBrowserHelpers;
|
|
225
|
+
exports.getAuthLocale = require_messages.getAuthLocale;
|
|
226
|
+
exports.isPasskeySupported = require_passkeys.isPasskeySupported;
|
|
227
|
+
exports.resolveAuthMessages = require_messages.resolveAuthMessages;
|
|
228
|
+
exports.startPasskeyAuthentication = require_passkeys.startPasskeyAuthentication;
|
|
229
|
+
exports.startPasskeyRegistration = require_passkeys.startPasskeyRegistration;
|
|
230
|
+
exports.useAuth = require_react.useAuth;
|
|
231
|
+
exports.useSession = require_react.useSession;
|
|
232
|
+
exports.useUser = require_react.useUser;
|
|
233
|
+
|
|
234
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createPasskeyBrowserHelpers"],"sources":["../../../src/auth/client/index.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AuthClientOptions,\n AuthClientSnapshot,\n AuthClientSignInInput,\n AuthClientTotpEnrollment,\n AuthClientEnrollmentResult,\n AuthClientRecoveryCodesResult,\n AuthClientFactorList,\n AuthClientRegisterInput,\n AuthClientLifecycleResult,\n} from \"../shared\";\n\nimport {\n createPasskeyBrowserHelpers,\n type PasskeyBrowserHelpers,\n} from \"./passkeys\";\n\nexport type {\n AuthClientStatus,\n AuthClientUser,\n AuthClientOptions,\n AuthClientSnapshot,\n AuthClientMfaState,\n AuthClientSignInInput,\n AuthClientRegisterInput,\n AuthClientMfaFactor,\n AuthClientTotpEnrollment,\n AuthClientEnrollmentResult,\n AuthClientRecoveryCodesResult,\n AuthClientFactorList,\n} from \"../shared\";\n\nexport {\n createPasskeyBrowserHelpers,\n isPasskeySupported,\n startPasskeyRegistration,\n startPasskeyAuthentication,\n type PasskeyBrowserAdapter,\n type PasskeyBrowserHelpers,\n} from \"./passkeys\";\n\nexport class AuthClientError extends Error {\n readonly status: number;\n readonly code: string;\n\n constructor(input: {\n readonly status: number;\n readonly code: string;\n readonly message: string;\n }) {\n super(input.message);\n\n this.name = \"AuthClientError\";\n this.status = input.status;\n this.code = input.code;\n }\n}\n\nexport type AuthClient = {\n register(input: AuthClientRegisterInput): Promise<AuthClientSnapshot>;\n\n beginRequiredTotpEnrollment(\n label?: string,\n ): Promise<AuthClientTotpEnrollment>;\n\n verifyRequiredTotpEnrollment(\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n registerRequiredPasskey(label?: string): Promise<AuthClientEnrollmentResult>;\n\n getSnapshot(): Promise<AuthClientSnapshot>;\n\n signIn(input: AuthClientSignInInput): Promise<AuthClientSnapshot>;\n signOut(): Promise<void>;\n\n verifyMfaTotp(code: string): Promise<AuthClientSnapshot>;\n verifyMfaRecoveryCode(code: string): Promise<AuthClientSnapshot>;\n\n signInWithPasskey(): Promise<AuthClientSnapshot>;\n verifyMfaWithPasskey(): Promise<AuthClientSnapshot>;\n\n beginTotpEnrollment(\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientTotpEnrollment>;\n\n verifyTotpEnrollment(\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n registerPasskey(\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n listMfaFactors(): Promise<AuthClientFactorList>;\n\n removeMfaFactor(factorId: string, currentPassword: string): Promise<void>;\n\n regenerateRecoveryCodes(\n currentPassword: string,\n ): Promise<AuthClientRecoveryCodesResult>;\n\n beginStepUp(): Promise<AuthClientSnapshot>;\n verifyStepUpTotp(code: string): Promise<AuthClientSnapshot>;\n verifyStepUpRecoveryCode(code: string): Promise<AuthClientSnapshot>;\n verifyStepUpWithPasskey(): Promise<AuthClientSnapshot>;\n\n isPasskeySupported(): boolean;\n\n requestEmailVerification(): Promise<AuthClientLifecycleResult>;\n\n verifyEmail(token: string): Promise<AuthClientLifecycleResult>;\n\n requestPasswordReset(email: string): Promise<AuthClientLifecycleResult>;\n\n resetPassword(\n token: string,\n newPassword: string,\n ): Promise<AuthClientLifecycleResult>;\n\n changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<AuthClientLifecycleResult>;\n};\n\ntype AuthApiErrorResponse = {\n readonly error?: {\n readonly code?: string;\n readonly message?: string;\n };\n};\n\ntype AuthApiSnapshotResponse = {\n readonly status: AuthClientSnapshot[\"status\"];\n readonly user?: AuthClientSnapshot[\"user\"];\n readonly mfa?: AuthClientSnapshot[\"mfa\"];\n};\n\ntype PasskeyOptionsResponse = {\n readonly options: Readonly<Record<string, unknown>>;\n};\n\ntype AuthClientFactoryOptions = AuthClientOptions & {\n readonly passkeys?: PasskeyBrowserHelpers;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst normalizeBasePath = (value: string | undefined): string => {\n const basePath = value ?? \"/api/auth\";\n\n if (\n !basePath.startsWith(\"/\") ||\n basePath.startsWith(\"//\") ||\n basePath.includes(\"?\") ||\n basePath.includes(\"#\")\n ) {\n throw new TypeError(\"AuthClient basePath must be an absolute path.\");\n }\n\n return basePath.replace(/\\/+$/, \"\");\n};\n\nconst getError = (response: Response, payload: unknown): AuthClientError => {\n const value = isRecord(payload)\n ? (payload as AuthApiErrorResponse).error\n : undefined;\n\n return new AuthClientError({\n status: response.status,\n code: value?.code ?? \"AUTH_REQUEST_FAILED\",\n message: value?.message ?? \"The authentication request failed.\",\n });\n};\n\nconst parseJson = async (response: Response): Promise<unknown> => {\n try {\n return await response.json();\n } catch {\n return null;\n }\n};\n\nexport const createAuthClient = (\n options: AuthClientFactoryOptions = {},\n): AuthClient => {\n const basePath = normalizeBasePath(options.basePath);\n const fetcher = options.fetcher ?? fetch;\n const credentials = options.credentials ?? \"same-origin\";\n\n const passkeys = options.passkeys ?? createPasskeyBrowserHelpers();\n\n let snapshot: AuthClientSnapshot = {\n status: \"loading\",\n user: null,\n };\n\n const request = async <T>(\n path: string,\n input?: {\n readonly method?: \"GET\" | \"POST\";\n readonly body?: unknown;\n },\n ): Promise<T> => {\n const method = input?.method ?? \"POST\";\n const headers = new Headers();\n\n if (input?.body !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const response = await fetcher(`${basePath}${path}`, {\n method,\n credentials,\n headers,\n ...(input?.body === undefined\n ? {}\n : {\n body: JSON.stringify(input.body),\n }),\n });\n\n const payload = await parseJson(response);\n\n if (!response.ok) {\n throw getError(response, payload);\n }\n\n return payload as T;\n };\n\n const post = <T>(path: string, body?: unknown): Promise<T> =>\n request<T>(path, {\n method: \"POST\",\n body,\n });\n\n const get = <T>(path: string): Promise<T> =>\n request<T>(path, {\n method: \"GET\",\n });\n\n const getSnapshot = async (): Promise<AuthClientSnapshot> => {\n const result = await get<AuthApiSnapshotResponse>(\"/state\");\n\n snapshot = {\n status: result.status,\n user: result.user ?? null,\n ...(result.mfa\n ? {\n mfa: result.mfa,\n }\n : {}),\n };\n\n return snapshot;\n };\n\n const refreshSnapshot = async (): Promise<AuthClientSnapshot> =>\n getSnapshot();\n\n const signIn = async (\n input: AuthClientSignInInput,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/sign-in\", input);\n\n return refreshSnapshot();\n };\n\n const register = async (\n input: AuthClientRegisterInput,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/register\", input);\n\n return refreshSnapshot();\n };\n\n const signOut = async (): Promise<void> => {\n await post(\"/sign-out\");\n\n snapshot = {\n status: \"unauthenticated\",\n user: null,\n };\n };\n\n const verifyMfaTotp = async (code: string): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/sign-in/totp\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyMfaRecoveryCode = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/sign-in/recovery-code\", { code });\n\n return refreshSnapshot();\n };\n\n const signInWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/sign-in/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/passkey/sign-in/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const verifyMfaWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/challenge/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/passkey/challenge/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const beginTotpEnrollment = async (\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientTotpEnrollment> =>\n post<AuthClientTotpEnrollment>(\"/mfa/totp/enrollment/start\", {\n currentPassword,\n ...(label === undefined ? {} : { label }),\n });\n\n const verifyTotpEnrollment = async (\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult> =>\n post<AuthClientEnrollmentResult>(\"/mfa/totp/enrollment/finish\", {\n factorId,\n code,\n });\n\n const registerPasskey = async (\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/enrollment/start\",\n {\n currentPassword,\n ...(label === undefined ? {} : { label }),\n },\n );\n\n const response = await passkeys.startRegistration(started.options);\n\n return post<AuthClientEnrollmentResult>(\"/mfa/passkey/enrollment/finish\", {\n response,\n });\n };\n\n const beginRequiredTotpEnrollment = async (\n label?: string,\n ): Promise<AuthClientTotpEnrollment> =>\n post<AuthClientTotpEnrollment>(\"/mfa/enrollment/required/totp/start\", {\n ...(label === undefined ? {} : { label }),\n });\n\n const verifyRequiredTotpEnrollment = async (\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const result = await post<AuthClientEnrollmentResult>(\n \"/mfa/enrollment/required/totp/finish\",\n {\n factorId,\n code,\n },\n );\n\n // The server only creates the authenticated session after the\n // TOTP factor, recovery codes and challenge have been committed.\n await refreshSnapshot();\n\n return result;\n };\n\n const registerRequiredPasskey = async (\n label?: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/enrollment/required/passkey/start\",\n {\n ...(label === undefined ? {} : { label }),\n },\n );\n\n const response = await passkeys.startRegistration(started.options);\n\n const completed = await post<AuthClientEnrollmentResult>(\n \"/mfa/enrollment/required/passkey/finish\",\n {\n response,\n },\n );\n\n await refreshSnapshot();\n\n return completed;\n };\n\n const listMfaFactors = (): Promise<AuthClientFactorList> =>\n get<AuthClientFactorList>(\"/mfa/factors\");\n\n const removeMfaFactor = async (\n factorId: string,\n currentPassword: string,\n ): Promise<void> => {\n await post(\"/mfa/factors/remove\", {\n factorId,\n currentPassword,\n });\n };\n\n const regenerateRecoveryCodes = (\n currentPassword: string,\n ): Promise<AuthClientRecoveryCodesResult> =>\n post<AuthClientRecoveryCodesResult>(\"/mfa/recovery-codes/regenerate\", {\n currentPassword,\n });\n\n const beginStepUp = async (): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/start\");\n\n return refreshSnapshot();\n };\n\n const verifyStepUpTotp = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/totp\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyStepUpRecoveryCode = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/recovery-code\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyStepUpWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/step-up/passkey/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/step-up/passkey/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const requestEmailVerification = () =>\n post<AuthClientLifecycleResult>(\"/email/verification/request\");\n\n const verifyEmail = (token: string) =>\n post<AuthClientLifecycleResult>(\"/email/verification/verify\", {\n token,\n });\n\n const requestPasswordReset = (email: string) =>\n post<AuthClientLifecycleResult>(\"/password/reset/request\", {\n email,\n });\n\n const resetPassword = (token: string, newPassword: string) =>\n post<AuthClientLifecycleResult>(\"/password/reset/finish\", {\n token,\n newPassword,\n });\n\n const changePassword = async (\n currentPassword: string,\n newPassword: string,\n ) => {\n const result = await post<AuthClientLifecycleResult>(\"/password/change\", {\n currentPassword,\n newPassword,\n });\n\n // Password changes invalidate existing sessions.\n // The server remains authoritative about the resulting state.\n await refreshSnapshot();\n\n return result;\n };\n\n return {\n register,\n getSnapshot,\n signIn,\n signOut,\n\n verifyMfaTotp,\n verifyMfaRecoveryCode,\n\n signInWithPasskey,\n verifyMfaWithPasskey,\n\n beginTotpEnrollment,\n verifyTotpEnrollment,\n beginRequiredTotpEnrollment,\n verifyRequiredTotpEnrollment,\n registerPasskey,\n registerRequiredPasskey,\n\n listMfaFactors,\n removeMfaFactor,\n regenerateRecoveryCodes,\n\n beginStepUp,\n verifyStepUpTotp,\n verifyStepUpRecoveryCode,\n verifyStepUpWithPasskey,\n\n isPasskeySupported: passkeys.isSupported,\n\n requestEmailVerification,\n verifyEmail,\n requestPasswordReset,\n resetPassword,\n changePassword,\n };\n};\n\nexport {\n AuthProvider,\n useAuth,\n useSession,\n useUser,\n SignInForm,\n SignUpForm,\n MfaChallengeForm,\n AuthScreen,\n MfaSettings,\n type AuthProviderProps,\n type AuthContextValue,\n type AuthFormProps,\n type SignInFormProps,\n type SignUpFormProps,\n type MfaChallengeFormProps,\n type AuthScreenProps,\n type MfaSettingsProps,\n} from \"./react\";\n\nexport {\n AuthExperience,\n type AuthExperienceProps,\n type AuthExperienceConfig,\n type AuthExperienceBranding,\n type AuthExperienceLayout,\n type AuthExperienceRedirects,\n type AuthCustomField,\n type AuthFieldOption,\n type AuthFieldValue,\n type AuthFieldValues,\n type AuthRegistrationInput,\n type AuthExperienceSubmitInput,\n} from \"./experience\";\n\nexport {\n getAuthLocale,\n resolveAuthMessages,\n type AuthLocale,\n type AuthMessages,\n type AuthMessageOverrides,\n} from \"./messages\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AuthClientEnrollmentResult, AuthClientFactorList, AuthClientLifecycleResult, AuthClientMfaFactor, AuthClientMfaState, AuthClientOptions, AuthClientRecoveryCodesResult, AuthClientRegisterInput, AuthClientSignInInput, AuthClientSnapshot, AuthClientStatus, AuthClientTotpEnrollment, AuthClientUser } from "../shared/index.cjs";
|
|
2
|
+
import { PasskeyBrowserAdapter, PasskeyBrowserHelpers, createPasskeyBrowserHelpers, isPasskeySupported, startPasskeyAuthentication, startPasskeyRegistration } from "./passkeys.cjs";
|
|
3
|
+
import { AuthContextValue, AuthFormProps, AuthProvider, AuthProviderProps, AuthScreen, AuthScreenProps, MfaChallengeForm, MfaChallengeFormProps, MfaSettings, MfaSettingsProps, SignInForm, SignInFormProps, SignUpForm, SignUpFormProps, useAuth, useSession, useUser } from "./react.cjs";
|
|
4
|
+
import { AuthCustomField, AuthExperience, AuthExperienceBranding, AuthExperienceConfig, AuthExperienceLayout, AuthExperienceProps, AuthExperienceRedirects, AuthExperienceSubmitInput, AuthFieldOption, AuthFieldValue, AuthFieldValues, AuthRegistrationInput } from "./experience.cjs";
|
|
5
|
+
import { AuthLocale, AuthMessageOverrides, AuthMessages, getAuthLocale, resolveAuthMessages } from "./messages.cjs";
|
|
6
|
+
export declare class AuthClientError extends Error {
|
|
7
|
+
readonly status: number;
|
|
8
|
+
readonly code: string;
|
|
9
|
+
constructor(input: {
|
|
10
|
+
readonly status: number;
|
|
11
|
+
readonly code: string;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export type AuthClient = {
|
|
16
|
+
register(input: AuthClientRegisterInput): Promise<AuthClientSnapshot>;
|
|
17
|
+
beginRequiredTotpEnrollment(label?: string): Promise<AuthClientTotpEnrollment>;
|
|
18
|
+
verifyRequiredTotpEnrollment(factorId: string, code: string): Promise<AuthClientEnrollmentResult>;
|
|
19
|
+
registerRequiredPasskey(label?: string): Promise<AuthClientEnrollmentResult>;
|
|
20
|
+
getSnapshot(): Promise<AuthClientSnapshot>;
|
|
21
|
+
signIn(input: AuthClientSignInInput): Promise<AuthClientSnapshot>;
|
|
22
|
+
signOut(): Promise<void>;
|
|
23
|
+
verifyMfaTotp(code: string): Promise<AuthClientSnapshot>;
|
|
24
|
+
verifyMfaRecoveryCode(code: string): Promise<AuthClientSnapshot>;
|
|
25
|
+
signInWithPasskey(): Promise<AuthClientSnapshot>;
|
|
26
|
+
verifyMfaWithPasskey(): Promise<AuthClientSnapshot>;
|
|
27
|
+
beginTotpEnrollment(currentPassword: string, label?: string): Promise<AuthClientTotpEnrollment>;
|
|
28
|
+
verifyTotpEnrollment(factorId: string, code: string): Promise<AuthClientEnrollmentResult>;
|
|
29
|
+
registerPasskey(currentPassword: string, label?: string): Promise<AuthClientEnrollmentResult>;
|
|
30
|
+
listMfaFactors(): Promise<AuthClientFactorList>;
|
|
31
|
+
removeMfaFactor(factorId: string, currentPassword: string): Promise<void>;
|
|
32
|
+
regenerateRecoveryCodes(currentPassword: string): Promise<AuthClientRecoveryCodesResult>;
|
|
33
|
+
beginStepUp(): Promise<AuthClientSnapshot>;
|
|
34
|
+
verifyStepUpTotp(code: string): Promise<AuthClientSnapshot>;
|
|
35
|
+
verifyStepUpRecoveryCode(code: string): Promise<AuthClientSnapshot>;
|
|
36
|
+
verifyStepUpWithPasskey(): Promise<AuthClientSnapshot>;
|
|
37
|
+
isPasskeySupported(): boolean;
|
|
38
|
+
requestEmailVerification(): Promise<AuthClientLifecycleResult>;
|
|
39
|
+
verifyEmail(token: string): Promise<AuthClientLifecycleResult>;
|
|
40
|
+
requestPasswordReset(email: string): Promise<AuthClientLifecycleResult>;
|
|
41
|
+
resetPassword(token: string, newPassword: string): Promise<AuthClientLifecycleResult>;
|
|
42
|
+
changePassword(currentPassword: string, newPassword: string): Promise<AuthClientLifecycleResult>;
|
|
43
|
+
};
|
|
44
|
+
type AuthClientFactoryOptions = AuthClientOptions & {
|
|
45
|
+
readonly passkeys?: PasskeyBrowserHelpers;
|
|
46
|
+
};
|
|
47
|
+
export declare const createAuthClient: (options?: AuthClientFactoryOptions) => AuthClient;
|
|
48
|
+
export { type AuthClientEnrollmentResult, type AuthClientFactorList, type AuthClientMfaFactor, type AuthClientMfaState, type AuthClientOptions, type AuthClientRecoveryCodesResult, type AuthClientRegisterInput, type AuthClientSignInInput, type AuthClientSnapshot, type AuthClientStatus, type AuthClientTotpEnrollment, type AuthClientUser, type AuthContextValue, type AuthCustomField, AuthExperience, type AuthExperienceBranding, type AuthExperienceConfig, type AuthExperienceLayout, type AuthExperienceProps, type AuthExperienceRedirects, type AuthExperienceSubmitInput, type AuthFieldOption, type AuthFieldValue, type AuthFieldValues, type AuthFormProps, type AuthLocale, type AuthMessageOverrides, type AuthMessages, AuthProvider, type AuthProviderProps, type AuthRegistrationInput, AuthScreen, type AuthScreenProps, MfaChallengeForm, type MfaChallengeFormProps, MfaSettings, type MfaSettingsProps, type PasskeyBrowserAdapter, type PasskeyBrowserHelpers, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, createPasskeyBrowserHelpers, getAuthLocale, isPasskeySupported, resolveAuthMessages, startPasskeyAuthentication, startPasskeyRegistration, useAuth, useSession, useUser };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AuthClientEnrollmentResult, AuthClientFactorList, AuthClientLifecycleResult, AuthClientMfaFactor, AuthClientMfaState, AuthClientOptions, AuthClientRecoveryCodesResult, AuthClientRegisterInput, AuthClientSignInInput, AuthClientSnapshot, AuthClientStatus, AuthClientTotpEnrollment, AuthClientUser } from "../shared/index.js";
|
|
2
|
+
import { PasskeyBrowserAdapter, PasskeyBrowserHelpers, createPasskeyBrowserHelpers, isPasskeySupported, startPasskeyAuthentication, startPasskeyRegistration } from "./passkeys.js";
|
|
3
|
+
import { AuthContextValue, AuthFormProps, AuthProvider, AuthProviderProps, AuthScreen, AuthScreenProps, MfaChallengeForm, MfaChallengeFormProps, MfaSettings, MfaSettingsProps, SignInForm, SignInFormProps, SignUpForm, SignUpFormProps, useAuth, useSession, useUser } from "./react.js";
|
|
4
|
+
import { AuthCustomField, AuthExperience, AuthExperienceBranding, AuthExperienceConfig, AuthExperienceLayout, AuthExperienceProps, AuthExperienceRedirects, AuthExperienceSubmitInput, AuthFieldOption, AuthFieldValue, AuthFieldValues, AuthRegistrationInput } from "./experience.js";
|
|
5
|
+
import { AuthLocale, AuthMessageOverrides, AuthMessages, getAuthLocale, resolveAuthMessages } from "./messages.js";
|
|
6
|
+
export declare class AuthClientError extends Error {
|
|
7
|
+
readonly status: number;
|
|
8
|
+
readonly code: string;
|
|
9
|
+
constructor(input: {
|
|
10
|
+
readonly status: number;
|
|
11
|
+
readonly code: string;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export type AuthClient = {
|
|
16
|
+
register(input: AuthClientRegisterInput): Promise<AuthClientSnapshot>;
|
|
17
|
+
beginRequiredTotpEnrollment(label?: string): Promise<AuthClientTotpEnrollment>;
|
|
18
|
+
verifyRequiredTotpEnrollment(factorId: string, code: string): Promise<AuthClientEnrollmentResult>;
|
|
19
|
+
registerRequiredPasskey(label?: string): Promise<AuthClientEnrollmentResult>;
|
|
20
|
+
getSnapshot(): Promise<AuthClientSnapshot>;
|
|
21
|
+
signIn(input: AuthClientSignInInput): Promise<AuthClientSnapshot>;
|
|
22
|
+
signOut(): Promise<void>;
|
|
23
|
+
verifyMfaTotp(code: string): Promise<AuthClientSnapshot>;
|
|
24
|
+
verifyMfaRecoveryCode(code: string): Promise<AuthClientSnapshot>;
|
|
25
|
+
signInWithPasskey(): Promise<AuthClientSnapshot>;
|
|
26
|
+
verifyMfaWithPasskey(): Promise<AuthClientSnapshot>;
|
|
27
|
+
beginTotpEnrollment(currentPassword: string, label?: string): Promise<AuthClientTotpEnrollment>;
|
|
28
|
+
verifyTotpEnrollment(factorId: string, code: string): Promise<AuthClientEnrollmentResult>;
|
|
29
|
+
registerPasskey(currentPassword: string, label?: string): Promise<AuthClientEnrollmentResult>;
|
|
30
|
+
listMfaFactors(): Promise<AuthClientFactorList>;
|
|
31
|
+
removeMfaFactor(factorId: string, currentPassword: string): Promise<void>;
|
|
32
|
+
regenerateRecoveryCodes(currentPassword: string): Promise<AuthClientRecoveryCodesResult>;
|
|
33
|
+
beginStepUp(): Promise<AuthClientSnapshot>;
|
|
34
|
+
verifyStepUpTotp(code: string): Promise<AuthClientSnapshot>;
|
|
35
|
+
verifyStepUpRecoveryCode(code: string): Promise<AuthClientSnapshot>;
|
|
36
|
+
verifyStepUpWithPasskey(): Promise<AuthClientSnapshot>;
|
|
37
|
+
isPasskeySupported(): boolean;
|
|
38
|
+
requestEmailVerification(): Promise<AuthClientLifecycleResult>;
|
|
39
|
+
verifyEmail(token: string): Promise<AuthClientLifecycleResult>;
|
|
40
|
+
requestPasswordReset(email: string): Promise<AuthClientLifecycleResult>;
|
|
41
|
+
resetPassword(token: string, newPassword: string): Promise<AuthClientLifecycleResult>;
|
|
42
|
+
changePassword(currentPassword: string, newPassword: string): Promise<AuthClientLifecycleResult>;
|
|
43
|
+
};
|
|
44
|
+
type AuthClientFactoryOptions = AuthClientOptions & {
|
|
45
|
+
readonly passkeys?: PasskeyBrowserHelpers;
|
|
46
|
+
};
|
|
47
|
+
export declare const createAuthClient: (options?: AuthClientFactoryOptions) => AuthClient;
|
|
48
|
+
export { type AuthClientEnrollmentResult, type AuthClientFactorList, type AuthClientMfaFactor, type AuthClientMfaState, type AuthClientOptions, type AuthClientRecoveryCodesResult, type AuthClientRegisterInput, type AuthClientSignInInput, type AuthClientSnapshot, type AuthClientStatus, type AuthClientTotpEnrollment, type AuthClientUser, type AuthContextValue, type AuthCustomField, AuthExperience, type AuthExperienceBranding, type AuthExperienceConfig, type AuthExperienceLayout, type AuthExperienceProps, type AuthExperienceRedirects, type AuthExperienceSubmitInput, type AuthFieldOption, type AuthFieldValue, type AuthFieldValues, type AuthFormProps, type AuthLocale, type AuthMessageOverrides, type AuthMessages, AuthProvider, type AuthProviderProps, type AuthRegistrationInput, AuthScreen, type AuthScreenProps, MfaChallengeForm, type MfaChallengeFormProps, MfaSettings, type MfaSettingsProps, type PasskeyBrowserAdapter, type PasskeyBrowserHelpers, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, createPasskeyBrowserHelpers, getAuthLocale, isPasskeySupported, resolveAuthMessages, startPasskeyAuthentication, startPasskeyRegistration, useAuth, useSession, useUser };
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createPasskeyBrowserHelpers, isPasskeySupported, startPasskeyAuthentication, startPasskeyRegistration } from "./passkeys.js";
|
|
3
|
+
import { AuthProvider, AuthScreen, MfaChallengeForm, MfaSettings, SignInForm, SignUpForm, useAuth, useSession, useUser } from "./react.js";
|
|
4
|
+
import { AuthExperience } from "./experience.js";
|
|
5
|
+
import { getAuthLocale, resolveAuthMessages } from "./messages.js";
|
|
6
|
+
// src/auth/client/index.ts
|
|
7
|
+
var AuthClientError = class extends Error {
|
|
8
|
+
status;
|
|
9
|
+
code;
|
|
10
|
+
constructor(input) {
|
|
11
|
+
super(input.message);
|
|
12
|
+
this.name = "AuthClientError";
|
|
13
|
+
this.status = input.status;
|
|
14
|
+
this.code = input.code;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
18
|
+
const normalizeBasePath = (value) => {
|
|
19
|
+
const basePath = value ?? "/api/auth";
|
|
20
|
+
if (!basePath.startsWith("/") || basePath.startsWith("//") || basePath.includes("?") || basePath.includes("#")) throw new TypeError("AuthClient basePath must be an absolute path.");
|
|
21
|
+
return basePath.replace(/\/+$/, "");
|
|
22
|
+
};
|
|
23
|
+
const getError = (response, payload) => {
|
|
24
|
+
const value = isRecord(payload) ? payload.error : void 0;
|
|
25
|
+
return new AuthClientError({
|
|
26
|
+
status: response.status,
|
|
27
|
+
code: value?.code ?? "AUTH_REQUEST_FAILED",
|
|
28
|
+
message: value?.message ?? "The authentication request failed."
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
const parseJson = async (response) => {
|
|
32
|
+
try {
|
|
33
|
+
return await response.json();
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const createAuthClient = (options = {}) => {
|
|
39
|
+
const basePath = normalizeBasePath(options.basePath);
|
|
40
|
+
const fetcher = options.fetcher ?? fetch;
|
|
41
|
+
const credentials = options.credentials ?? "same-origin";
|
|
42
|
+
const passkeys = options.passkeys ?? createPasskeyBrowserHelpers();
|
|
43
|
+
let snapshot = {
|
|
44
|
+
status: "loading",
|
|
45
|
+
user: null
|
|
46
|
+
};
|
|
47
|
+
const request = async (path, input) => {
|
|
48
|
+
const method = input?.method ?? "POST";
|
|
49
|
+
const headers = new Headers();
|
|
50
|
+
if (input?.body !== void 0) headers.set("Content-Type", "application/json");
|
|
51
|
+
const response = await fetcher(`${basePath}${path}`, {
|
|
52
|
+
method,
|
|
53
|
+
credentials,
|
|
54
|
+
headers,
|
|
55
|
+
...input?.body === void 0 ? {} : { body: JSON.stringify(input.body) }
|
|
56
|
+
});
|
|
57
|
+
const payload = await parseJson(response);
|
|
58
|
+
if (!response.ok) throw getError(response, payload);
|
|
59
|
+
return payload;
|
|
60
|
+
};
|
|
61
|
+
const post = (path, body) => request(path, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
body
|
|
64
|
+
});
|
|
65
|
+
const get = (path) => request(path, { method: "GET" });
|
|
66
|
+
const getSnapshot = async () => {
|
|
67
|
+
const result = await get("/state");
|
|
68
|
+
snapshot = {
|
|
69
|
+
status: result.status,
|
|
70
|
+
user: result.user ?? null,
|
|
71
|
+
...result.mfa ? { mfa: result.mfa } : {}
|
|
72
|
+
};
|
|
73
|
+
return snapshot;
|
|
74
|
+
};
|
|
75
|
+
const refreshSnapshot = async () => getSnapshot();
|
|
76
|
+
const signIn = async (input) => {
|
|
77
|
+
await post("/sign-in", input);
|
|
78
|
+
return refreshSnapshot();
|
|
79
|
+
};
|
|
80
|
+
const register = async (input) => {
|
|
81
|
+
await post("/register", input);
|
|
82
|
+
return refreshSnapshot();
|
|
83
|
+
};
|
|
84
|
+
const signOut = async () => {
|
|
85
|
+
await post("/sign-out");
|
|
86
|
+
snapshot = {
|
|
87
|
+
status: "unauthenticated",
|
|
88
|
+
user: null
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
const verifyMfaTotp = async (code) => {
|
|
92
|
+
await post("/mfa/sign-in/totp", { code });
|
|
93
|
+
return refreshSnapshot();
|
|
94
|
+
};
|
|
95
|
+
const verifyMfaRecoveryCode = async (code) => {
|
|
96
|
+
await post("/mfa/sign-in/recovery-code", { code });
|
|
97
|
+
return refreshSnapshot();
|
|
98
|
+
};
|
|
99
|
+
const signInWithPasskey = async () => {
|
|
100
|
+
const started = await post("/mfa/passkey/sign-in/start");
|
|
101
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
102
|
+
await post("/mfa/passkey/sign-in/finish", { response });
|
|
103
|
+
return refreshSnapshot();
|
|
104
|
+
};
|
|
105
|
+
const verifyMfaWithPasskey = async () => {
|
|
106
|
+
const started = await post("/mfa/passkey/challenge/start");
|
|
107
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
108
|
+
await post("/mfa/passkey/challenge/finish", { response });
|
|
109
|
+
return refreshSnapshot();
|
|
110
|
+
};
|
|
111
|
+
const beginTotpEnrollment = async (currentPassword, label) => post("/mfa/totp/enrollment/start", {
|
|
112
|
+
currentPassword,
|
|
113
|
+
...label === void 0 ? {} : { label }
|
|
114
|
+
});
|
|
115
|
+
const verifyTotpEnrollment = async (factorId, code) => post("/mfa/totp/enrollment/finish", {
|
|
116
|
+
factorId,
|
|
117
|
+
code
|
|
118
|
+
});
|
|
119
|
+
const registerPasskey = async (currentPassword, label) => {
|
|
120
|
+
const started = await post("/mfa/passkey/enrollment/start", {
|
|
121
|
+
currentPassword,
|
|
122
|
+
...label === void 0 ? {} : { label }
|
|
123
|
+
});
|
|
124
|
+
const response = await passkeys.startRegistration(started.options);
|
|
125
|
+
return post("/mfa/passkey/enrollment/finish", { response });
|
|
126
|
+
};
|
|
127
|
+
const beginRequiredTotpEnrollment = async (label) => post("/mfa/enrollment/required/totp/start", { ...label === void 0 ? {} : { label } });
|
|
128
|
+
const verifyRequiredTotpEnrollment = async (factorId, code) => {
|
|
129
|
+
const result = await post("/mfa/enrollment/required/totp/finish", {
|
|
130
|
+
factorId,
|
|
131
|
+
code
|
|
132
|
+
});
|
|
133
|
+
await refreshSnapshot();
|
|
134
|
+
return result;
|
|
135
|
+
};
|
|
136
|
+
const registerRequiredPasskey = async (label) => {
|
|
137
|
+
const started = await post("/mfa/enrollment/required/passkey/start", { ...label === void 0 ? {} : { label } });
|
|
138
|
+
const response = await passkeys.startRegistration(started.options);
|
|
139
|
+
const completed = await post("/mfa/enrollment/required/passkey/finish", { response });
|
|
140
|
+
await refreshSnapshot();
|
|
141
|
+
return completed;
|
|
142
|
+
};
|
|
143
|
+
const listMfaFactors = () => get("/mfa/factors");
|
|
144
|
+
const removeMfaFactor = async (factorId, currentPassword) => {
|
|
145
|
+
await post("/mfa/factors/remove", {
|
|
146
|
+
factorId,
|
|
147
|
+
currentPassword
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
const regenerateRecoveryCodes = (currentPassword) => post("/mfa/recovery-codes/regenerate", { currentPassword });
|
|
151
|
+
const beginStepUp = async () => {
|
|
152
|
+
await post("/mfa/step-up/start");
|
|
153
|
+
return refreshSnapshot();
|
|
154
|
+
};
|
|
155
|
+
const verifyStepUpTotp = async (code) => {
|
|
156
|
+
await post("/mfa/step-up/totp", { code });
|
|
157
|
+
return refreshSnapshot();
|
|
158
|
+
};
|
|
159
|
+
const verifyStepUpRecoveryCode = async (code) => {
|
|
160
|
+
await post("/mfa/step-up/recovery-code", { code });
|
|
161
|
+
return refreshSnapshot();
|
|
162
|
+
};
|
|
163
|
+
const verifyStepUpWithPasskey = async () => {
|
|
164
|
+
const started = await post("/mfa/step-up/passkey/start");
|
|
165
|
+
const response = await passkeys.startAuthentication(started.options);
|
|
166
|
+
await post("/mfa/step-up/passkey/finish", { response });
|
|
167
|
+
return refreshSnapshot();
|
|
168
|
+
};
|
|
169
|
+
const requestEmailVerification = () => post("/email/verification/request");
|
|
170
|
+
const verifyEmail = (token) => post("/email/verification/verify", { token });
|
|
171
|
+
const requestPasswordReset = (email) => post("/password/reset/request", { email });
|
|
172
|
+
const resetPassword = (token, newPassword) => post("/password/reset/finish", {
|
|
173
|
+
token,
|
|
174
|
+
newPassword
|
|
175
|
+
});
|
|
176
|
+
const changePassword = async (currentPassword, newPassword) => {
|
|
177
|
+
const result = await post("/password/change", {
|
|
178
|
+
currentPassword,
|
|
179
|
+
newPassword
|
|
180
|
+
});
|
|
181
|
+
await refreshSnapshot();
|
|
182
|
+
return result;
|
|
183
|
+
};
|
|
184
|
+
return {
|
|
185
|
+
register,
|
|
186
|
+
getSnapshot,
|
|
187
|
+
signIn,
|
|
188
|
+
signOut,
|
|
189
|
+
verifyMfaTotp,
|
|
190
|
+
verifyMfaRecoveryCode,
|
|
191
|
+
signInWithPasskey,
|
|
192
|
+
verifyMfaWithPasskey,
|
|
193
|
+
beginTotpEnrollment,
|
|
194
|
+
verifyTotpEnrollment,
|
|
195
|
+
beginRequiredTotpEnrollment,
|
|
196
|
+
verifyRequiredTotpEnrollment,
|
|
197
|
+
registerPasskey,
|
|
198
|
+
registerRequiredPasskey,
|
|
199
|
+
listMfaFactors,
|
|
200
|
+
removeMfaFactor,
|
|
201
|
+
regenerateRecoveryCodes,
|
|
202
|
+
beginStepUp,
|
|
203
|
+
verifyStepUpTotp,
|
|
204
|
+
verifyStepUpRecoveryCode,
|
|
205
|
+
verifyStepUpWithPasskey,
|
|
206
|
+
isPasskeySupported: passkeys.isSupported,
|
|
207
|
+
requestEmailVerification,
|
|
208
|
+
verifyEmail,
|
|
209
|
+
requestPasswordReset,
|
|
210
|
+
resetPassword,
|
|
211
|
+
changePassword
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
export { AuthClientError, AuthExperience, AuthProvider, AuthScreen, MfaChallengeForm, MfaSettings, SignInForm, SignUpForm, createAuthClient, createPasskeyBrowserHelpers, getAuthLocale, isPasskeySupported, resolveAuthMessages, startPasskeyAuthentication, startPasskeyRegistration, useAuth, useSession, useUser };
|
|
215
|
+
|
|
216
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/auth/client/index.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AuthClientOptions,\n AuthClientSnapshot,\n AuthClientSignInInput,\n AuthClientTotpEnrollment,\n AuthClientEnrollmentResult,\n AuthClientRecoveryCodesResult,\n AuthClientFactorList,\n AuthClientRegisterInput,\n AuthClientLifecycleResult,\n} from \"../shared\";\n\nimport {\n createPasskeyBrowserHelpers,\n type PasskeyBrowserHelpers,\n} from \"./passkeys\";\n\nexport type {\n AuthClientStatus,\n AuthClientUser,\n AuthClientOptions,\n AuthClientSnapshot,\n AuthClientMfaState,\n AuthClientSignInInput,\n AuthClientRegisterInput,\n AuthClientMfaFactor,\n AuthClientTotpEnrollment,\n AuthClientEnrollmentResult,\n AuthClientRecoveryCodesResult,\n AuthClientFactorList,\n} from \"../shared\";\n\nexport {\n createPasskeyBrowserHelpers,\n isPasskeySupported,\n startPasskeyRegistration,\n startPasskeyAuthentication,\n type PasskeyBrowserAdapter,\n type PasskeyBrowserHelpers,\n} from \"./passkeys\";\n\nexport class AuthClientError extends Error {\n readonly status: number;\n readonly code: string;\n\n constructor(input: {\n readonly status: number;\n readonly code: string;\n readonly message: string;\n }) {\n super(input.message);\n\n this.name = \"AuthClientError\";\n this.status = input.status;\n this.code = input.code;\n }\n}\n\nexport type AuthClient = {\n register(input: AuthClientRegisterInput): Promise<AuthClientSnapshot>;\n\n beginRequiredTotpEnrollment(\n label?: string,\n ): Promise<AuthClientTotpEnrollment>;\n\n verifyRequiredTotpEnrollment(\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n registerRequiredPasskey(label?: string): Promise<AuthClientEnrollmentResult>;\n\n getSnapshot(): Promise<AuthClientSnapshot>;\n\n signIn(input: AuthClientSignInInput): Promise<AuthClientSnapshot>;\n signOut(): Promise<void>;\n\n verifyMfaTotp(code: string): Promise<AuthClientSnapshot>;\n verifyMfaRecoveryCode(code: string): Promise<AuthClientSnapshot>;\n\n signInWithPasskey(): Promise<AuthClientSnapshot>;\n verifyMfaWithPasskey(): Promise<AuthClientSnapshot>;\n\n beginTotpEnrollment(\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientTotpEnrollment>;\n\n verifyTotpEnrollment(\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n registerPasskey(\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientEnrollmentResult>;\n\n listMfaFactors(): Promise<AuthClientFactorList>;\n\n removeMfaFactor(factorId: string, currentPassword: string): Promise<void>;\n\n regenerateRecoveryCodes(\n currentPassword: string,\n ): Promise<AuthClientRecoveryCodesResult>;\n\n beginStepUp(): Promise<AuthClientSnapshot>;\n verifyStepUpTotp(code: string): Promise<AuthClientSnapshot>;\n verifyStepUpRecoveryCode(code: string): Promise<AuthClientSnapshot>;\n verifyStepUpWithPasskey(): Promise<AuthClientSnapshot>;\n\n isPasskeySupported(): boolean;\n\n requestEmailVerification(): Promise<AuthClientLifecycleResult>;\n\n verifyEmail(token: string): Promise<AuthClientLifecycleResult>;\n\n requestPasswordReset(email: string): Promise<AuthClientLifecycleResult>;\n\n resetPassword(\n token: string,\n newPassword: string,\n ): Promise<AuthClientLifecycleResult>;\n\n changePassword(\n currentPassword: string,\n newPassword: string,\n ): Promise<AuthClientLifecycleResult>;\n};\n\ntype AuthApiErrorResponse = {\n readonly error?: {\n readonly code?: string;\n readonly message?: string;\n };\n};\n\ntype AuthApiSnapshotResponse = {\n readonly status: AuthClientSnapshot[\"status\"];\n readonly user?: AuthClientSnapshot[\"user\"];\n readonly mfa?: AuthClientSnapshot[\"mfa\"];\n};\n\ntype PasskeyOptionsResponse = {\n readonly options: Readonly<Record<string, unknown>>;\n};\n\ntype AuthClientFactoryOptions = AuthClientOptions & {\n readonly passkeys?: PasskeyBrowserHelpers;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst normalizeBasePath = (value: string | undefined): string => {\n const basePath = value ?? \"/api/auth\";\n\n if (\n !basePath.startsWith(\"/\") ||\n basePath.startsWith(\"//\") ||\n basePath.includes(\"?\") ||\n basePath.includes(\"#\")\n ) {\n throw new TypeError(\"AuthClient basePath must be an absolute path.\");\n }\n\n return basePath.replace(/\\/+$/, \"\");\n};\n\nconst getError = (response: Response, payload: unknown): AuthClientError => {\n const value = isRecord(payload)\n ? (payload as AuthApiErrorResponse).error\n : undefined;\n\n return new AuthClientError({\n status: response.status,\n code: value?.code ?? \"AUTH_REQUEST_FAILED\",\n message: value?.message ?? \"The authentication request failed.\",\n });\n};\n\nconst parseJson = async (response: Response): Promise<unknown> => {\n try {\n return await response.json();\n } catch {\n return null;\n }\n};\n\nexport const createAuthClient = (\n options: AuthClientFactoryOptions = {},\n): AuthClient => {\n const basePath = normalizeBasePath(options.basePath);\n const fetcher = options.fetcher ?? fetch;\n const credentials = options.credentials ?? \"same-origin\";\n\n const passkeys = options.passkeys ?? createPasskeyBrowserHelpers();\n\n let snapshot: AuthClientSnapshot = {\n status: \"loading\",\n user: null,\n };\n\n const request = async <T>(\n path: string,\n input?: {\n readonly method?: \"GET\" | \"POST\";\n readonly body?: unknown;\n },\n ): Promise<T> => {\n const method = input?.method ?? \"POST\";\n const headers = new Headers();\n\n if (input?.body !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n\n const response = await fetcher(`${basePath}${path}`, {\n method,\n credentials,\n headers,\n ...(input?.body === undefined\n ? {}\n : {\n body: JSON.stringify(input.body),\n }),\n });\n\n const payload = await parseJson(response);\n\n if (!response.ok) {\n throw getError(response, payload);\n }\n\n return payload as T;\n };\n\n const post = <T>(path: string, body?: unknown): Promise<T> =>\n request<T>(path, {\n method: \"POST\",\n body,\n });\n\n const get = <T>(path: string): Promise<T> =>\n request<T>(path, {\n method: \"GET\",\n });\n\n const getSnapshot = async (): Promise<AuthClientSnapshot> => {\n const result = await get<AuthApiSnapshotResponse>(\"/state\");\n\n snapshot = {\n status: result.status,\n user: result.user ?? null,\n ...(result.mfa\n ? {\n mfa: result.mfa,\n }\n : {}),\n };\n\n return snapshot;\n };\n\n const refreshSnapshot = async (): Promise<AuthClientSnapshot> =>\n getSnapshot();\n\n const signIn = async (\n input: AuthClientSignInInput,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/sign-in\", input);\n\n return refreshSnapshot();\n };\n\n const register = async (\n input: AuthClientRegisterInput,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/register\", input);\n\n return refreshSnapshot();\n };\n\n const signOut = async (): Promise<void> => {\n await post(\"/sign-out\");\n\n snapshot = {\n status: \"unauthenticated\",\n user: null,\n };\n };\n\n const verifyMfaTotp = async (code: string): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/sign-in/totp\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyMfaRecoveryCode = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/sign-in/recovery-code\", { code });\n\n return refreshSnapshot();\n };\n\n const signInWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/sign-in/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/passkey/sign-in/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const verifyMfaWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/challenge/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/passkey/challenge/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const beginTotpEnrollment = async (\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientTotpEnrollment> =>\n post<AuthClientTotpEnrollment>(\"/mfa/totp/enrollment/start\", {\n currentPassword,\n ...(label === undefined ? {} : { label }),\n });\n\n const verifyTotpEnrollment = async (\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult> =>\n post<AuthClientEnrollmentResult>(\"/mfa/totp/enrollment/finish\", {\n factorId,\n code,\n });\n\n const registerPasskey = async (\n currentPassword: string,\n label?: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/passkey/enrollment/start\",\n {\n currentPassword,\n ...(label === undefined ? {} : { label }),\n },\n );\n\n const response = await passkeys.startRegistration(started.options);\n\n return post<AuthClientEnrollmentResult>(\"/mfa/passkey/enrollment/finish\", {\n response,\n });\n };\n\n const beginRequiredTotpEnrollment = async (\n label?: string,\n ): Promise<AuthClientTotpEnrollment> =>\n post<AuthClientTotpEnrollment>(\"/mfa/enrollment/required/totp/start\", {\n ...(label === undefined ? {} : { label }),\n });\n\n const verifyRequiredTotpEnrollment = async (\n factorId: string,\n code: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const result = await post<AuthClientEnrollmentResult>(\n \"/mfa/enrollment/required/totp/finish\",\n {\n factorId,\n code,\n },\n );\n\n // The server only creates the authenticated session after the\n // TOTP factor, recovery codes and challenge have been committed.\n await refreshSnapshot();\n\n return result;\n };\n\n const registerRequiredPasskey = async (\n label?: string,\n ): Promise<AuthClientEnrollmentResult> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/enrollment/required/passkey/start\",\n {\n ...(label === undefined ? {} : { label }),\n },\n );\n\n const response = await passkeys.startRegistration(started.options);\n\n const completed = await post<AuthClientEnrollmentResult>(\n \"/mfa/enrollment/required/passkey/finish\",\n {\n response,\n },\n );\n\n await refreshSnapshot();\n\n return completed;\n };\n\n const listMfaFactors = (): Promise<AuthClientFactorList> =>\n get<AuthClientFactorList>(\"/mfa/factors\");\n\n const removeMfaFactor = async (\n factorId: string,\n currentPassword: string,\n ): Promise<void> => {\n await post(\"/mfa/factors/remove\", {\n factorId,\n currentPassword,\n });\n };\n\n const regenerateRecoveryCodes = (\n currentPassword: string,\n ): Promise<AuthClientRecoveryCodesResult> =>\n post<AuthClientRecoveryCodesResult>(\"/mfa/recovery-codes/regenerate\", {\n currentPassword,\n });\n\n const beginStepUp = async (): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/start\");\n\n return refreshSnapshot();\n };\n\n const verifyStepUpTotp = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/totp\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyStepUpRecoveryCode = async (\n code: string,\n ): Promise<AuthClientSnapshot> => {\n await post(\"/mfa/step-up/recovery-code\", { code });\n\n return refreshSnapshot();\n };\n\n const verifyStepUpWithPasskey = async (): Promise<AuthClientSnapshot> => {\n const started = await post<PasskeyOptionsResponse>(\n \"/mfa/step-up/passkey/start\",\n );\n\n const response = await passkeys.startAuthentication(started.options);\n\n await post(\"/mfa/step-up/passkey/finish\", {\n response,\n });\n\n return refreshSnapshot();\n };\n\n const requestEmailVerification = () =>\n post<AuthClientLifecycleResult>(\"/email/verification/request\");\n\n const verifyEmail = (token: string) =>\n post<AuthClientLifecycleResult>(\"/email/verification/verify\", {\n token,\n });\n\n const requestPasswordReset = (email: string) =>\n post<AuthClientLifecycleResult>(\"/password/reset/request\", {\n email,\n });\n\n const resetPassword = (token: string, newPassword: string) =>\n post<AuthClientLifecycleResult>(\"/password/reset/finish\", {\n token,\n newPassword,\n });\n\n const changePassword = async (\n currentPassword: string,\n newPassword: string,\n ) => {\n const result = await post<AuthClientLifecycleResult>(\"/password/change\", {\n currentPassword,\n newPassword,\n });\n\n // Password changes invalidate existing sessions.\n // The server remains authoritative about the resulting state.\n await refreshSnapshot();\n\n return result;\n };\n\n return {\n register,\n getSnapshot,\n signIn,\n signOut,\n\n verifyMfaTotp,\n verifyMfaRecoveryCode,\n\n signInWithPasskey,\n verifyMfaWithPasskey,\n\n beginTotpEnrollment,\n verifyTotpEnrollment,\n beginRequiredTotpEnrollment,\n verifyRequiredTotpEnrollment,\n registerPasskey,\n registerRequiredPasskey,\n\n listMfaFactors,\n removeMfaFactor,\n regenerateRecoveryCodes,\n\n beginStepUp,\n verifyStepUpTotp,\n verifyStepUpRecoveryCode,\n verifyStepUpWithPasskey,\n\n isPasskeySupported: passkeys.isSupported,\n\n requestEmailVerification,\n verifyEmail,\n requestPasswordReset,\n resetPassword,\n changePassword,\n };\n};\n\nexport {\n AuthProvider,\n useAuth,\n useSession,\n useUser,\n SignInForm,\n SignUpForm,\n MfaChallengeForm,\n AuthScreen,\n MfaSettings,\n type AuthProviderProps,\n type AuthContextValue,\n type AuthFormProps,\n type SignInFormProps,\n type SignUpFormProps,\n type MfaChallengeFormProps,\n type AuthScreenProps,\n type MfaSettingsProps,\n} from \"./react\";\n\nexport {\n AuthExperience,\n type AuthExperienceProps,\n type AuthExperienceConfig,\n type AuthExperienceBranding,\n type AuthExperienceLayout,\n type AuthExperienceRedirects,\n type AuthCustomField,\n type AuthFieldOption,\n type AuthFieldValue,\n type AuthFieldValues,\n type AuthRegistrationInput,\n type AuthExperienceSubmitInput,\n} from \"./experience\";\n\nexport {\n getAuthLocale,\n resolveAuthMessages,\n type AuthLocale,\n type AuthMessages,\n type AuthMessageOverrides,\n} from \"./messages\";\n"],"mappings":"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"}
|