@authsome/ui-core 0.1.8 → 1.0.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/dist/index.d.ts +1140 -618
- package/dist/index.js +1458 -1515
- package/dist/index.js.map +1 -1
- package/package.json +22 -45
- package/README.md +0 -166
- package/dist/adapters/index.d.mts +0 -65
- package/dist/adapters/index.d.ts +0 -65
- package/dist/adapters/index.js +0 -94
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/index.mjs +0 -92
- package/dist/adapters/index.mjs.map +0 -1
- package/dist/index.d.mts +0 -772
- package/dist/index.mjs +0 -1734
- package/dist/index.mjs.map +0 -1
- package/dist/provider-S9ZY5hsp.d.mts +0 -787
- package/dist/provider-S9ZY5hsp.d.ts +0 -787
- package/dist/types/index.d.mts +0 -98
- package/dist/types/index.d.ts +0 -98
- package/dist/types/index.js +0 -180
- package/dist/types/index.js.map +0 -1
- package/dist/types/index.mjs +0 -170
- package/dist/types/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,1781 +1,1724 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
AuthErrorType2["UNKNOWN_ERROR"] = "unknown_error";
|
|
24
|
-
return AuthErrorType2;
|
|
25
|
-
})(AuthErrorType || {});
|
|
26
|
-
var AuthError = class _AuthError extends Error {
|
|
27
|
-
constructor(message, type = "unknown_error" /* UNKNOWN_ERROR */, options) {
|
|
28
|
-
super(message);
|
|
29
|
-
this.name = "AuthError";
|
|
30
|
-
this.type = type;
|
|
31
|
-
this.details = options?.details;
|
|
32
|
-
this.code = options?.code;
|
|
33
|
-
this.originalError = options?.originalError;
|
|
34
|
-
if (Error.captureStackTrace) {
|
|
35
|
-
Error.captureStackTrace(this, _AuthError);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var OAuthProvider = /* @__PURE__ */ ((OAuthProvider2) => {
|
|
40
|
-
OAuthProvider2["GOOGLE"] = "google";
|
|
41
|
-
OAuthProvider2["GITHUB"] = "github";
|
|
42
|
-
OAuthProvider2["FACEBOOK"] = "facebook";
|
|
43
|
-
OAuthProvider2["TWITTER"] = "twitter";
|
|
44
|
-
OAuthProvider2["MICROSOFT"] = "microsoft";
|
|
45
|
-
OAuthProvider2["APPLE"] = "apple";
|
|
46
|
-
OAuthProvider2["LINKEDIN"] = "linkedin";
|
|
47
|
-
OAuthProvider2["DISCORD"] = "discord";
|
|
48
|
-
return OAuthProvider2;
|
|
49
|
-
})(OAuthProvider || {});
|
|
50
|
-
var TwoFactorMethod = /* @__PURE__ */ ((TwoFactorMethod2) => {
|
|
51
|
-
TwoFactorMethod2["TOTP"] = "totp";
|
|
52
|
-
TwoFactorMethod2["SMS"] = "sms";
|
|
53
|
-
TwoFactorMethod2["EMAIL"] = "email";
|
|
54
|
-
TwoFactorMethod2["BACKUP_CODE"] = "backup_code";
|
|
55
|
-
return TwoFactorMethod2;
|
|
56
|
-
})(TwoFactorMethod || {});
|
|
57
|
-
|
|
58
|
-
// src/types/storage.ts
|
|
59
|
-
var LocalStorageAdapter = class {
|
|
60
|
-
getItem(key) {
|
|
61
|
-
if (typeof window === "undefined") return null;
|
|
62
|
-
return window.localStorage.getItem(key);
|
|
63
|
-
}
|
|
64
|
-
setItem(key, value) {
|
|
65
|
-
if (typeof window === "undefined") return;
|
|
66
|
-
window.localStorage.setItem(key, value);
|
|
67
|
-
}
|
|
68
|
-
removeItem(key) {
|
|
69
|
-
if (typeof window === "undefined") return;
|
|
70
|
-
window.localStorage.removeItem(key);
|
|
71
|
-
}
|
|
72
|
-
clear() {
|
|
73
|
-
if (typeof window === "undefined") return;
|
|
74
|
-
window.localStorage.clear();
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
var SessionStorageAdapter = class {
|
|
78
|
-
getItem(key) {
|
|
79
|
-
if (typeof window === "undefined") return null;
|
|
80
|
-
return window.sessionStorage.getItem(key);
|
|
81
|
-
}
|
|
82
|
-
setItem(key, value) {
|
|
83
|
-
if (typeof window === "undefined") return;
|
|
84
|
-
window.sessionStorage.setItem(key, value);
|
|
85
|
-
}
|
|
86
|
-
removeItem(key) {
|
|
87
|
-
if (typeof window === "undefined") return;
|
|
88
|
-
window.sessionStorage.removeItem(key);
|
|
89
|
-
}
|
|
90
|
-
clear() {
|
|
91
|
-
if (typeof window === "undefined") return;
|
|
92
|
-
window.sessionStorage.clear();
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
var MemoryStorageAdapter = class {
|
|
96
|
-
constructor() {
|
|
97
|
-
this.store = /* @__PURE__ */ new Map();
|
|
98
|
-
}
|
|
99
|
-
getItem(key) {
|
|
100
|
-
return this.store.get(key) ?? null;
|
|
101
|
-
}
|
|
102
|
-
setItem(key, value) {
|
|
103
|
-
this.store.set(key, value);
|
|
104
|
-
}
|
|
105
|
-
removeItem(key) {
|
|
106
|
-
this.store.delete(key);
|
|
1
|
+
// src/generated/api-client.ts
|
|
2
|
+
var AuthClient = class {
|
|
3
|
+
baseURL;
|
|
4
|
+
fetchFn;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.baseURL = config.baseURL.replace(/\/+$/, "");
|
|
7
|
+
this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
|
|
8
|
+
}
|
|
9
|
+
// ──────────────────────────────────────────────────
|
|
10
|
+
// Generated methods
|
|
11
|
+
// ──────────────────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Get AuthSome manifest
|
|
14
|
+
* GET /.well-known/authsome/manifest
|
|
15
|
+
*/
|
|
16
|
+
async getManifest() {
|
|
17
|
+
const path = "/.well-known/authsome/manifest";
|
|
18
|
+
return this.request(
|
|
19
|
+
"GET",
|
|
20
|
+
path,
|
|
21
|
+
void 0
|
|
22
|
+
);
|
|
107
23
|
}
|
|
108
|
-
|
|
109
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Get OpenAPI specification
|
|
26
|
+
* GET /.well-known/authsome/openapi
|
|
27
|
+
*/
|
|
28
|
+
async getOpenAPI() {
|
|
29
|
+
const path = "/.well-known/authsome/openapi";
|
|
30
|
+
return this.request(
|
|
31
|
+
"GET",
|
|
32
|
+
path,
|
|
33
|
+
void 0
|
|
34
|
+
);
|
|
110
35
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.
|
|
36
|
+
/**
|
|
37
|
+
* Stop impersonation (admin)
|
|
38
|
+
* POST /v1/auth/admin/impersonate/stop
|
|
39
|
+
*/
|
|
40
|
+
async adminStopImpersonation(body, token) {
|
|
41
|
+
const path = "/v1/auth/admin/impersonate/stop";
|
|
42
|
+
return this.request(
|
|
43
|
+
"POST",
|
|
44
|
+
path,
|
|
45
|
+
body,
|
|
46
|
+
token
|
|
47
|
+
);
|
|
118
48
|
}
|
|
119
49
|
/**
|
|
120
|
-
*
|
|
50
|
+
* Impersonate user (admin)
|
|
51
|
+
* POST /v1/auth/admin/impersonate/{userId}
|
|
121
52
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
53
|
+
async adminImpersonate(userId, body, token) {
|
|
54
|
+
const path = `/v1/auth/admin/impersonate/${userId}`;
|
|
55
|
+
return this.request(
|
|
56
|
+
"POST",
|
|
57
|
+
path,
|
|
58
|
+
body,
|
|
59
|
+
token
|
|
60
|
+
);
|
|
124
61
|
}
|
|
125
62
|
/**
|
|
126
|
-
*
|
|
63
|
+
* List organizations (admin)
|
|
64
|
+
* GET /v1/auth/admin/orgs
|
|
127
65
|
*/
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
66
|
+
async adminListOrgs(token) {
|
|
67
|
+
const path = "/v1/auth/admin/orgs";
|
|
68
|
+
return this.request(
|
|
69
|
+
"GET",
|
|
70
|
+
path,
|
|
71
|
+
void 0,
|
|
72
|
+
token
|
|
73
|
+
);
|
|
133
74
|
}
|
|
134
75
|
/**
|
|
135
|
-
*
|
|
76
|
+
* Get stats (admin)
|
|
77
|
+
* GET /v1/auth/admin/stats
|
|
136
78
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
79
|
+
async adminGetStats(token) {
|
|
80
|
+
const path = "/v1/auth/admin/stats";
|
|
81
|
+
return this.request(
|
|
82
|
+
"GET",
|
|
83
|
+
path,
|
|
84
|
+
void 0,
|
|
85
|
+
token
|
|
86
|
+
);
|
|
139
87
|
}
|
|
140
88
|
/**
|
|
141
|
-
*
|
|
89
|
+
* List users (admin)
|
|
90
|
+
* GET /v1/auth/admin/users
|
|
142
91
|
*/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
92
|
+
async adminListUsers(token) {
|
|
93
|
+
const path = "/v1/auth/admin/users";
|
|
94
|
+
return this.request(
|
|
95
|
+
"GET",
|
|
96
|
+
path,
|
|
97
|
+
void 0,
|
|
98
|
+
token
|
|
99
|
+
);
|
|
149
100
|
}
|
|
150
101
|
/**
|
|
151
|
-
*
|
|
102
|
+
* Get user (admin)
|
|
103
|
+
* GET /v1/auth/admin/users/{userId}
|
|
152
104
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
105
|
+
async adminGetUser(userId, token) {
|
|
106
|
+
const path = `/v1/auth/admin/users/${userId}`;
|
|
107
|
+
return this.request(
|
|
108
|
+
"GET",
|
|
109
|
+
path,
|
|
110
|
+
void 0,
|
|
111
|
+
token
|
|
112
|
+
);
|
|
155
113
|
}
|
|
156
114
|
/**
|
|
157
|
-
*
|
|
115
|
+
* Delete user (admin)
|
|
116
|
+
* DELETE /v1/auth/admin/users/{userId}
|
|
158
117
|
*/
|
|
159
|
-
|
|
160
|
-
|
|
118
|
+
async adminDeleteUser(userId, body, token) {
|
|
119
|
+
const path = `/v1/auth/admin/users/${userId}`;
|
|
120
|
+
return this.request(
|
|
121
|
+
"DELETE",
|
|
122
|
+
path,
|
|
123
|
+
body,
|
|
124
|
+
token
|
|
125
|
+
);
|
|
161
126
|
}
|
|
162
127
|
/**
|
|
163
|
-
*
|
|
128
|
+
* Ban user (admin)
|
|
129
|
+
* POST /v1/auth/admin/users/{userId}/ban
|
|
164
130
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
131
|
+
async adminBanUser(userId, body, token) {
|
|
132
|
+
const path = `/v1/auth/admin/users/${userId}/ban`;
|
|
133
|
+
return this.request(
|
|
134
|
+
"POST",
|
|
135
|
+
path,
|
|
136
|
+
body,
|
|
137
|
+
token
|
|
138
|
+
);
|
|
167
139
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
if (error instanceof Error) {
|
|
182
|
-
return new AuthError(error.message, "unknown_error" /* UNKNOWN_ERROR */, {
|
|
183
|
-
details: {
|
|
184
|
-
originalError: error.name,
|
|
185
|
-
stack: error.stack
|
|
186
|
-
}
|
|
187
|
-
});
|
|
140
|
+
/**
|
|
141
|
+
* Unban user (admin)
|
|
142
|
+
* POST /v1/auth/admin/users/{userId}/unban
|
|
143
|
+
*/
|
|
144
|
+
async adminUnbanUser(userId, body, token) {
|
|
145
|
+
const path = `/v1/auth/admin/users/${userId}/unban`;
|
|
146
|
+
return this.request(
|
|
147
|
+
"POST",
|
|
148
|
+
path,
|
|
149
|
+
body,
|
|
150
|
+
token
|
|
151
|
+
);
|
|
188
152
|
}
|
|
189
|
-
|
|
190
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Change password
|
|
155
|
+
* POST /v1/auth/change-password
|
|
156
|
+
*/
|
|
157
|
+
async changePassword(body, token) {
|
|
158
|
+
const path = "/v1/auth/change-password";
|
|
159
|
+
return this.request(
|
|
160
|
+
"POST",
|
|
161
|
+
path,
|
|
162
|
+
body,
|
|
163
|
+
token
|
|
164
|
+
);
|
|
191
165
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
166
|
+
/**
|
|
167
|
+
* List devices
|
|
168
|
+
* GET /v1/auth/devices
|
|
169
|
+
*/
|
|
170
|
+
async listDevices(token) {
|
|
171
|
+
const path = "/v1/auth/devices";
|
|
172
|
+
return this.request(
|
|
173
|
+
"GET",
|
|
174
|
+
path,
|
|
175
|
+
void 0,
|
|
176
|
+
token
|
|
177
|
+
);
|
|
201
178
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Get device
|
|
181
|
+
* GET /v1/auth/devices/{deviceId}
|
|
182
|
+
*/
|
|
183
|
+
async getDevice(deviceId, token) {
|
|
184
|
+
const path = `/v1/auth/devices/${deviceId}`;
|
|
185
|
+
return this.request(
|
|
186
|
+
"GET",
|
|
187
|
+
path,
|
|
188
|
+
void 0,
|
|
189
|
+
token
|
|
190
|
+
);
|
|
207
191
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Delete device
|
|
194
|
+
* DELETE /v1/auth/devices/{deviceId}
|
|
195
|
+
*/
|
|
196
|
+
async deleteDevice(deviceId, body, token) {
|
|
197
|
+
const path = `/v1/auth/devices/${deviceId}`;
|
|
198
|
+
return this.request(
|
|
199
|
+
"DELETE",
|
|
200
|
+
path,
|
|
201
|
+
body,
|
|
202
|
+
token
|
|
203
|
+
);
|
|
213
204
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
optional: "optional"
|
|
227
|
-
},
|
|
228
|
-
auth: {
|
|
229
|
-
signIn: "Sign In",
|
|
230
|
-
signUp: "Sign Up",
|
|
231
|
-
signOut: "Sign Out",
|
|
232
|
-
email: "Email",
|
|
233
|
-
password: "Password",
|
|
234
|
-
confirmPassword: "Confirm Password",
|
|
235
|
-
username: "Username",
|
|
236
|
-
phone: "Phone",
|
|
237
|
-
rememberMe: "Remember me",
|
|
238
|
-
forgotPassword: "Forgot password?",
|
|
239
|
-
continueWith: "Continue with {provider}",
|
|
240
|
-
orContinueWith: "Or continue with"
|
|
241
|
-
},
|
|
242
|
-
oauth: {
|
|
243
|
-
google: "Google",
|
|
244
|
-
github: "GitHub",
|
|
245
|
-
microsoft: "Microsoft",
|
|
246
|
-
facebook: "Facebook",
|
|
247
|
-
apple: "Apple",
|
|
248
|
-
discord: "Discord",
|
|
249
|
-
twitter: "Twitter",
|
|
250
|
-
linkedin: "LinkedIn",
|
|
251
|
-
chooseProvider: "Choose Your Provider",
|
|
252
|
-
signInPreferred: "Sign in with your preferred account"
|
|
253
|
-
},
|
|
254
|
-
magicLink: {
|
|
255
|
-
sendLink: "Send magic link",
|
|
256
|
-
checkEmail: "Check your email",
|
|
257
|
-
linkSent: "Magic link sent! Check your email to continue.",
|
|
258
|
-
enterEmail: "Enter your email to receive a magic link"
|
|
259
|
-
},
|
|
260
|
-
phone: {
|
|
261
|
-
enterPhone: "Enter your phone number",
|
|
262
|
-
sendCode: "Send code",
|
|
263
|
-
enterCode: "Enter verification code",
|
|
264
|
-
verifyPhone: "Verify phone number",
|
|
265
|
-
codeLabel: "Verification code"
|
|
266
|
-
},
|
|
267
|
-
mfa: {
|
|
268
|
-
required: "Two-factor authentication required",
|
|
269
|
-
selectMethod: "Select verification method",
|
|
270
|
-
verify: "Verify",
|
|
271
|
-
enterCode: "Enter verification code",
|
|
272
|
-
sms: "SMS",
|
|
273
|
-
authenticator: "Authenticator app",
|
|
274
|
-
email: "Email"
|
|
275
|
-
},
|
|
276
|
-
passkey: {
|
|
277
|
-
signInWith: "Sign in with passkey",
|
|
278
|
-
register: "Register passkey",
|
|
279
|
-
usePasskey: "Use passkey"
|
|
280
|
-
},
|
|
281
|
-
signUp: {
|
|
282
|
-
title: "Create Account",
|
|
283
|
-
subtitle: "Get started with your account",
|
|
284
|
-
haveAccount: "Already have an account?",
|
|
285
|
-
signInLink: "Sign in",
|
|
286
|
-
agreeToTerms: "I agree to the {terms}",
|
|
287
|
-
terms: "terms and conditions"
|
|
288
|
-
},
|
|
289
|
-
signIn: {
|
|
290
|
-
title: "Sign In",
|
|
291
|
-
subtitle: "Enter your email to continue",
|
|
292
|
-
noAccount: "Don't have an account?",
|
|
293
|
-
signUpLink: "Sign up",
|
|
294
|
-
enterEmail: "Enter your email to continue"
|
|
295
|
-
},
|
|
296
|
-
validation: {
|
|
297
|
-
emailRequired: "Email is required",
|
|
298
|
-
emailInvalid: "Invalid email address",
|
|
299
|
-
passwordRequired: "Password is required",
|
|
300
|
-
passwordTooShort: "Password must be at least {min} characters",
|
|
301
|
-
passwordRequireUppercase: "Password must contain an uppercase letter",
|
|
302
|
-
passwordRequireLowercase: "Password must contain a lowercase letter",
|
|
303
|
-
passwordRequireNumber: "Password must contain a number",
|
|
304
|
-
passwordRequireSpecial: "Password must contain a special character",
|
|
305
|
-
passwordMismatch: "Passwords do not match",
|
|
306
|
-
usernameRequired: "Username is required",
|
|
307
|
-
usernameInvalid: "Username must be 3-30 characters and contain only letters, numbers, underscores, and hyphens",
|
|
308
|
-
phoneRequired: "Phone number is required",
|
|
309
|
-
phoneInvalid: "Invalid phone number",
|
|
310
|
-
codeRequired: "Verification code is required",
|
|
311
|
-
codeInvalid: "Invalid verification code",
|
|
312
|
-
fieldRequired: "{field} is required",
|
|
313
|
-
termsRequired: "You must agree to the terms and conditions"
|
|
314
|
-
},
|
|
315
|
-
errors: {
|
|
316
|
-
invalidCredentials: "Invalid email or password",
|
|
317
|
-
userNotFound: "User not found",
|
|
318
|
-
userExists: "User already exists",
|
|
319
|
-
invalidToken: "Invalid or expired token",
|
|
320
|
-
tokenExpired: "Token has expired",
|
|
321
|
-
networkError: "Network error. Please try again.",
|
|
322
|
-
mfaRequired: "Two-factor authentication required",
|
|
323
|
-
emailNotVerified: "Email not verified",
|
|
324
|
-
phoneNotVerified: "Phone number not verified",
|
|
325
|
-
rateLimitExceeded: "Too many attempts. Please try again later.",
|
|
326
|
-
unknownError: "An unknown error occurred",
|
|
327
|
-
generic: "Something went wrong. Please try again."
|
|
328
|
-
},
|
|
329
|
-
success: {
|
|
330
|
-
signedIn: "Successfully signed in",
|
|
331
|
-
signedUp: "Account created successfully",
|
|
332
|
-
signedOut: "Successfully signed out",
|
|
333
|
-
linkSent: "Link sent successfully",
|
|
334
|
-
codeSent: "Verification code sent",
|
|
335
|
-
verified: "Successfully verified",
|
|
336
|
-
welcome: "Welcome, {name}!"
|
|
337
|
-
},
|
|
338
|
-
placeholders: {
|
|
339
|
-
email: "john@example.com",
|
|
340
|
-
password: "Enter your password",
|
|
341
|
-
confirmPassword: "Confirm your password",
|
|
342
|
-
username: "johndoe",
|
|
343
|
-
phone: "+1234567890",
|
|
344
|
-
code: "123456",
|
|
345
|
-
fullName: "John Doe"
|
|
205
|
+
/**
|
|
206
|
+
* Trust device
|
|
207
|
+
* PATCH /v1/auth/devices/{deviceId}/trust
|
|
208
|
+
*/
|
|
209
|
+
async trustDevice(deviceId, body, token) {
|
|
210
|
+
const path = `/v1/auth/devices/${deviceId}/trust`;
|
|
211
|
+
return this.request(
|
|
212
|
+
"PATCH",
|
|
213
|
+
path,
|
|
214
|
+
body,
|
|
215
|
+
token
|
|
216
|
+
);
|
|
346
217
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
result[key] = source[key];
|
|
359
|
-
}
|
|
360
|
-
}
|
|
218
|
+
/**
|
|
219
|
+
* Forgot password
|
|
220
|
+
* POST /v1/auth/forgot-password
|
|
221
|
+
*/
|
|
222
|
+
async forgotPassword(body) {
|
|
223
|
+
const path = "/v1/auth/forgot-password";
|
|
224
|
+
return this.request(
|
|
225
|
+
"POST",
|
|
226
|
+
path,
|
|
227
|
+
body
|
|
228
|
+
);
|
|
361
229
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Health check
|
|
232
|
+
* GET /v1/auth/health
|
|
233
|
+
*/
|
|
234
|
+
async getHealth() {
|
|
235
|
+
const path = "/v1/auth/health";
|
|
236
|
+
return this.request(
|
|
237
|
+
"GET",
|
|
238
|
+
path,
|
|
239
|
+
void 0
|
|
240
|
+
);
|
|
367
241
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
function validateEmail(email, locale) {
|
|
381
|
-
const messages = locale?.validation || defaultLocale.validation;
|
|
382
|
-
if (!email) {
|
|
383
|
-
return { field: "email", message: messages.emailRequired };
|
|
384
|
-
}
|
|
385
|
-
if (!EMAIL_REGEX.test(email)) {
|
|
386
|
-
return { field: "email", message: messages.emailInvalid };
|
|
387
|
-
}
|
|
388
|
-
return null;
|
|
389
|
-
}
|
|
390
|
-
function validatePassword(password, options = {}) {
|
|
391
|
-
const {
|
|
392
|
-
minLength = 8,
|
|
393
|
-
requireUppercase = true,
|
|
394
|
-
requireLowercase = true,
|
|
395
|
-
requireNumber = true,
|
|
396
|
-
requireSpecial = false,
|
|
397
|
-
locale
|
|
398
|
-
} = options;
|
|
399
|
-
const messages = locale?.validation || defaultLocale.validation;
|
|
400
|
-
if (!password) {
|
|
401
|
-
return { field: "password", message: messages.passwordRequired };
|
|
402
|
-
}
|
|
403
|
-
if (password.length < minLength) {
|
|
404
|
-
return {
|
|
405
|
-
field: "password",
|
|
406
|
-
message: interpolate(messages.passwordTooShort, { min: minLength.toString() })
|
|
407
|
-
};
|
|
242
|
+
/**
|
|
243
|
+
* List API keys
|
|
244
|
+
* GET /v1/auth/keys
|
|
245
|
+
*/
|
|
246
|
+
async listAPIKeys(token) {
|
|
247
|
+
const path = "/v1/auth/keys";
|
|
248
|
+
return this.request(
|
|
249
|
+
"GET",
|
|
250
|
+
path,
|
|
251
|
+
void 0,
|
|
252
|
+
token
|
|
253
|
+
);
|
|
408
254
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Create API key
|
|
257
|
+
* POST /v1/auth/keys
|
|
258
|
+
*/
|
|
259
|
+
async createAPIKey(body, token) {
|
|
260
|
+
const path = "/v1/auth/keys";
|
|
261
|
+
return this.request(
|
|
262
|
+
"POST",
|
|
263
|
+
path,
|
|
264
|
+
body,
|
|
265
|
+
token
|
|
266
|
+
);
|
|
414
267
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Revoke API key
|
|
270
|
+
* DELETE /v1/auth/keys/{keyId}
|
|
271
|
+
*/
|
|
272
|
+
async revokeAPIKey(keyId, body, token) {
|
|
273
|
+
const path = `/v1/auth/keys/${keyId}`;
|
|
274
|
+
return this.request(
|
|
275
|
+
"DELETE",
|
|
276
|
+
path,
|
|
277
|
+
body,
|
|
278
|
+
token
|
|
279
|
+
);
|
|
420
280
|
}
|
|
421
|
-
|
|
422
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Send magic link
|
|
283
|
+
* POST /v1/auth/magic-link/send
|
|
284
|
+
*/
|
|
285
|
+
async sendMagicLink(body) {
|
|
286
|
+
const path = "/v1/auth/magic-link/send";
|
|
287
|
+
return this.request(
|
|
288
|
+
"POST",
|
|
289
|
+
path,
|
|
290
|
+
body
|
|
291
|
+
);
|
|
423
292
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Verify magic link
|
|
295
|
+
* POST /v1/auth/magic-link/verify
|
|
296
|
+
*/
|
|
297
|
+
async verifyMagicLink(body) {
|
|
298
|
+
const path = "/v1/auth/magic-link/verify";
|
|
299
|
+
return this.request(
|
|
300
|
+
"POST",
|
|
301
|
+
path,
|
|
302
|
+
body
|
|
303
|
+
);
|
|
429
304
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Get current user
|
|
307
|
+
* GET /v1/auth/me
|
|
308
|
+
*/
|
|
309
|
+
async getMe(token) {
|
|
310
|
+
const path = "/v1/auth/me";
|
|
311
|
+
return this.request(
|
|
312
|
+
"GET",
|
|
313
|
+
path,
|
|
314
|
+
void 0,
|
|
315
|
+
token
|
|
316
|
+
);
|
|
442
317
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Update current user
|
|
320
|
+
* PATCH /v1/auth/me
|
|
321
|
+
*/
|
|
322
|
+
async updateMe(body, token) {
|
|
323
|
+
const path = "/v1/auth/me";
|
|
324
|
+
return this.request(
|
|
325
|
+
"PATCH",
|
|
326
|
+
path,
|
|
327
|
+
body,
|
|
328
|
+
token
|
|
329
|
+
);
|
|
455
330
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Delete account
|
|
333
|
+
* DELETE /v1/auth/me
|
|
334
|
+
*/
|
|
335
|
+
async deleteMe(body, token) {
|
|
336
|
+
const path = "/v1/auth/me";
|
|
337
|
+
return this.request(
|
|
338
|
+
"DELETE",
|
|
339
|
+
path,
|
|
340
|
+
body,
|
|
341
|
+
token
|
|
342
|
+
);
|
|
462
343
|
}
|
|
463
|
-
|
|
464
|
-
|
|
344
|
+
/**
|
|
345
|
+
* Export user data
|
|
346
|
+
* GET /v1/auth/me/export
|
|
347
|
+
*/
|
|
348
|
+
async exportMyData(token) {
|
|
349
|
+
const path = "/v1/auth/me/export";
|
|
350
|
+
return this.request(
|
|
351
|
+
"GET",
|
|
352
|
+
path,
|
|
353
|
+
void 0,
|
|
354
|
+
token
|
|
355
|
+
);
|
|
465
356
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
357
|
+
/**
|
|
358
|
+
* MFA challenge
|
|
359
|
+
* POST /v1/auth/mfa/challenge
|
|
360
|
+
*/
|
|
361
|
+
async challengeMFA(body) {
|
|
362
|
+
const path = "/v1/auth/mfa/challenge";
|
|
363
|
+
return this.request(
|
|
364
|
+
"POST",
|
|
365
|
+
path,
|
|
366
|
+
body
|
|
367
|
+
);
|
|
475
368
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
369
|
+
/**
|
|
370
|
+
* Enroll in MFA
|
|
371
|
+
* POST /v1/auth/mfa/enroll
|
|
372
|
+
*/
|
|
373
|
+
async enrollMFA(body, token) {
|
|
374
|
+
const path = "/v1/auth/mfa/enroll";
|
|
375
|
+
return this.request(
|
|
376
|
+
"POST",
|
|
377
|
+
path,
|
|
378
|
+
body,
|
|
379
|
+
token
|
|
380
|
+
);
|
|
485
381
|
}
|
|
486
382
|
/**
|
|
487
|
-
*
|
|
383
|
+
* Disable MFA
|
|
384
|
+
* DELETE /v1/auth/mfa/enrollment
|
|
488
385
|
*/
|
|
489
|
-
async
|
|
490
|
-
|
|
386
|
+
async disableMFA(body, token) {
|
|
387
|
+
const path = "/v1/auth/mfa/enrollment";
|
|
388
|
+
return this.request(
|
|
389
|
+
"DELETE",
|
|
390
|
+
path,
|
|
391
|
+
body,
|
|
392
|
+
token
|
|
393
|
+
);
|
|
491
394
|
}
|
|
492
395
|
/**
|
|
493
|
-
*
|
|
396
|
+
* Regenerate MFA recovery codes
|
|
397
|
+
* POST /v1/auth/mfa/recovery/regenerate
|
|
494
398
|
*/
|
|
495
|
-
async
|
|
496
|
-
|
|
399
|
+
async regenerateMFARecoveryCodes(body, token) {
|
|
400
|
+
const path = "/v1/auth/mfa/recovery/regenerate";
|
|
401
|
+
return this.request(
|
|
402
|
+
"POST",
|
|
403
|
+
path,
|
|
404
|
+
body,
|
|
405
|
+
token
|
|
406
|
+
);
|
|
497
407
|
}
|
|
498
408
|
/**
|
|
499
|
-
*
|
|
409
|
+
* Verify MFA recovery code
|
|
410
|
+
* POST /v1/auth/mfa/recovery/verify
|
|
500
411
|
*/
|
|
501
|
-
async
|
|
502
|
-
|
|
412
|
+
async verifyRecoveryCode(body) {
|
|
413
|
+
const path = "/v1/auth/mfa/recovery/verify";
|
|
414
|
+
return this.request(
|
|
415
|
+
"POST",
|
|
416
|
+
path,
|
|
417
|
+
body
|
|
418
|
+
);
|
|
503
419
|
}
|
|
504
420
|
/**
|
|
505
|
-
*
|
|
421
|
+
* Send SMS verification code
|
|
422
|
+
* POST /v1/auth/mfa/sms/send
|
|
506
423
|
*/
|
|
507
|
-
async
|
|
508
|
-
|
|
424
|
+
async sendSMSCode(body, token) {
|
|
425
|
+
const path = "/v1/auth/mfa/sms/send";
|
|
426
|
+
return this.request(
|
|
427
|
+
"POST",
|
|
428
|
+
path,
|
|
429
|
+
body,
|
|
430
|
+
token
|
|
431
|
+
);
|
|
509
432
|
}
|
|
510
433
|
/**
|
|
511
|
-
*
|
|
434
|
+
* Verify SMS code
|
|
435
|
+
* POST /v1/auth/mfa/sms/verify
|
|
512
436
|
*/
|
|
513
|
-
async
|
|
514
|
-
|
|
437
|
+
async verifySMSCode(body, token) {
|
|
438
|
+
const path = "/v1/auth/mfa/sms/verify";
|
|
439
|
+
return this.request(
|
|
440
|
+
"POST",
|
|
441
|
+
path,
|
|
442
|
+
body,
|
|
443
|
+
token
|
|
444
|
+
);
|
|
515
445
|
}
|
|
516
446
|
/**
|
|
517
|
-
*
|
|
447
|
+
* Verify MFA code
|
|
448
|
+
* POST /v1/auth/mfa/verify
|
|
518
449
|
*/
|
|
519
|
-
async
|
|
520
|
-
|
|
450
|
+
async verifyMFA(body) {
|
|
451
|
+
const path = "/v1/auth/mfa/verify";
|
|
452
|
+
return this.request(
|
|
453
|
+
"POST",
|
|
454
|
+
path,
|
|
455
|
+
body
|
|
456
|
+
);
|
|
521
457
|
}
|
|
522
458
|
/**
|
|
523
|
-
*
|
|
459
|
+
* List organizations
|
|
460
|
+
* GET /v1/auth/orgs
|
|
524
461
|
*/
|
|
525
|
-
async
|
|
526
|
-
|
|
527
|
-
|
|
462
|
+
async listOrganizations(token) {
|
|
463
|
+
const path = "/v1/auth/orgs";
|
|
464
|
+
return this.request(
|
|
465
|
+
"GET",
|
|
466
|
+
path,
|
|
467
|
+
void 0,
|
|
468
|
+
token
|
|
469
|
+
);
|
|
528
470
|
}
|
|
529
471
|
/**
|
|
530
|
-
*
|
|
472
|
+
* Create organization
|
|
473
|
+
* POST /v1/auth/orgs
|
|
531
474
|
*/
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
return true;
|
|
541
|
-
}
|
|
475
|
+
async createOrganization(body, token) {
|
|
476
|
+
const path = "/v1/auth/orgs";
|
|
477
|
+
return this.request(
|
|
478
|
+
"POST",
|
|
479
|
+
path,
|
|
480
|
+
body,
|
|
481
|
+
token
|
|
482
|
+
);
|
|
542
483
|
}
|
|
543
484
|
/**
|
|
544
|
-
*
|
|
485
|
+
* Check slug availability
|
|
486
|
+
* GET /v1/auth/orgs/check-slug
|
|
545
487
|
*/
|
|
546
|
-
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
488
|
+
async checkOrgSlug(token) {
|
|
489
|
+
const path = "/v1/auth/orgs/check-slug";
|
|
490
|
+
return this.request(
|
|
491
|
+
"GET",
|
|
492
|
+
path,
|
|
493
|
+
void 0,
|
|
494
|
+
token
|
|
495
|
+
);
|
|
554
496
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
for (let i = 1; i < parts.length; i++) {
|
|
568
|
-
const part = parts[i];
|
|
569
|
-
const lowerPart = part.toLowerCase();
|
|
570
|
-
if (lowerPart === "httponly") {
|
|
571
|
-
options.httpOnly = true;
|
|
572
|
-
} else if (lowerPart === "secure") {
|
|
573
|
-
options.secure = true;
|
|
574
|
-
} else if (lowerPart.startsWith("path=")) {
|
|
575
|
-
options.path = part.substring(5);
|
|
576
|
-
} else if (lowerPart.startsWith("domain=")) {
|
|
577
|
-
options.domain = part.substring(7);
|
|
578
|
-
} else if (lowerPart.startsWith("max-age=")) {
|
|
579
|
-
const maxAge = parseInt(part.substring(8), 10);
|
|
580
|
-
if (!isNaN(maxAge)) {
|
|
581
|
-
options.maxAge = maxAge;
|
|
582
|
-
}
|
|
583
|
-
} else if (lowerPart.startsWith("expires=")) {
|
|
584
|
-
const expiresStr = part.substring(8);
|
|
585
|
-
const expiresDate = new Date(expiresStr);
|
|
586
|
-
if (!isNaN(expiresDate.getTime())) {
|
|
587
|
-
options.expires = expiresDate;
|
|
588
|
-
}
|
|
589
|
-
} else if (lowerPart.startsWith("samesite=")) {
|
|
590
|
-
const sameSiteValue = lowerPart.substring(9);
|
|
591
|
-
if (sameSiteValue === "strict" || sameSiteValue === "lax" || sameSiteValue === "none") {
|
|
592
|
-
options.sameSite = sameSiteValue;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
497
|
+
/**
|
|
498
|
+
* Accept invitation
|
|
499
|
+
* POST /v1/auth/orgs/invitations/accept
|
|
500
|
+
*/
|
|
501
|
+
async acceptInvitation(body, token) {
|
|
502
|
+
const path = "/v1/auth/orgs/invitations/accept";
|
|
503
|
+
return this.request(
|
|
504
|
+
"POST",
|
|
505
|
+
path,
|
|
506
|
+
body,
|
|
507
|
+
token
|
|
508
|
+
);
|
|
595
509
|
}
|
|
596
|
-
|
|
597
|
-
|
|
510
|
+
/**
|
|
511
|
+
* Decline invitation
|
|
512
|
+
* POST /v1/auth/orgs/invitations/decline
|
|
513
|
+
*/
|
|
514
|
+
async declineInvitation(body, token) {
|
|
515
|
+
const path = "/v1/auth/orgs/invitations/decline";
|
|
516
|
+
return this.request(
|
|
517
|
+
"POST",
|
|
518
|
+
path,
|
|
519
|
+
body,
|
|
520
|
+
token
|
|
521
|
+
);
|
|
598
522
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
523
|
+
/**
|
|
524
|
+
* Get organization
|
|
525
|
+
* GET /v1/auth/orgs/{orgId}
|
|
526
|
+
*/
|
|
527
|
+
async getOrganization(orgId, token) {
|
|
528
|
+
const path = `/v1/auth/orgs/${orgId}`;
|
|
529
|
+
return this.request(
|
|
530
|
+
"GET",
|
|
531
|
+
path,
|
|
532
|
+
void 0,
|
|
533
|
+
token
|
|
534
|
+
);
|
|
609
535
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (opts.expires) {
|
|
623
|
-
parts.push(`Expires=${opts.expires.toUTCString()}`);
|
|
624
|
-
}
|
|
625
|
-
if (opts.maxAge !== void 0) {
|
|
626
|
-
parts.push(`Max-Age=${opts.maxAge}`);
|
|
627
|
-
}
|
|
628
|
-
if (opts.httpOnly) {
|
|
629
|
-
parts.push("HttpOnly");
|
|
630
|
-
}
|
|
631
|
-
if (opts.secure) {
|
|
632
|
-
parts.push("Secure");
|
|
633
|
-
}
|
|
634
|
-
if (opts.sameSite) {
|
|
635
|
-
const sameSite = opts.sameSite.charAt(0).toUpperCase() + opts.sameSite.slice(1);
|
|
636
|
-
parts.push(`SameSite=${sameSite}`);
|
|
637
|
-
}
|
|
536
|
+
/**
|
|
537
|
+
* Update organization
|
|
538
|
+
* PATCH /v1/auth/orgs/{orgId}
|
|
539
|
+
*/
|
|
540
|
+
async updateOrganization(orgId, body, token) {
|
|
541
|
+
const path = `/v1/auth/orgs/${orgId}`;
|
|
542
|
+
return this.request(
|
|
543
|
+
"PATCH",
|
|
544
|
+
path,
|
|
545
|
+
body,
|
|
546
|
+
token
|
|
547
|
+
);
|
|
638
548
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
549
|
+
/**
|
|
550
|
+
* Delete organization
|
|
551
|
+
* DELETE /v1/auth/orgs/{orgId}
|
|
552
|
+
*/
|
|
553
|
+
async deleteOrganization(orgId, body, token) {
|
|
554
|
+
const path = `/v1/auth/orgs/${orgId}`;
|
|
555
|
+
return this.request(
|
|
556
|
+
"DELETE",
|
|
557
|
+
path,
|
|
558
|
+
body,
|
|
559
|
+
token
|
|
560
|
+
);
|
|
650
561
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
562
|
+
/**
|
|
563
|
+
* List invitations
|
|
564
|
+
* GET /v1/auth/orgs/{orgId}/invitations
|
|
565
|
+
*/
|
|
566
|
+
async listInvitations(orgId, token) {
|
|
567
|
+
const path = `/v1/auth/orgs/${orgId}/invitations`;
|
|
568
|
+
return this.request(
|
|
569
|
+
"GET",
|
|
570
|
+
path,
|
|
571
|
+
void 0,
|
|
572
|
+
token
|
|
573
|
+
);
|
|
662
574
|
}
|
|
663
575
|
/**
|
|
664
|
-
*
|
|
576
|
+
* Create invitation
|
|
577
|
+
* POST /v1/auth/orgs/{orgId}/invitations
|
|
665
578
|
*/
|
|
666
|
-
async
|
|
667
|
-
|
|
668
|
-
this.
|
|
579
|
+
async createInvitation(orgId, body, token) {
|
|
580
|
+
const path = `/v1/auth/orgs/${orgId}/invitations`;
|
|
581
|
+
return this.request(
|
|
582
|
+
"POST",
|
|
583
|
+
path,
|
|
584
|
+
body,
|
|
585
|
+
token
|
|
586
|
+
);
|
|
669
587
|
}
|
|
670
588
|
/**
|
|
671
|
-
*
|
|
589
|
+
* List members
|
|
590
|
+
* GET /v1/auth/orgs/{orgId}/members
|
|
672
591
|
*/
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
592
|
+
async listMembers(orgId, token) {
|
|
593
|
+
const path = `/v1/auth/orgs/${orgId}/members`;
|
|
594
|
+
return this.request(
|
|
595
|
+
"GET",
|
|
596
|
+
path,
|
|
597
|
+
void 0,
|
|
598
|
+
token
|
|
599
|
+
);
|
|
677
600
|
}
|
|
678
601
|
/**
|
|
679
|
-
*
|
|
602
|
+
* Add member
|
|
603
|
+
* POST /v1/auth/orgs/{orgId}/members
|
|
680
604
|
*/
|
|
681
|
-
async
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
if (!response.ok) {
|
|
690
|
-
const error = await response.json().catch(() => ({
|
|
691
|
-
message: response.statusText
|
|
692
|
-
}));
|
|
693
|
-
throw error;
|
|
694
|
-
}
|
|
695
|
-
return response.json();
|
|
605
|
+
async addMember(orgId, body, token) {
|
|
606
|
+
const path = `/v1/auth/orgs/${orgId}/members`;
|
|
607
|
+
return this.request(
|
|
608
|
+
"POST",
|
|
609
|
+
path,
|
|
610
|
+
body,
|
|
611
|
+
token
|
|
612
|
+
);
|
|
696
613
|
}
|
|
697
614
|
/**
|
|
698
|
-
*
|
|
615
|
+
* Update member role
|
|
616
|
+
* PATCH /v1/auth/orgs/{orgId}/members/{memberId}
|
|
699
617
|
*/
|
|
700
|
-
|
|
701
|
-
|
|
618
|
+
async updateMember(orgId, memberId, body, token) {
|
|
619
|
+
const path = `/v1/auth/orgs/${orgId}/members/${memberId}`;
|
|
620
|
+
return this.request(
|
|
621
|
+
"PATCH",
|
|
622
|
+
path,
|
|
623
|
+
body,
|
|
624
|
+
token
|
|
625
|
+
);
|
|
702
626
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
return this.
|
|
627
|
+
/**
|
|
628
|
+
* Remove member
|
|
629
|
+
* DELETE /v1/auth/orgs/{orgId}/members/{memberId}
|
|
630
|
+
*/
|
|
631
|
+
async removeMember(orgId, memberId, body, token) {
|
|
632
|
+
const path = `/v1/auth/orgs/${orgId}/members/${memberId}`;
|
|
633
|
+
return this.request(
|
|
634
|
+
"DELETE",
|
|
635
|
+
path,
|
|
636
|
+
body,
|
|
637
|
+
token
|
|
638
|
+
);
|
|
710
639
|
}
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
640
|
+
/**
|
|
641
|
+
* List teams
|
|
642
|
+
* GET /v1/auth/orgs/{orgId}/teams
|
|
643
|
+
*/
|
|
644
|
+
async listTeams(orgId, token) {
|
|
645
|
+
const path = `/v1/auth/orgs/${orgId}/teams`;
|
|
646
|
+
return this.request(
|
|
647
|
+
"GET",
|
|
648
|
+
path,
|
|
649
|
+
void 0,
|
|
650
|
+
token
|
|
651
|
+
);
|
|
723
652
|
}
|
|
724
653
|
/**
|
|
725
|
-
*
|
|
654
|
+
* Create team
|
|
655
|
+
* POST /v1/auth/orgs/{orgId}/teams
|
|
726
656
|
*/
|
|
727
|
-
async
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
session,
|
|
736
|
-
error: null,
|
|
737
|
-
isAuthenticated: true,
|
|
738
|
-
isLoading: false
|
|
739
|
-
});
|
|
740
|
-
if (this.autoRefresh) {
|
|
741
|
-
this.startAutoRefresh();
|
|
742
|
-
}
|
|
743
|
-
} else {
|
|
744
|
-
this.updateState({
|
|
745
|
-
state: "unauthenticated" /* UNAUTHENTICATED */,
|
|
746
|
-
user: null,
|
|
747
|
-
session: null,
|
|
748
|
-
error: null,
|
|
749
|
-
isAuthenticated: false,
|
|
750
|
-
isLoading: false
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
} catch (error) {
|
|
754
|
-
this.handleError(error);
|
|
755
|
-
}
|
|
657
|
+
async createTeam(orgId, body, token) {
|
|
658
|
+
const path = `/v1/auth/orgs/${orgId}/teams`;
|
|
659
|
+
return this.request(
|
|
660
|
+
"POST",
|
|
661
|
+
path,
|
|
662
|
+
body,
|
|
663
|
+
token
|
|
664
|
+
);
|
|
756
665
|
}
|
|
757
666
|
/**
|
|
758
|
-
*
|
|
667
|
+
* Get team
|
|
668
|
+
* GET /v1/auth/orgs/{orgId}/teams/{teamId}
|
|
759
669
|
*/
|
|
760
|
-
async
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
session: null,
|
|
769
|
-
error: null,
|
|
770
|
-
isAuthenticated: false,
|
|
771
|
-
isLoading: false
|
|
772
|
-
});
|
|
773
|
-
return;
|
|
774
|
-
}
|
|
775
|
-
this.updateState({
|
|
776
|
-
state: "authenticated" /* AUTHENTICATED */,
|
|
777
|
-
user: response.user,
|
|
778
|
-
session: response.session,
|
|
779
|
-
error: null,
|
|
780
|
-
isAuthenticated: true,
|
|
781
|
-
isLoading: false
|
|
782
|
-
});
|
|
783
|
-
if (this.autoRefresh) {
|
|
784
|
-
this.startAutoRefresh();
|
|
785
|
-
}
|
|
786
|
-
} catch (error) {
|
|
787
|
-
this.handleError(error);
|
|
788
|
-
}
|
|
670
|
+
async getTeam(orgId, teamId, token) {
|
|
671
|
+
const path = `/v1/auth/orgs/${orgId}/teams/${teamId}`;
|
|
672
|
+
return this.request(
|
|
673
|
+
"GET",
|
|
674
|
+
path,
|
|
675
|
+
void 0,
|
|
676
|
+
token
|
|
677
|
+
);
|
|
789
678
|
}
|
|
790
679
|
/**
|
|
791
|
-
*
|
|
680
|
+
* Update team
|
|
681
|
+
* PATCH /v1/auth/orgs/{orgId}/teams/{teamId}
|
|
792
682
|
*/
|
|
793
|
-
async
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
error: null,
|
|
802
|
-
isAuthenticated: true,
|
|
803
|
-
isLoading: false
|
|
804
|
-
});
|
|
805
|
-
if (this.autoRefresh) {
|
|
806
|
-
this.startAutoRefresh();
|
|
807
|
-
}
|
|
808
|
-
} catch (error) {
|
|
809
|
-
this.handleError(error);
|
|
810
|
-
}
|
|
683
|
+
async updateTeam(orgId, teamId, body, token) {
|
|
684
|
+
const path = `/v1/auth/orgs/${orgId}/teams/${teamId}`;
|
|
685
|
+
return this.request(
|
|
686
|
+
"PATCH",
|
|
687
|
+
path,
|
|
688
|
+
body,
|
|
689
|
+
token
|
|
690
|
+
);
|
|
811
691
|
}
|
|
812
692
|
/**
|
|
813
|
-
*
|
|
693
|
+
* Delete team
|
|
694
|
+
* DELETE /v1/auth/orgs/{orgId}/teams/{teamId}
|
|
814
695
|
*/
|
|
815
|
-
async
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
error: null,
|
|
824
|
-
isAuthenticated: false,
|
|
825
|
-
isLoading: false
|
|
826
|
-
});
|
|
827
|
-
} catch (error) {
|
|
828
|
-
this.handleError(error);
|
|
829
|
-
}
|
|
696
|
+
async deleteTeam(orgId, teamId, body, token) {
|
|
697
|
+
const path = `/v1/auth/orgs/${orgId}/teams/${teamId}`;
|
|
698
|
+
return this.request(
|
|
699
|
+
"DELETE",
|
|
700
|
+
path,
|
|
701
|
+
body,
|
|
702
|
+
token
|
|
703
|
+
);
|
|
830
704
|
}
|
|
831
705
|
/**
|
|
832
|
-
*
|
|
706
|
+
* List passkeys
|
|
707
|
+
* GET /v1/auth/passkeys/
|
|
708
|
+
*/
|
|
709
|
+
async listPasskeys(token) {
|
|
710
|
+
const path = "/v1/auth/passkeys/";
|
|
711
|
+
return this.request(
|
|
712
|
+
"GET",
|
|
713
|
+
path,
|
|
714
|
+
void 0,
|
|
715
|
+
token
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Begin passkey login
|
|
720
|
+
* POST /v1/auth/passkeys/login/begin
|
|
833
721
|
*/
|
|
834
|
-
async
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
});
|
|
842
|
-
} catch (error) {
|
|
843
|
-
this.handleError(error);
|
|
844
|
-
}
|
|
722
|
+
async passkeyLoginBegin(body) {
|
|
723
|
+
const path = "/v1/auth/passkeys/login/begin";
|
|
724
|
+
return this.request(
|
|
725
|
+
"POST",
|
|
726
|
+
path,
|
|
727
|
+
body
|
|
728
|
+
);
|
|
845
729
|
}
|
|
846
730
|
/**
|
|
847
|
-
*
|
|
731
|
+
* Complete passkey login
|
|
732
|
+
* POST /v1/auth/passkeys/login/finish
|
|
848
733
|
*/
|
|
849
|
-
async
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
734
|
+
async passkeyLoginFinish(body) {
|
|
735
|
+
const path = "/v1/auth/passkeys/login/finish";
|
|
736
|
+
return this.request(
|
|
737
|
+
"POST",
|
|
738
|
+
path,
|
|
739
|
+
body
|
|
740
|
+
);
|
|
855
741
|
}
|
|
856
742
|
/**
|
|
857
|
-
*
|
|
743
|
+
* Begin passkey registration
|
|
744
|
+
* POST /v1/auth/passkeys/register/begin
|
|
858
745
|
*/
|
|
859
|
-
async
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
746
|
+
async passkeyRegisterBegin(body, token) {
|
|
747
|
+
const path = "/v1/auth/passkeys/register/begin";
|
|
748
|
+
return this.request(
|
|
749
|
+
"POST",
|
|
750
|
+
path,
|
|
751
|
+
body,
|
|
752
|
+
token
|
|
753
|
+
);
|
|
865
754
|
}
|
|
866
755
|
/**
|
|
867
|
-
*
|
|
756
|
+
* Complete passkey registration
|
|
757
|
+
* POST /v1/auth/passkeys/register/finish
|
|
868
758
|
*/
|
|
869
|
-
async
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
759
|
+
async passkeyRegisterFinish(body, token) {
|
|
760
|
+
const path = "/v1/auth/passkeys/register/finish";
|
|
761
|
+
return this.request(
|
|
762
|
+
"POST",
|
|
763
|
+
path,
|
|
764
|
+
body,
|
|
765
|
+
token
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Delete passkey
|
|
770
|
+
* DELETE /v1/auth/passkeys/{credentialId}
|
|
771
|
+
*/
|
|
772
|
+
async deletePasskey(credentialId, body, token) {
|
|
773
|
+
const path = `/v1/auth/passkeys/${credentialId}`;
|
|
774
|
+
return this.request(
|
|
775
|
+
"DELETE",
|
|
776
|
+
path,
|
|
777
|
+
body,
|
|
778
|
+
token
|
|
779
|
+
);
|
|
875
780
|
}
|
|
876
781
|
/**
|
|
877
|
-
*
|
|
782
|
+
* Refresh tokens
|
|
783
|
+
* POST /v1/auth/refresh
|
|
878
784
|
*/
|
|
879
|
-
async
|
|
880
|
-
|
|
785
|
+
async refresh(body) {
|
|
786
|
+
const path = "/v1/auth/refresh";
|
|
787
|
+
return this.request(
|
|
788
|
+
"POST",
|
|
789
|
+
path,
|
|
790
|
+
body
|
|
791
|
+
);
|
|
881
792
|
}
|
|
882
793
|
/**
|
|
883
|
-
*
|
|
794
|
+
* Reset password
|
|
795
|
+
* POST /v1/auth/reset-password
|
|
884
796
|
*/
|
|
885
|
-
async
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
session: response.session,
|
|
893
|
-
error: null,
|
|
894
|
-
isAuthenticated: true,
|
|
895
|
-
isLoading: false
|
|
896
|
-
});
|
|
897
|
-
if (this.autoRefresh) {
|
|
898
|
-
this.startAutoRefresh();
|
|
899
|
-
}
|
|
900
|
-
} catch (error) {
|
|
901
|
-
this.handleError(error);
|
|
902
|
-
}
|
|
797
|
+
async resetPassword(body) {
|
|
798
|
+
const path = "/v1/auth/reset-password";
|
|
799
|
+
return this.request(
|
|
800
|
+
"POST",
|
|
801
|
+
path,
|
|
802
|
+
body
|
|
803
|
+
);
|
|
903
804
|
}
|
|
904
805
|
/**
|
|
905
|
-
*
|
|
806
|
+
* List roles
|
|
807
|
+
* GET /v1/auth/roles
|
|
906
808
|
*/
|
|
907
|
-
async
|
|
908
|
-
|
|
809
|
+
async listRoles(token) {
|
|
810
|
+
const path = "/v1/auth/roles";
|
|
811
|
+
return this.request(
|
|
812
|
+
"GET",
|
|
813
|
+
path,
|
|
814
|
+
void 0,
|
|
815
|
+
token
|
|
816
|
+
);
|
|
909
817
|
}
|
|
910
818
|
/**
|
|
911
|
-
*
|
|
819
|
+
* Create role
|
|
820
|
+
* POST /v1/auth/roles
|
|
912
821
|
*/
|
|
913
|
-
async
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
822
|
+
async createRole(body, token) {
|
|
823
|
+
const path = "/v1/auth/roles";
|
|
824
|
+
return this.request(
|
|
825
|
+
"POST",
|
|
826
|
+
path,
|
|
827
|
+
body,
|
|
828
|
+
token
|
|
829
|
+
);
|
|
919
830
|
}
|
|
920
831
|
/**
|
|
921
|
-
*
|
|
832
|
+
* Get role
|
|
833
|
+
* GET /v1/auth/roles/{roleId}
|
|
922
834
|
*/
|
|
923
|
-
async
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
error: null,
|
|
932
|
-
isAuthenticated: true,
|
|
933
|
-
isLoading: false
|
|
934
|
-
});
|
|
935
|
-
if (this.autoRefresh) {
|
|
936
|
-
this.startAutoRefresh();
|
|
937
|
-
}
|
|
938
|
-
} catch (error) {
|
|
939
|
-
this.handleError(error);
|
|
940
|
-
}
|
|
835
|
+
async getRole(roleId, token) {
|
|
836
|
+
const path = `/v1/auth/roles/${roleId}`;
|
|
837
|
+
return this.request(
|
|
838
|
+
"GET",
|
|
839
|
+
path,
|
|
840
|
+
void 0,
|
|
841
|
+
token
|
|
842
|
+
);
|
|
941
843
|
}
|
|
942
844
|
/**
|
|
943
|
-
*
|
|
845
|
+
* Update role
|
|
846
|
+
* PATCH /v1/auth/roles/{roleId}
|
|
944
847
|
*/
|
|
945
|
-
async
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
848
|
+
async updateRole(roleId, body, token) {
|
|
849
|
+
const path = `/v1/auth/roles/${roleId}`;
|
|
850
|
+
return this.request(
|
|
851
|
+
"PATCH",
|
|
852
|
+
path,
|
|
853
|
+
body,
|
|
854
|
+
token
|
|
855
|
+
);
|
|
951
856
|
}
|
|
952
857
|
/**
|
|
953
|
-
*
|
|
858
|
+
* Delete role
|
|
859
|
+
* DELETE /v1/auth/roles/{roleId}
|
|
954
860
|
*/
|
|
955
|
-
async
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
error: null,
|
|
964
|
-
isAuthenticated: true,
|
|
965
|
-
isLoading: false
|
|
966
|
-
});
|
|
967
|
-
if (this.autoRefresh) {
|
|
968
|
-
this.startAutoRefresh();
|
|
969
|
-
}
|
|
970
|
-
} catch (error) {
|
|
971
|
-
this.handleError(error);
|
|
972
|
-
}
|
|
861
|
+
async deleteRole(roleId, body, token) {
|
|
862
|
+
const path = `/v1/auth/roles/${roleId}`;
|
|
863
|
+
return this.request(
|
|
864
|
+
"DELETE",
|
|
865
|
+
path,
|
|
866
|
+
body,
|
|
867
|
+
token
|
|
868
|
+
);
|
|
973
869
|
}
|
|
974
870
|
/**
|
|
975
|
-
*
|
|
871
|
+
* Assign role to user
|
|
872
|
+
* POST /v1/auth/roles/{roleId}/assign
|
|
976
873
|
*/
|
|
977
|
-
async
|
|
978
|
-
|
|
874
|
+
async assignRole(roleId, body, token) {
|
|
875
|
+
const path = `/v1/auth/roles/${roleId}/assign`;
|
|
876
|
+
return this.request(
|
|
877
|
+
"POST",
|
|
878
|
+
path,
|
|
879
|
+
body,
|
|
880
|
+
token
|
|
881
|
+
);
|
|
979
882
|
}
|
|
980
883
|
/**
|
|
981
|
-
*
|
|
884
|
+
* List role permissions
|
|
885
|
+
* GET /v1/auth/roles/{roleId}/permissions
|
|
982
886
|
*/
|
|
983
|
-
async
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
error: null,
|
|
992
|
-
isAuthenticated: true,
|
|
993
|
-
isLoading: false
|
|
994
|
-
});
|
|
995
|
-
if (this.autoRefresh) {
|
|
996
|
-
this.startAutoRefresh();
|
|
997
|
-
}
|
|
998
|
-
} catch (error) {
|
|
999
|
-
this.handleError(error);
|
|
1000
|
-
}
|
|
887
|
+
async listRolePermissions(roleId, token) {
|
|
888
|
+
const path = `/v1/auth/roles/${roleId}/permissions`;
|
|
889
|
+
return this.request(
|
|
890
|
+
"GET",
|
|
891
|
+
path,
|
|
892
|
+
void 0,
|
|
893
|
+
token
|
|
894
|
+
);
|
|
1001
895
|
}
|
|
1002
896
|
/**
|
|
1003
|
-
*
|
|
897
|
+
* Add permission to role
|
|
898
|
+
* POST /v1/auth/roles/{roleId}/permissions
|
|
1004
899
|
*/
|
|
1005
|
-
async
|
|
1006
|
-
|
|
900
|
+
async addPermission(roleId, body, token) {
|
|
901
|
+
const path = `/v1/auth/roles/${roleId}/permissions`;
|
|
902
|
+
return this.request(
|
|
903
|
+
"POST",
|
|
904
|
+
path,
|
|
905
|
+
body,
|
|
906
|
+
token
|
|
907
|
+
);
|
|
1007
908
|
}
|
|
1008
909
|
/**
|
|
1009
|
-
*
|
|
910
|
+
* Remove permission from role
|
|
911
|
+
* DELETE /v1/auth/roles/{roleId}/permissions/{permissionId}
|
|
1010
912
|
*/
|
|
1011
|
-
async
|
|
1012
|
-
|
|
913
|
+
async removePermission(roleId, permissionId, body, token) {
|
|
914
|
+
const path = `/v1/auth/roles/${roleId}/permissions/${permissionId}`;
|
|
915
|
+
return this.request(
|
|
916
|
+
"DELETE",
|
|
917
|
+
path,
|
|
918
|
+
body,
|
|
919
|
+
token
|
|
920
|
+
);
|
|
1013
921
|
}
|
|
1014
922
|
/**
|
|
1015
|
-
*
|
|
923
|
+
* Unassign role from user
|
|
924
|
+
* POST /v1/auth/roles/{roleId}/unassign
|
|
1016
925
|
*/
|
|
1017
|
-
async
|
|
1018
|
-
|
|
926
|
+
async unassignRole(roleId, body, token) {
|
|
927
|
+
const path = `/v1/auth/roles/${roleId}/unassign`;
|
|
928
|
+
return this.request(
|
|
929
|
+
"POST",
|
|
930
|
+
path,
|
|
931
|
+
body,
|
|
932
|
+
token
|
|
933
|
+
);
|
|
1019
934
|
}
|
|
1020
935
|
/**
|
|
1021
|
-
*
|
|
936
|
+
* List sessions
|
|
937
|
+
* GET /v1/auth/sessions
|
|
1022
938
|
*/
|
|
1023
|
-
async
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
error: null,
|
|
1032
|
-
isAuthenticated: true,
|
|
1033
|
-
isLoading: false
|
|
1034
|
-
});
|
|
1035
|
-
if (this.autoRefresh) {
|
|
1036
|
-
this.startAutoRefresh();
|
|
1037
|
-
}
|
|
1038
|
-
} catch (error) {
|
|
1039
|
-
this.handleError(error);
|
|
1040
|
-
}
|
|
939
|
+
async listSessions(token) {
|
|
940
|
+
const path = "/v1/auth/sessions";
|
|
941
|
+
return this.request(
|
|
942
|
+
"GET",
|
|
943
|
+
path,
|
|
944
|
+
void 0,
|
|
945
|
+
token
|
|
946
|
+
);
|
|
1041
947
|
}
|
|
1042
948
|
/**
|
|
1043
|
-
*
|
|
949
|
+
* Revoke session
|
|
950
|
+
* DELETE /v1/auth/sessions/{sessionId}
|
|
1044
951
|
*/
|
|
1045
|
-
async
|
|
1046
|
-
|
|
952
|
+
async revokeSession(sessionId, body, token) {
|
|
953
|
+
const path = `/v1/auth/sessions/${sessionId}`;
|
|
954
|
+
return this.request(
|
|
955
|
+
"DELETE",
|
|
956
|
+
path,
|
|
957
|
+
body,
|
|
958
|
+
token
|
|
959
|
+
);
|
|
1047
960
|
}
|
|
1048
961
|
/**
|
|
1049
|
-
*
|
|
962
|
+
* Sign in
|
|
963
|
+
* POST /v1/auth/signin
|
|
1050
964
|
*/
|
|
1051
|
-
async
|
|
1052
|
-
|
|
965
|
+
async signIn(body) {
|
|
966
|
+
const path = "/v1/auth/signin";
|
|
967
|
+
return this.request(
|
|
968
|
+
"POST",
|
|
969
|
+
path,
|
|
970
|
+
body
|
|
971
|
+
);
|
|
1053
972
|
}
|
|
1054
973
|
/**
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
974
|
+
* Sign out
|
|
975
|
+
* POST /v1/auth/signout
|
|
976
|
+
*/
|
|
977
|
+
async signOut(body, token) {
|
|
978
|
+
const path = "/v1/auth/signout";
|
|
979
|
+
return this.request(
|
|
980
|
+
"POST",
|
|
981
|
+
path,
|
|
982
|
+
body,
|
|
983
|
+
token
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Sign up
|
|
988
|
+
* POST /v1/auth/signup
|
|
1057
989
|
*/
|
|
1058
|
-
async
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
990
|
+
async signUp(body) {
|
|
991
|
+
const path = "/v1/auth/signup";
|
|
992
|
+
return this.request(
|
|
993
|
+
"POST",
|
|
994
|
+
path,
|
|
995
|
+
body
|
|
996
|
+
);
|
|
1063
997
|
}
|
|
1064
998
|
/**
|
|
1065
|
-
*
|
|
1066
|
-
*
|
|
999
|
+
* Start OAuth flow
|
|
1000
|
+
* POST /v1/auth/social/{provider}
|
|
1067
1001
|
*/
|
|
1068
|
-
async
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1002
|
+
async startOAuth(provider, body) {
|
|
1003
|
+
const path = `/v1/auth/social/${provider}`;
|
|
1004
|
+
return this.request(
|
|
1005
|
+
"POST",
|
|
1006
|
+
path,
|
|
1007
|
+
body
|
|
1008
|
+
);
|
|
1073
1009
|
}
|
|
1074
1010
|
/**
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1011
|
+
* OAuth callback
|
|
1012
|
+
* GET /v1/auth/social/{provider}/callback
|
|
1077
1013
|
*/
|
|
1078
|
-
async
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1014
|
+
async oauthCallback(provider) {
|
|
1015
|
+
const path = `/v1/auth/social/${provider}/callback`;
|
|
1016
|
+
return this.request(
|
|
1017
|
+
"GET",
|
|
1018
|
+
path,
|
|
1019
|
+
void 0
|
|
1020
|
+
);
|
|
1084
1021
|
}
|
|
1085
1022
|
/**
|
|
1086
|
-
*
|
|
1087
|
-
*
|
|
1023
|
+
* SSO SAML ACS endpoint
|
|
1024
|
+
* POST /v1/auth/sso/{provider}/acs
|
|
1088
1025
|
*/
|
|
1089
|
-
async
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1026
|
+
async ssoACS(provider, body) {
|
|
1027
|
+
const path = `/v1/auth/sso/${provider}/acs`;
|
|
1028
|
+
return this.request(
|
|
1029
|
+
"POST",
|
|
1030
|
+
path,
|
|
1031
|
+
body
|
|
1032
|
+
);
|
|
1094
1033
|
}
|
|
1095
1034
|
/**
|
|
1096
|
-
*
|
|
1035
|
+
* SSO callback (OIDC)
|
|
1036
|
+
* POST /v1/auth/sso/{provider}/callback
|
|
1097
1037
|
*/
|
|
1098
|
-
|
|
1099
|
-
|
|
1038
|
+
async ssoCallback(provider, body) {
|
|
1039
|
+
const path = `/v1/auth/sso/${provider}/callback`;
|
|
1040
|
+
return this.request(
|
|
1041
|
+
"POST",
|
|
1042
|
+
path,
|
|
1043
|
+
body
|
|
1044
|
+
);
|
|
1100
1045
|
}
|
|
1101
1046
|
/**
|
|
1102
|
-
*
|
|
1047
|
+
* Start SSO login flow
|
|
1048
|
+
* POST /v1/auth/sso/{provider}/login
|
|
1103
1049
|
*/
|
|
1104
|
-
async
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
});
|
|
1112
|
-
} catch (error) {
|
|
1113
|
-
console.warn("[AuthClient] Session refresh failed:", error);
|
|
1114
|
-
}
|
|
1050
|
+
async startSSOLogin(provider, body) {
|
|
1051
|
+
const path = `/v1/auth/sso/${provider}/login`;
|
|
1052
|
+
return this.request(
|
|
1053
|
+
"POST",
|
|
1054
|
+
path,
|
|
1055
|
+
body
|
|
1056
|
+
);
|
|
1115
1057
|
}
|
|
1116
1058
|
/**
|
|
1117
|
-
*
|
|
1059
|
+
* List user roles
|
|
1060
|
+
* GET /v1/auth/users/{userId}/roles
|
|
1118
1061
|
*/
|
|
1119
|
-
|
|
1120
|
-
|
|
1062
|
+
async listUserRoles(userId, token) {
|
|
1063
|
+
const path = `/v1/auth/users/${userId}/roles`;
|
|
1064
|
+
return this.request(
|
|
1065
|
+
"GET",
|
|
1066
|
+
path,
|
|
1067
|
+
void 0,
|
|
1068
|
+
token
|
|
1069
|
+
);
|
|
1121
1070
|
}
|
|
1122
1071
|
/**
|
|
1123
|
-
*
|
|
1072
|
+
* Verify email
|
|
1073
|
+
* POST /v1/auth/verify-email
|
|
1124
1074
|
*/
|
|
1125
|
-
|
|
1126
|
-
|
|
1075
|
+
async verifyEmail(body) {
|
|
1076
|
+
const path = "/v1/auth/verify-email";
|
|
1077
|
+
return this.request(
|
|
1078
|
+
"POST",
|
|
1079
|
+
path,
|
|
1080
|
+
body
|
|
1081
|
+
);
|
|
1127
1082
|
}
|
|
1128
1083
|
/**
|
|
1129
|
-
*
|
|
1084
|
+
* List webhooks
|
|
1085
|
+
* GET /v1/auth/webhooks
|
|
1130
1086
|
*/
|
|
1131
|
-
|
|
1132
|
-
|
|
1087
|
+
async listWebhooks(token) {
|
|
1088
|
+
const path = "/v1/auth/webhooks";
|
|
1089
|
+
return this.request(
|
|
1090
|
+
"GET",
|
|
1091
|
+
path,
|
|
1092
|
+
void 0,
|
|
1093
|
+
token
|
|
1094
|
+
);
|
|
1133
1095
|
}
|
|
1134
1096
|
/**
|
|
1135
|
-
*
|
|
1097
|
+
* Create webhook
|
|
1098
|
+
* POST /v1/auth/webhooks
|
|
1136
1099
|
*/
|
|
1137
|
-
|
|
1138
|
-
|
|
1100
|
+
async createWebhook(body, token) {
|
|
1101
|
+
const path = "/v1/auth/webhooks";
|
|
1102
|
+
return this.request(
|
|
1103
|
+
"POST",
|
|
1104
|
+
path,
|
|
1105
|
+
body,
|
|
1106
|
+
token
|
|
1107
|
+
);
|
|
1139
1108
|
}
|
|
1140
1109
|
/**
|
|
1141
|
-
*
|
|
1110
|
+
* Get webhook
|
|
1111
|
+
* GET /v1/auth/webhooks/{webhookId}
|
|
1142
1112
|
*/
|
|
1143
|
-
|
|
1144
|
-
const
|
|
1145
|
-
this.
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1113
|
+
async getWebhook(webhookId, token) {
|
|
1114
|
+
const path = `/v1/auth/webhooks/${webhookId}`;
|
|
1115
|
+
return this.request(
|
|
1116
|
+
"GET",
|
|
1117
|
+
path,
|
|
1118
|
+
void 0,
|
|
1119
|
+
token
|
|
1120
|
+
);
|
|
1149
1121
|
}
|
|
1150
1122
|
/**
|
|
1151
|
-
*
|
|
1123
|
+
* Update webhook
|
|
1124
|
+
* PATCH /v1/auth/webhooks/{webhookId}
|
|
1152
1125
|
*/
|
|
1153
|
-
|
|
1154
|
-
|
|
1126
|
+
async updateWebhook(webhookId, body, token) {
|
|
1127
|
+
const path = `/v1/auth/webhooks/${webhookId}`;
|
|
1128
|
+
return this.request(
|
|
1129
|
+
"PATCH",
|
|
1130
|
+
path,
|
|
1131
|
+
body,
|
|
1132
|
+
token
|
|
1133
|
+
);
|
|
1155
1134
|
}
|
|
1156
1135
|
/**
|
|
1157
|
-
*
|
|
1136
|
+
* Delete webhook
|
|
1137
|
+
* DELETE /v1/auth/webhooks/{webhookId}
|
|
1158
1138
|
*/
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
this.
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
setLoading() {
|
|
1168
|
-
const currentState = this.state.getValue();
|
|
1169
|
-
this.updateState({
|
|
1170
|
-
...currentState,
|
|
1171
|
-
state: "loading" /* LOADING */,
|
|
1172
|
-
isLoading: true,
|
|
1173
|
-
error: null
|
|
1174
|
-
});
|
|
1139
|
+
async deleteWebhook(webhookId, body, token) {
|
|
1140
|
+
const path = `/v1/auth/webhooks/${webhookId}`;
|
|
1141
|
+
return this.request(
|
|
1142
|
+
"DELETE",
|
|
1143
|
+
path,
|
|
1144
|
+
body,
|
|
1145
|
+
token
|
|
1146
|
+
);
|
|
1175
1147
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1148
|
+
// ──────────────────────────────────────────────────
|
|
1149
|
+
// Internal request helper
|
|
1150
|
+
// ──────────────────────────────────────────────────
|
|
1151
|
+
async request(method, path, body, token) {
|
|
1152
|
+
const headers = {
|
|
1153
|
+
"Content-Type": "application/json",
|
|
1154
|
+
"Accept": "application/json"
|
|
1155
|
+
};
|
|
1156
|
+
if (token) {
|
|
1157
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
1158
|
+
}
|
|
1159
|
+
const response = await this.fetchFn(`${this.baseURL}${path}`, {
|
|
1160
|
+
method,
|
|
1161
|
+
headers,
|
|
1162
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
1184
1163
|
});
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
clearInterval(this.refreshTimer);
|
|
1196
|
-
this.refreshTimer = void 0;
|
|
1164
|
+
if (!response.ok) {
|
|
1165
|
+
let apiError;
|
|
1166
|
+
try {
|
|
1167
|
+
apiError = await response.json();
|
|
1168
|
+
} catch {
|
|
1169
|
+
}
|
|
1170
|
+
throw new AuthClientError(
|
|
1171
|
+
apiError?.error ?? `Request failed with status ${response.status}`,
|
|
1172
|
+
apiError?.code ?? response.status
|
|
1173
|
+
);
|
|
1197
1174
|
}
|
|
1175
|
+
if (response.status === 204) {
|
|
1176
|
+
return void 0;
|
|
1177
|
+
}
|
|
1178
|
+
return response.json();
|
|
1198
1179
|
}
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1180
|
+
};
|
|
1181
|
+
var AuthClientError = class extends Error {
|
|
1182
|
+
code;
|
|
1183
|
+
constructor(message, code) {
|
|
1184
|
+
super(message);
|
|
1185
|
+
this.name = "AuthClientError";
|
|
1186
|
+
this.code = code;
|
|
1205
1187
|
}
|
|
1206
1188
|
};
|
|
1207
1189
|
|
|
1208
|
-
// src/
|
|
1209
|
-
var
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
FlowStep2["PHONE_REQUEST"] = "phone_request";
|
|
1220
|
-
FlowStep2["PHONE_VERIFY"] = "phone_verify";
|
|
1221
|
-
FlowStep2["USERNAME_SIGN_IN"] = "username_sign_in";
|
|
1222
|
-
FlowStep2["USERNAME_SIGN_UP"] = "username_sign_up";
|
|
1223
|
-
FlowStep2["PASSKEY_REGISTER"] = "passkey_register";
|
|
1224
|
-
FlowStep2["PASSKEY_AUTHENTICATE"] = "passkey_authenticate";
|
|
1225
|
-
FlowStep2["MFA_REQUIRED"] = "mfa_required";
|
|
1226
|
-
FlowStep2["MFA_SETUP"] = "mfa_setup";
|
|
1227
|
-
FlowStep2["MFA_VERIFY"] = "mfa_verify";
|
|
1228
|
-
FlowStep2["MFA_SELECT_METHOD"] = "mfa_select_method";
|
|
1229
|
-
FlowStep2["EMAIL_VERIFICATION_REQUIRED"] = "email_verification_required";
|
|
1230
|
-
FlowStep2["EMAIL_VERIFICATION_SENT"] = "email_verification_sent";
|
|
1231
|
-
FlowStep2["PHONE_VERIFICATION_REQUIRED"] = "phone_verification_required";
|
|
1232
|
-
FlowStep2["PASSWORD_RESET_REQUEST"] = "password_reset_request";
|
|
1233
|
-
FlowStep2["PASSWORD_RESET_SENT"] = "password_reset_sent";
|
|
1234
|
-
FlowStep2["PASSWORD_RESET_CONFIRM"] = "password_reset_confirm";
|
|
1235
|
-
FlowStep2["PASSWORD_CHANGE"] = "password_change";
|
|
1236
|
-
FlowStep2["PROFILE_UPDATE"] = "profile_update";
|
|
1237
|
-
FlowStep2["PROFILE_COMPLETE"] = "profile_complete";
|
|
1238
|
-
FlowStep2["SUCCESS"] = "success";
|
|
1239
|
-
FlowStep2["ERROR"] = "error";
|
|
1240
|
-
FlowStep2["CANCELLED"] = "cancelled";
|
|
1241
|
-
return FlowStep2;
|
|
1242
|
-
})(FlowStep || {});
|
|
1243
|
-
var FlowConfigType = /* @__PURE__ */ ((FlowConfigType2) => {
|
|
1244
|
-
FlowConfigType2["SIMPLE_SIGN_IN"] = "simple_sign_in";
|
|
1245
|
-
FlowConfigType2["SIMPLE_SIGN_UP"] = "simple_sign_up";
|
|
1246
|
-
FlowConfigType2["SIGN_UP_WITH_EMAIL_VERIFICATION"] = "sign_up_with_email_verification";
|
|
1247
|
-
FlowConfigType2["SIGN_IN_WITH_MFA"] = "sign_in_with_mfa";
|
|
1248
|
-
FlowConfigType2["OAUTH_SIGN_IN"] = "oauth_sign_in";
|
|
1249
|
-
FlowConfigType2["MAGIC_LINK_FLOW"] = "magic_link_flow";
|
|
1250
|
-
FlowConfigType2["PHONE_AUTH_FLOW"] = "phone_auth_flow";
|
|
1251
|
-
FlowConfigType2["COMPLETE_SIGN_UP_FLOW"] = "complete_sign_up_flow";
|
|
1252
|
-
FlowConfigType2["SECURE_SIGN_IN_FLOW"] = "secure_sign_in_flow";
|
|
1253
|
-
FlowConfigType2["PASSWORD_RESET_FLOW"] = "password_reset_flow";
|
|
1254
|
-
FlowConfigType2["EMAIL_VERIFICATION_FLOW"] = "email_verification_flow";
|
|
1255
|
-
FlowConfigType2["CUSTOM"] = "custom";
|
|
1256
|
-
return FlowConfigType2;
|
|
1257
|
-
})(FlowConfigType || {});
|
|
1258
|
-
var FlowAction = /* @__PURE__ */ ((FlowAction2) => {
|
|
1259
|
-
FlowAction2["START"] = "start";
|
|
1260
|
-
FlowAction2["NEXT"] = "next";
|
|
1261
|
-
FlowAction2["BACK"] = "back";
|
|
1262
|
-
FlowAction2["CANCEL"] = "cancel";
|
|
1263
|
-
FlowAction2["ERROR"] = "error";
|
|
1264
|
-
FlowAction2["RESET"] = "reset";
|
|
1265
|
-
return FlowAction2;
|
|
1266
|
-
})(FlowAction || {});
|
|
1267
|
-
|
|
1268
|
-
// src/flows/engine.ts
|
|
1269
|
-
var FlowEngine = class {
|
|
1270
|
-
constructor(config, initialState) {
|
|
1271
|
-
this.history = [];
|
|
1272
|
-
this.config = config;
|
|
1273
|
-
this.state = {
|
|
1274
|
-
currentStep: config.initialStep,
|
|
1275
|
-
...initialState
|
|
1276
|
-
};
|
|
1277
|
-
this.history.push(this.state.currentStep);
|
|
1190
|
+
// src/client.ts
|
|
1191
|
+
var AuthClient2 = class extends AuthClient {
|
|
1192
|
+
/**
|
|
1193
|
+
* Refresh session tokens.
|
|
1194
|
+
*
|
|
1195
|
+
* Accepts a raw refresh-token string (used by auth.ts) or the full
|
|
1196
|
+
* RefreshRequest body.
|
|
1197
|
+
*/
|
|
1198
|
+
async refresh(body) {
|
|
1199
|
+
const req = typeof body === "string" ? { refresh_token: body } : body;
|
|
1200
|
+
return super.refresh(req);
|
|
1278
1201
|
}
|
|
1279
1202
|
/**
|
|
1280
|
-
*
|
|
1203
|
+
* Sign out.
|
|
1204
|
+
*
|
|
1205
|
+
* Accepts a raw token string (used by auth.ts) or the full
|
|
1206
|
+
* (body, token) pair from the generated client.
|
|
1281
1207
|
*/
|
|
1282
|
-
|
|
1283
|
-
|
|
1208
|
+
async signOut(bodyOrToken, token) {
|
|
1209
|
+
if (typeof bodyOrToken === "string") {
|
|
1210
|
+
return super.signOut({}, bodyOrToken);
|
|
1211
|
+
}
|
|
1212
|
+
return super.signOut(bodyOrToken, token);
|
|
1284
1213
|
}
|
|
1285
1214
|
/**
|
|
1286
|
-
*
|
|
1215
|
+
* MFA challenge — bridge for auth.ts.
|
|
1216
|
+
*
|
|
1217
|
+
* auth.ts calls `mfaChallenge({ enrollment_id, code })` and expects
|
|
1218
|
+
* an AuthResponse back. The generated client uses `challengeMFA`.
|
|
1287
1219
|
*/
|
|
1288
|
-
|
|
1289
|
-
return
|
|
1220
|
+
async mfaChallenge(body) {
|
|
1221
|
+
return super.challengeMFA(body);
|
|
1290
1222
|
}
|
|
1291
1223
|
/**
|
|
1292
|
-
*
|
|
1224
|
+
* Verify an MFA recovery code.
|
|
1225
|
+
*
|
|
1226
|
+
* Accepts a raw code string (used by auth.ts) or the full request body.
|
|
1293
1227
|
*/
|
|
1294
|
-
|
|
1295
|
-
|
|
1228
|
+
async verifyRecoveryCode(body) {
|
|
1229
|
+
const req = typeof body === "string" ? { code: body } : body;
|
|
1230
|
+
return super.verifyRecoveryCode(req);
|
|
1296
1231
|
}
|
|
1297
1232
|
/**
|
|
1298
|
-
*
|
|
1233
|
+
* Send an SMS code for MFA — bridge for auth.ts.
|
|
1234
|
+
*
|
|
1235
|
+
* Simplifies the call-site by accepting just the session token.
|
|
1299
1236
|
*/
|
|
1300
|
-
async
|
|
1301
|
-
|
|
1302
|
-
switch (action) {
|
|
1303
|
-
case "start":
|
|
1304
|
-
return this.handleStart(data);
|
|
1305
|
-
case "next":
|
|
1306
|
-
return this.handleNext(data);
|
|
1307
|
-
case "back":
|
|
1308
|
-
return this.handleBack();
|
|
1309
|
-
case "cancel":
|
|
1310
|
-
return this.handleCancel();
|
|
1311
|
-
case "error":
|
|
1312
|
-
return this.handleError(error);
|
|
1313
|
-
case "reset":
|
|
1314
|
-
return this.handleReset();
|
|
1315
|
-
default:
|
|
1316
|
-
throw new AuthError(
|
|
1317
|
-
`Unknown flow action: ${action}`,
|
|
1318
|
-
"validation_error" /* VALIDATION_ERROR */
|
|
1319
|
-
);
|
|
1320
|
-
}
|
|
1237
|
+
async sendSMSCodeForMFA(token) {
|
|
1238
|
+
return super.sendSMSCode({}, token);
|
|
1321
1239
|
}
|
|
1322
1240
|
/**
|
|
1323
|
-
*
|
|
1241
|
+
* Verify an SMS code for MFA — bridge for auth.ts.
|
|
1242
|
+
*
|
|
1243
|
+
* Simplifies the call-site by accepting code + token directly.
|
|
1324
1244
|
*/
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
currentStep: this.config.initialStep,
|
|
1328
|
-
...data
|
|
1329
|
-
};
|
|
1330
|
-
this.history = [this.state.currentStep];
|
|
1331
|
-
if (this.config.onStepChange) {
|
|
1332
|
-
this.config.onStepChange(this.state.currentStep, this.state);
|
|
1333
|
-
}
|
|
1334
|
-
return this.getState();
|
|
1245
|
+
async verifySMSCodeForMFA(code, token) {
|
|
1246
|
+
return super.verifySMSCode({ code }, token);
|
|
1335
1247
|
}
|
|
1336
1248
|
/**
|
|
1337
|
-
*
|
|
1249
|
+
* Fetch the client configuration from the backend.
|
|
1250
|
+
*
|
|
1251
|
+
* The config describes which auth methods are enabled so SDK
|
|
1252
|
+
* components can auto-configure without manual props.
|
|
1338
1253
|
*/
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
previousStep: this.state.currentStep
|
|
1344
|
-
};
|
|
1345
|
-
const transitionConfig = this.config.transitions[this.state.currentStep];
|
|
1346
|
-
if (!transitionConfig) {
|
|
1347
|
-
throw new AuthError(
|
|
1348
|
-
`No transition configured for step: ${this.state.currentStep}`,
|
|
1349
|
-
"validation_error" /* VALIDATION_ERROR */
|
|
1350
|
-
);
|
|
1254
|
+
async fetchClientConfig(publishableKey) {
|
|
1255
|
+
const url = new URL("/v1/auth/client-config", this.config.baseURL);
|
|
1256
|
+
if (publishableKey) {
|
|
1257
|
+
url.searchParams.set("key", publishableKey);
|
|
1351
1258
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1259
|
+
const fetchFn = this.config.fetch ?? globalThis.fetch;
|
|
1260
|
+
const res = await fetchFn(url.toString(), {
|
|
1261
|
+
method: "GET",
|
|
1262
|
+
headers: { "Content-Type": "application/json" }
|
|
1263
|
+
});
|
|
1264
|
+
if (!res.ok) {
|
|
1265
|
+
throw new AuthClientError("Failed to fetch client config", res.status);
|
|
1358
1266
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1267
|
+
return res.json();
|
|
1268
|
+
}
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
// src/auth.ts
|
|
1272
|
+
var SESSION_KEY = "authsome:session";
|
|
1273
|
+
var CONFIG_KEY = "authsome:client_config";
|
|
1274
|
+
var REFRESH_BEFORE_MS = 6e4;
|
|
1275
|
+
var CONFIG_TTL_MS = 5 * 6e4;
|
|
1276
|
+
var memoryStorage = /* @__PURE__ */ (() => {
|
|
1277
|
+
const store = /* @__PURE__ */ new Map();
|
|
1278
|
+
return {
|
|
1279
|
+
getItem: (key) => store.get(key) ?? null,
|
|
1280
|
+
setItem: (key, value) => {
|
|
1281
|
+
store.set(key, value);
|
|
1282
|
+
},
|
|
1283
|
+
removeItem: (key) => {
|
|
1284
|
+
store.delete(key);
|
|
1361
1285
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1286
|
+
};
|
|
1287
|
+
})();
|
|
1288
|
+
function defaultStorage() {
|
|
1289
|
+
try {
|
|
1290
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
1291
|
+
return window.localStorage;
|
|
1292
|
+
}
|
|
1293
|
+
} catch {
|
|
1366
1294
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1295
|
+
return memoryStorage;
|
|
1296
|
+
}
|
|
1297
|
+
var AuthManager = class {
|
|
1298
|
+
client;
|
|
1299
|
+
storage;
|
|
1300
|
+
state = { status: "idle" };
|
|
1301
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1302
|
+
refreshTimer = null;
|
|
1303
|
+
onError;
|
|
1304
|
+
publishableKey;
|
|
1305
|
+
clientConfig = null;
|
|
1306
|
+
configListeners = /* @__PURE__ */ new Set();
|
|
1307
|
+
configFetchPromise = null;
|
|
1308
|
+
constructor(config) {
|
|
1309
|
+
this.client = new AuthClient2(config);
|
|
1310
|
+
this.storage = config.storage ?? defaultStorage();
|
|
1311
|
+
this.onError = config.onError;
|
|
1312
|
+
this.publishableKey = config.publishableKey;
|
|
1313
|
+
if (config.initialClientConfig) {
|
|
1314
|
+
this.clientConfig = config.initialClientConfig;
|
|
1315
|
+
}
|
|
1316
|
+
if (config.onStateChange) {
|
|
1317
|
+
this.listeners.add(config.onStateChange);
|
|
1376
1318
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
return this.
|
|
1319
|
+
}
|
|
1320
|
+
// ── Public API ────────────────────────────────────
|
|
1321
|
+
/** Current auth state (snapshot). */
|
|
1322
|
+
getState() {
|
|
1323
|
+
return this.state;
|
|
1324
|
+
}
|
|
1325
|
+
/** Subscribe to state changes. Returns an unsubscribe function. */
|
|
1326
|
+
subscribe(listener) {
|
|
1327
|
+
this.listeners.add(listener);
|
|
1328
|
+
return () => {
|
|
1329
|
+
this.listeners.delete(listener);
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
/** Access the underlying HTTP client. */
|
|
1333
|
+
getClient() {
|
|
1334
|
+
return this.client;
|
|
1382
1335
|
}
|
|
1383
1336
|
/**
|
|
1384
|
-
*
|
|
1337
|
+
* Initialize by hydrating the session from storage.
|
|
1338
|
+
* When a publishableKey is set, also fetches client config in parallel.
|
|
1339
|
+
* Call this once on app start.
|
|
1385
1340
|
*/
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
if (this.config.onCancel) {
|
|
1390
|
-
this.config.onCancel(this.state);
|
|
1341
|
+
async initialize() {
|
|
1342
|
+
if (this.publishableKey && !this.clientConfig) {
|
|
1343
|
+
void this.fetchClientConfig();
|
|
1391
1344
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1345
|
+
try {
|
|
1346
|
+
const raw = await this.storage.getItem(SESSION_KEY);
|
|
1347
|
+
if (!raw) {
|
|
1348
|
+
this.setState({ status: "unauthenticated" });
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
const session = JSON.parse(raw);
|
|
1352
|
+
const expiresAt = new Date(session.expires_at).getTime();
|
|
1353
|
+
if (Date.now() >= expiresAt) {
|
|
1354
|
+
await this.refreshSession(session.refresh_token);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
this.setState({ status: "loading" });
|
|
1358
|
+
const user = await this.client.getMe(session.session_token);
|
|
1359
|
+
this.setState({ status: "authenticated", user, session });
|
|
1360
|
+
this.scheduleRefresh(session);
|
|
1361
|
+
} catch {
|
|
1362
|
+
await this.clearSession();
|
|
1363
|
+
this.setState({ status: "unauthenticated" });
|
|
1394
1364
|
}
|
|
1395
|
-
this.state.currentStep = "cancelled";
|
|
1396
|
-
return this.getState();
|
|
1397
1365
|
}
|
|
1398
|
-
/**
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1366
|
+
/** Sign in with email & password. */
|
|
1367
|
+
async signIn(credentials) {
|
|
1368
|
+
this.setState({ status: "loading" });
|
|
1369
|
+
try {
|
|
1370
|
+
const res = await this.client.signIn(credentials);
|
|
1371
|
+
const session = {
|
|
1372
|
+
session_token: res.session_token,
|
|
1373
|
+
refresh_token: res.refresh_token,
|
|
1374
|
+
expires_at: new Date(Date.now() + 36e5).toISOString()
|
|
1375
|
+
// fallback
|
|
1376
|
+
};
|
|
1377
|
+
await this.handleAuthResponse(res.user, session);
|
|
1378
|
+
} catch (err) {
|
|
1379
|
+
this.handleError(err);
|
|
1380
|
+
throw err;
|
|
1407
1381
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1382
|
+
}
|
|
1383
|
+
/** Sign up with email & password. */
|
|
1384
|
+
async signUp(data) {
|
|
1385
|
+
this.setState({ status: "loading" });
|
|
1386
|
+
try {
|
|
1387
|
+
const res = await this.client.signUp(data);
|
|
1388
|
+
const session = {
|
|
1389
|
+
session_token: res.session_token,
|
|
1390
|
+
refresh_token: res.refresh_token,
|
|
1391
|
+
expires_at: new Date(Date.now() + 36e5).toISOString()
|
|
1392
|
+
};
|
|
1393
|
+
await this.handleAuthResponse(res.user, session);
|
|
1394
|
+
} catch (err) {
|
|
1395
|
+
this.handleError(err);
|
|
1396
|
+
throw err;
|
|
1410
1397
|
}
|
|
1411
|
-
return this.getState();
|
|
1412
1398
|
}
|
|
1413
|
-
/**
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1399
|
+
/** Sign out and clear the session. */
|
|
1400
|
+
async signOut() {
|
|
1401
|
+
const token = this.getSessionToken();
|
|
1402
|
+
if (token) {
|
|
1403
|
+
try {
|
|
1404
|
+
await this.client.signOut(token);
|
|
1405
|
+
} catch {
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
this.clearRefreshTimer();
|
|
1409
|
+
await this.clearSession();
|
|
1410
|
+
this.setState({ status: "unauthenticated" });
|
|
1418
1411
|
}
|
|
1419
|
-
/**
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1412
|
+
/** Submit an MFA challenge code. */
|
|
1413
|
+
async submitMFACode(enrollmentId, code) {
|
|
1414
|
+
this.setState({ status: "loading" });
|
|
1415
|
+
try {
|
|
1416
|
+
const res = await this.client.mfaChallenge({ enrollment_id: enrollmentId, code });
|
|
1417
|
+
const session = {
|
|
1418
|
+
session_token: res.session_token,
|
|
1419
|
+
refresh_token: res.refresh_token,
|
|
1420
|
+
expires_at: new Date(Date.now() + 36e5).toISOString()
|
|
1421
|
+
};
|
|
1422
|
+
await this.handleAuthResponse(res.user, session);
|
|
1423
|
+
} catch (err) {
|
|
1424
|
+
this.handleError(err);
|
|
1428
1425
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1426
|
+
}
|
|
1427
|
+
/** Submit an MFA recovery code. */
|
|
1428
|
+
async submitRecoveryCode(code) {
|
|
1429
|
+
this.setState({ status: "loading" });
|
|
1430
|
+
try {
|
|
1431
|
+
const res = await this.client.verifyRecoveryCode(code);
|
|
1432
|
+
const session = {
|
|
1433
|
+
session_token: res.session_token,
|
|
1434
|
+
refresh_token: res.refresh_token,
|
|
1435
|
+
expires_at: new Date(Date.now() + 36e5).toISOString()
|
|
1436
|
+
};
|
|
1437
|
+
await this.handleAuthResponse(res.user, session);
|
|
1438
|
+
} catch (err) {
|
|
1439
|
+
this.handleError(err);
|
|
1432
1440
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1441
|
+
}
|
|
1442
|
+
/** Send an SMS code for MFA verification. Returns masked phone + expiry info. */
|
|
1443
|
+
async sendSMSCode() {
|
|
1444
|
+
const token = this.getSessionToken();
|
|
1445
|
+
if (!token) throw new Error("No session token available");
|
|
1446
|
+
return this.client.sendSMSCodeForMFA(token);
|
|
1447
|
+
}
|
|
1448
|
+
/** Submit an SMS verification code during MFA challenge. */
|
|
1449
|
+
async submitSMSCode(code) {
|
|
1450
|
+
this.setState({ status: "loading" });
|
|
1451
|
+
try {
|
|
1452
|
+
const token = this.getSessionToken();
|
|
1453
|
+
if (!token) throw new Error("No session token available");
|
|
1454
|
+
const res = await this.client.verifySMSCodeForMFA(code, token);
|
|
1455
|
+
const session = {
|
|
1456
|
+
session_token: res.session_token,
|
|
1457
|
+
refresh_token: res.refresh_token,
|
|
1458
|
+
expires_at: new Date(Date.now() + 36e5).toISOString()
|
|
1459
|
+
};
|
|
1460
|
+
await this.handleAuthResponse(res.user, session);
|
|
1461
|
+
} catch (err) {
|
|
1462
|
+
this.handleError(err);
|
|
1435
1463
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1464
|
+
}
|
|
1465
|
+
/** Refresh the current session manually. */
|
|
1466
|
+
async refreshNow() {
|
|
1467
|
+
const state = this.state;
|
|
1468
|
+
if (state.status !== "authenticated") return;
|
|
1469
|
+
await this.refreshSession(state.session.refresh_token);
|
|
1470
|
+
}
|
|
1471
|
+
/** Get the current session token (if authenticated). */
|
|
1472
|
+
getSessionToken() {
|
|
1473
|
+
if (this.state.status === "authenticated") {
|
|
1474
|
+
return this.state.session.session_token;
|
|
1440
1475
|
}
|
|
1441
|
-
|
|
1476
|
+
if (this.state.status === "mfa_required") {
|
|
1477
|
+
return this.state.session.session_token;
|
|
1478
|
+
}
|
|
1479
|
+
return null;
|
|
1442
1480
|
}
|
|
1443
|
-
/**
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1481
|
+
/** Get the current user (if authenticated). */
|
|
1482
|
+
getUser() {
|
|
1483
|
+
if (this.state.status === "authenticated") {
|
|
1484
|
+
return this.state.user;
|
|
1485
|
+
}
|
|
1486
|
+
return null;
|
|
1487
|
+
}
|
|
1488
|
+
// ── Client Config API ────────────────────────────
|
|
1489
|
+
/** Get the cached client config (or null if not yet fetched). */
|
|
1490
|
+
getClientConfig() {
|
|
1491
|
+
return this.clientConfig;
|
|
1492
|
+
}
|
|
1493
|
+
/** Subscribe to client config changes. Returns an unsubscribe function. */
|
|
1494
|
+
subscribeConfig(listener) {
|
|
1495
|
+
this.configListeners.add(listener);
|
|
1496
|
+
return () => {
|
|
1497
|
+
this.configListeners.delete(listener);
|
|
1498
|
+
};
|
|
1448
1499
|
}
|
|
1449
1500
|
/**
|
|
1450
|
-
*
|
|
1501
|
+
* Fetch client config from the backend.
|
|
1502
|
+
* Deduplicates concurrent calls and caches the result with a TTL.
|
|
1451
1503
|
*/
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
};
|
|
1456
|
-
|
|
1457
|
-
// src/flows/configs.ts
|
|
1458
|
-
var simpleSignInFlow = {
|
|
1459
|
-
name: "Simple Sign In",
|
|
1460
|
-
description: "Basic email/password sign-in",
|
|
1461
|
-
initialStep: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1462
|
-
allowedSteps: [
|
|
1463
|
-
"email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1464
|
-
"email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
|
|
1465
|
-
"email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
|
|
1466
|
-
"password_reset_request" /* PASSWORD_RESET_REQUEST */,
|
|
1467
|
-
"password_reset_sent" /* PASSWORD_RESET_SENT */,
|
|
1468
|
-
"success" /* SUCCESS */,
|
|
1469
|
-
"error" /* ERROR */
|
|
1470
|
-
],
|
|
1471
|
-
transitions: {
|
|
1472
|
-
["email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */]: {
|
|
1473
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1474
|
-
onError: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
|
|
1475
|
-
},
|
|
1476
|
-
["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
|
|
1477
|
-
onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
|
|
1478
|
-
onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
|
|
1479
|
-
},
|
|
1480
|
-
["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
|
|
1481
|
-
onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1482
|
-
onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
|
|
1483
|
-
},
|
|
1484
|
-
["password_reset_request" /* PASSWORD_RESET_REQUEST */]: {
|
|
1485
|
-
onSuccess: "password_reset_sent" /* PASSWORD_RESET_SENT */,
|
|
1486
|
-
onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
|
|
1487
|
-
},
|
|
1488
|
-
["password_reset_sent" /* PASSWORD_RESET_SENT */]: {
|
|
1489
|
-
onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
|
|
1504
|
+
async fetchClientConfig() {
|
|
1505
|
+
if (this.configFetchPromise) {
|
|
1506
|
+
return this.configFetchPromise;
|
|
1490
1507
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
"email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1499
|
-
"email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */,
|
|
1500
|
-
"email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
|
|
1501
|
-
"mfa_required" /* MFA_REQUIRED */,
|
|
1502
|
-
"mfa_select_method" /* MFA_SELECT_METHOD */,
|
|
1503
|
-
"mfa_verify" /* MFA_VERIFY */,
|
|
1504
|
-
"password_reset_request" /* PASSWORD_RESET_REQUEST */,
|
|
1505
|
-
"password_reset_sent" /* PASSWORD_RESET_SENT */,
|
|
1506
|
-
"success" /* SUCCESS */,
|
|
1507
|
-
"error" /* ERROR */
|
|
1508
|
-
],
|
|
1509
|
-
transitions: {
|
|
1510
|
-
["email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */]: {
|
|
1511
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1512
|
-
onError: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1513
|
-
conditions: [
|
|
1514
|
-
{
|
|
1515
|
-
when: (state) => state.mfaRequired === true,
|
|
1516
|
-
then: "mfa_required" /* MFA_REQUIRED */
|
|
1517
|
-
}
|
|
1518
|
-
]
|
|
1519
|
-
},
|
|
1520
|
-
["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
|
|
1521
|
-
onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */,
|
|
1522
|
-
onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
|
|
1523
|
-
},
|
|
1524
|
-
["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
|
|
1525
|
-
onSuccess: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */,
|
|
1526
|
-
onError: "email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */
|
|
1527
|
-
},
|
|
1528
|
-
["mfa_required" /* MFA_REQUIRED */]: {
|
|
1529
|
-
onSuccess: "mfa_verify" /* MFA_VERIFY */,
|
|
1530
|
-
conditions: [
|
|
1531
|
-
{
|
|
1532
|
-
when: (state) => (state.mfaMethods?.length || 0) > 1,
|
|
1533
|
-
then: "mfa_select_method" /* MFA_SELECT_METHOD */
|
|
1508
|
+
try {
|
|
1509
|
+
const cached = await this.storage.getItem(CONFIG_KEY);
|
|
1510
|
+
if (cached) {
|
|
1511
|
+
const { config, fetchedAt } = JSON.parse(cached);
|
|
1512
|
+
if (Date.now() - fetchedAt < CONFIG_TTL_MS) {
|
|
1513
|
+
this.setClientConfig(config);
|
|
1514
|
+
return config;
|
|
1534
1515
|
}
|
|
1535
|
-
|
|
1536
|
-
}
|
|
1537
|
-
["mfa_select_method" /* MFA_SELECT_METHOD */]: {
|
|
1538
|
-
onSuccess: "mfa_verify" /* MFA_VERIFY */,
|
|
1539
|
-
onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
|
|
1540
|
-
},
|
|
1541
|
-
["mfa_verify" /* MFA_VERIFY */]: {
|
|
1542
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1543
|
-
onError: "mfa_verify" /* MFA_VERIFY */,
|
|
1544
|
-
onBack: "mfa_select_method" /* MFA_SELECT_METHOD */
|
|
1545
|
-
},
|
|
1546
|
-
["password_reset_request" /* PASSWORD_RESET_REQUEST */]: {
|
|
1547
|
-
onSuccess: "password_reset_sent" /* PASSWORD_RESET_SENT */,
|
|
1548
|
-
onBack: "email_password_sign_in" /* EMAIL_PASSWORD_SIGN_IN */
|
|
1516
|
+
}
|
|
1517
|
+
} catch {
|
|
1549
1518
|
}
|
|
1519
|
+
this.configFetchPromise = this.client.fetchClientConfig(this.publishableKey).then(async (config) => {
|
|
1520
|
+
this.setClientConfig(config);
|
|
1521
|
+
try {
|
|
1522
|
+
await this.storage.setItem(
|
|
1523
|
+
CONFIG_KEY,
|
|
1524
|
+
JSON.stringify({ config, fetchedAt: Date.now() })
|
|
1525
|
+
);
|
|
1526
|
+
} catch {
|
|
1527
|
+
}
|
|
1528
|
+
return config;
|
|
1529
|
+
}).finally(() => {
|
|
1530
|
+
this.configFetchPromise = null;
|
|
1531
|
+
});
|
|
1532
|
+
return this.configFetchPromise;
|
|
1550
1533
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
"
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
]
|
|
1574
|
-
},
|
|
1575
|
-
["email_verification_required" /* EMAIL_VERIFICATION_REQUIRED */]: {
|
|
1576
|
-
onSuccess: "email_verification_sent" /* EMAIL_VERIFICATION_SENT */
|
|
1577
|
-
},
|
|
1578
|
-
["email_verification_sent" /* EMAIL_VERIFICATION_SENT */]: {
|
|
1579
|
-
onSuccess: "profile_complete" /* PROFILE_COMPLETE */
|
|
1580
|
-
},
|
|
1581
|
-
["profile_complete" /* PROFILE_COMPLETE */]: {
|
|
1582
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1583
|
-
onError: "profile_complete" /* PROFILE_COMPLETE */
|
|
1534
|
+
/** Tear down: clear timers and listeners. */
|
|
1535
|
+
destroy() {
|
|
1536
|
+
this.clearRefreshTimer();
|
|
1537
|
+
this.listeners.clear();
|
|
1538
|
+
this.configListeners.clear();
|
|
1539
|
+
}
|
|
1540
|
+
// ── Internals ─────────────────────────────────────
|
|
1541
|
+
async handleAuthResponse(user, session) {
|
|
1542
|
+
await this.persistSession(session);
|
|
1543
|
+
this.setState({ status: "authenticated", user, session });
|
|
1544
|
+
this.scheduleRefresh(session);
|
|
1545
|
+
}
|
|
1546
|
+
async refreshSession(refreshToken) {
|
|
1547
|
+
try {
|
|
1548
|
+
const newSession = await this.client.refresh(refreshToken);
|
|
1549
|
+
const user = await this.client.getMe(newSession.session_token);
|
|
1550
|
+
await this.persistSession(newSession);
|
|
1551
|
+
this.setState({ status: "authenticated", user, session: newSession });
|
|
1552
|
+
this.scheduleRefresh(newSession);
|
|
1553
|
+
} catch {
|
|
1554
|
+
await this.clearSession();
|
|
1555
|
+
this.setState({ status: "unauthenticated" });
|
|
1584
1556
|
}
|
|
1585
1557
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
},
|
|
1603
|
-
["magic_link_sent" /* MAGIC_LINK_SENT */]: {
|
|
1604
|
-
onSuccess: "magic_link_verify" /* MAGIC_LINK_VERIFY */
|
|
1605
|
-
},
|
|
1606
|
-
["magic_link_verify" /* MAGIC_LINK_VERIFY */]: {
|
|
1607
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1608
|
-
onError: "magic_link_request" /* MAGIC_LINK_REQUEST */
|
|
1558
|
+
scheduleRefresh(session) {
|
|
1559
|
+
this.clearRefreshTimer();
|
|
1560
|
+
const expiresAt = new Date(session.expires_at).getTime();
|
|
1561
|
+
const delay = expiresAt - Date.now() - REFRESH_BEFORE_MS;
|
|
1562
|
+
if (delay <= 0) {
|
|
1563
|
+
void this.refreshSession(session.refresh_token);
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
this.refreshTimer = setTimeout(() => {
|
|
1567
|
+
void this.refreshSession(session.refresh_token);
|
|
1568
|
+
}, delay);
|
|
1569
|
+
}
|
|
1570
|
+
clearRefreshTimer() {
|
|
1571
|
+
if (this.refreshTimer !== null) {
|
|
1572
|
+
clearTimeout(this.refreshTimer);
|
|
1573
|
+
this.refreshTimer = null;
|
|
1609
1574
|
}
|
|
1610
1575
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
onSuccess: "phone_verify" /* PHONE_VERIFY */,
|
|
1625
|
-
onError: "phone_request" /* PHONE_REQUEST */
|
|
1626
|
-
},
|
|
1627
|
-
["phone_verify" /* PHONE_VERIFY */]: {
|
|
1628
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1629
|
-
onError: "phone_verify" /* PHONE_VERIFY */,
|
|
1630
|
-
onBack: "phone_request" /* PHONE_REQUEST */
|
|
1576
|
+
async persistSession(session) {
|
|
1577
|
+
await this.storage.setItem(SESSION_KEY, JSON.stringify(session));
|
|
1578
|
+
}
|
|
1579
|
+
async clearSession() {
|
|
1580
|
+
await this.storage.removeItem(SESSION_KEY);
|
|
1581
|
+
}
|
|
1582
|
+
setClientConfig(config) {
|
|
1583
|
+
this.clientConfig = config;
|
|
1584
|
+
for (const listener of this.configListeners) {
|
|
1585
|
+
try {
|
|
1586
|
+
listener(config);
|
|
1587
|
+
} catch {
|
|
1588
|
+
}
|
|
1631
1589
|
}
|
|
1632
1590
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
"oauth_callback" /* OAUTH_CALLBACK */,
|
|
1641
|
-
"success" /* SUCCESS */,
|
|
1642
|
-
"error" /* ERROR */
|
|
1643
|
-
],
|
|
1644
|
-
transitions: {
|
|
1645
|
-
["oauth_select" /* OAUTH_SELECT */]: {
|
|
1646
|
-
onSuccess: "oauth_callback" /* OAUTH_CALLBACK */,
|
|
1647
|
-
onError: "oauth_select" /* OAUTH_SELECT */
|
|
1648
|
-
},
|
|
1649
|
-
["oauth_callback" /* OAUTH_CALLBACK */]: {
|
|
1650
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1651
|
-
onError: "oauth_select" /* OAUTH_SELECT */
|
|
1591
|
+
setState(newState) {
|
|
1592
|
+
this.state = newState;
|
|
1593
|
+
for (const listener of this.listeners) {
|
|
1594
|
+
try {
|
|
1595
|
+
listener(newState);
|
|
1596
|
+
} catch {
|
|
1597
|
+
}
|
|
1652
1598
|
}
|
|
1653
1599
|
}
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
},
|
|
1671
|
-
["password_reset_sent" /* PASSWORD_RESET_SENT */]: {
|
|
1672
|
-
onSuccess: "password_reset_confirm" /* PASSWORD_RESET_CONFIRM */
|
|
1673
|
-
},
|
|
1674
|
-
["password_reset_confirm" /* PASSWORD_RESET_CONFIRM */]: {
|
|
1675
|
-
onSuccess: "success" /* SUCCESS */,
|
|
1676
|
-
onError: "password_reset_confirm" /* PASSWORD_RESET_CONFIRM */
|
|
1600
|
+
handleError(err) {
|
|
1601
|
+
const message = err instanceof AuthClientError ? err.message : "An unexpected error occurred";
|
|
1602
|
+
const code = err instanceof AuthClientError ? err.code : void 0;
|
|
1603
|
+
if (code === 403 && message.toLowerCase().includes("mfa")) {
|
|
1604
|
+
const token = this.getSessionToken();
|
|
1605
|
+
if (token) {
|
|
1606
|
+
this.setState({
|
|
1607
|
+
status: "mfa_required",
|
|
1608
|
+
session: {
|
|
1609
|
+
session_token: token,
|
|
1610
|
+
refresh_token: "",
|
|
1611
|
+
expires_at: new Date(Date.now() + 3e5).toISOString()
|
|
1612
|
+
}
|
|
1613
|
+
});
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1677
1616
|
}
|
|
1617
|
+
this.setState({ status: "error", error: message });
|
|
1618
|
+
this.onError?.({ error: message, code });
|
|
1678
1619
|
}
|
|
1679
1620
|
};
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1621
|
+
|
|
1622
|
+
// src/webauthn.ts
|
|
1623
|
+
function base64urlToBuffer(base64url) {
|
|
1624
|
+
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
1625
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
1626
|
+
const binary = atob(padded);
|
|
1627
|
+
const bytes = new Uint8Array(binary.length);
|
|
1628
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1629
|
+
bytes[i] = binary.charCodeAt(i);
|
|
1630
|
+
}
|
|
1631
|
+
return bytes;
|
|
1632
|
+
}
|
|
1633
|
+
function bufferToBase64url(buffer) {
|
|
1634
|
+
const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
1635
|
+
let binary = "";
|
|
1636
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
1637
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1638
|
+
}
|
|
1639
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1640
|
+
}
|
|
1641
|
+
function prepareCreationOptions(options) {
|
|
1642
|
+
const publicKey = options.publicKey ?? options;
|
|
1643
|
+
const out = { ...publicKey };
|
|
1644
|
+
if (typeof out.challenge === "string") {
|
|
1645
|
+
out.challenge = base64urlToBuffer(out.challenge);
|
|
1646
|
+
}
|
|
1647
|
+
if (out.user && typeof out.user === "object") {
|
|
1648
|
+
const user = { ...out.user };
|
|
1649
|
+
if (typeof user.id === "string") {
|
|
1650
|
+
user.id = base64urlToBuffer(user.id);
|
|
1698
1651
|
}
|
|
1652
|
+
out.user = user;
|
|
1699
1653
|
}
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1654
|
+
if (Array.isArray(out.excludeCredentials)) {
|
|
1655
|
+
out.excludeCredentials = out.excludeCredentials.map((c) => {
|
|
1656
|
+
if (typeof c.id === "string") {
|
|
1657
|
+
return { ...c, id: base64urlToBuffer(c.id) };
|
|
1658
|
+
}
|
|
1659
|
+
return c;
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1662
|
+
return out;
|
|
1663
|
+
}
|
|
1664
|
+
function prepareRequestOptions(options) {
|
|
1665
|
+
const publicKey = options.publicKey ?? options;
|
|
1666
|
+
const out = { ...publicKey };
|
|
1667
|
+
if (typeof out.challenge === "string") {
|
|
1668
|
+
out.challenge = base64urlToBuffer(out.challenge);
|
|
1669
|
+
}
|
|
1670
|
+
if (Array.isArray(out.allowCredentials)) {
|
|
1671
|
+
out.allowCredentials = out.allowCredentials.map((c) => {
|
|
1672
|
+
if (typeof c.id === "string") {
|
|
1673
|
+
return { ...c, id: base64urlToBuffer(c.id) };
|
|
1674
|
+
}
|
|
1675
|
+
return c;
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
return out;
|
|
1679
|
+
}
|
|
1680
|
+
function serializeCredential(credential) {
|
|
1681
|
+
const cred = credential;
|
|
1682
|
+
const response = cred.response;
|
|
1683
|
+
const result = {
|
|
1684
|
+
id: cred.id,
|
|
1685
|
+
rawId: bufferToBase64url(cred.rawId),
|
|
1686
|
+
type: cred.type,
|
|
1687
|
+
response: {}
|
|
1688
|
+
};
|
|
1689
|
+
const serializedResponse = {
|
|
1690
|
+
clientDataJSON: bufferToBase64url(response.clientDataJSON)
|
|
1691
|
+
};
|
|
1692
|
+
if ("attestationObject" in response) {
|
|
1693
|
+
const attestation = response;
|
|
1694
|
+
serializedResponse.attestationObject = bufferToBase64url(
|
|
1695
|
+
attestation.attestationObject
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
if ("authenticatorData" in response) {
|
|
1699
|
+
const assertion = response;
|
|
1700
|
+
serializedResponse.authenticatorData = bufferToBase64url(
|
|
1701
|
+
assertion.authenticatorData
|
|
1702
|
+
);
|
|
1703
|
+
serializedResponse.signature = bufferToBase64url(assertion.signature);
|
|
1704
|
+
if (assertion.userHandle) {
|
|
1705
|
+
serializedResponse.userHandle = bufferToBase64url(assertion.userHandle);
|
|
1706
|
+
}
|
|
1721
1707
|
}
|
|
1708
|
+
result.response = serializedResponse;
|
|
1709
|
+
if (cred.authenticatorAttachment) {
|
|
1710
|
+
result.authenticatorAttachment = cred.authenticatorAttachment;
|
|
1711
|
+
}
|
|
1712
|
+
return result;
|
|
1722
1713
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1714
|
+
export {
|
|
1715
|
+
AuthClient2 as AuthClient,
|
|
1716
|
+
AuthClientError,
|
|
1717
|
+
AuthManager,
|
|
1718
|
+
base64urlToBuffer,
|
|
1719
|
+
bufferToBase64url,
|
|
1720
|
+
prepareCreationOptions,
|
|
1721
|
+
prepareRequestOptions,
|
|
1722
|
+
serializeCredential
|
|
1732
1723
|
};
|
|
1733
|
-
|
|
1734
|
-
exports.AuthClient = AuthClient;
|
|
1735
|
-
exports.AuthError = AuthError;
|
|
1736
|
-
exports.AuthErrorType = AuthErrorType;
|
|
1737
|
-
exports.AuthState = AuthState;
|
|
1738
|
-
exports.BaseAuthProvider = BaseAuthProvider;
|
|
1739
|
-
exports.FlowAction = FlowAction;
|
|
1740
|
-
exports.FlowConfigType = FlowConfigType;
|
|
1741
|
-
exports.FlowEngine = FlowEngine;
|
|
1742
|
-
exports.FlowStep = FlowStep;
|
|
1743
|
-
exports.LocalStorageAdapter = LocalStorageAdapter;
|
|
1744
|
-
exports.MemoryStorageAdapter = MemoryStorageAdapter;
|
|
1745
|
-
exports.OAuthProvider = OAuthProvider;
|
|
1746
|
-
exports.Observable = Observable;
|
|
1747
|
-
exports.SessionStorageAdapter = SessionStorageAdapter;
|
|
1748
|
-
exports.TokenManager = TokenManager;
|
|
1749
|
-
exports.TwoFactorMethod = TwoFactorMethod;
|
|
1750
|
-
exports.completeSignUpFlow = completeSignUpFlow;
|
|
1751
|
-
exports.createAuthError = createAuthError;
|
|
1752
|
-
exports.createLocale = createLocale;
|
|
1753
|
-
exports.defaultLocale = defaultLocale;
|
|
1754
|
-
exports.emailVerificationFlow = emailVerificationFlow;
|
|
1755
|
-
exports.extractCookiesFromHeaders = extractCookiesFromHeaders;
|
|
1756
|
-
exports.getFlowConfig = getFlowConfig;
|
|
1757
|
-
exports.interpolate = interpolate;
|
|
1758
|
-
exports.isAuthError = isAuthError;
|
|
1759
|
-
exports.isMFARequiredError = isMFARequiredError;
|
|
1760
|
-
exports.isNetworkError = isNetworkError;
|
|
1761
|
-
exports.isUnauthenticatedError = isUnauthenticatedError;
|
|
1762
|
-
exports.magicLinkFlow = magicLinkFlow;
|
|
1763
|
-
exports.oauthSignInFlow = oauthSignInFlow;
|
|
1764
|
-
exports.parseCookie = parseCookie;
|
|
1765
|
-
exports.parseCookieOptions = parseCookieOptions;
|
|
1766
|
-
exports.passwordResetFlow = passwordResetFlow;
|
|
1767
|
-
exports.phoneAuthFlow = phoneAuthFlow;
|
|
1768
|
-
exports.predefinedFlows = predefinedFlows;
|
|
1769
|
-
exports.serializeCookie = serializeCookie;
|
|
1770
|
-
exports.serializeCookies = serializeCookies;
|
|
1771
|
-
exports.signInWithMFAFlow = signInWithMFAFlow;
|
|
1772
|
-
exports.simpleSignInFlow = simpleSignInFlow;
|
|
1773
|
-
exports.toAuthError = toAuthError;
|
|
1774
|
-
exports.validate2FACode = validate2FACode;
|
|
1775
|
-
exports.validateEmail = validateEmail;
|
|
1776
|
-
exports.validatePassword = validatePassword;
|
|
1777
|
-
exports.validatePhone = validatePhone;
|
|
1778
|
-
exports.validateRequired = validateRequired;
|
|
1779
|
-
exports.validateUsername = validateUsername;
|
|
1780
|
-
//# sourceMappingURL=index.js.map
|
|
1781
1724
|
//# sourceMappingURL=index.js.map
|