cauthy-auth 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/client.d.mts +86 -1
- package/dist/client.d.ts +86 -1
- package/dist/client.js +21 -7
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +21 -7
- package/dist/client.mjs.map +1 -1
- package/dist/index.js +81 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +81 -2
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.d.mts +103 -0
- package/dist/mcp.d.ts +103 -0
- package/dist/mcp.js +218 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcp.mjs +191 -0
- package/dist/mcp.mjs.map +1 -0
- package/dist/react.d.mts +104 -1
- package/dist/react.d.ts +104 -1
- package/dist/react.js +259 -12
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +259 -12
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +5 -0
- package/dist/svelte.js +21 -7
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +21 -7
- package/dist/svelte.mjs.map +1 -1
- package/dist/vue.js +21 -7
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +21 -7
- package/dist/vue.mjs.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -123,6 +123,14 @@ const who = await verifyToken(request) // throws CauthyTokenError: answer 401
|
|
|
123
123
|
who.userId, who.tenantId, who.roles
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
An MCP server (or an API) that AI agents use as one of your people: Claude, Cursor and others find Cauthy from it, the person signs in and allows the agent, and the token works on that server alone.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { mcpAuth } from 'cauthy-auth/mcp'
|
|
130
|
+
const auth = mcpAuth({ resource: 'https://mcp.example.com/mcp', scopes: ['books:read'] })
|
|
131
|
+
app.use(auth.middleware()) // or auth.protect(handler) for Request/Response
|
|
132
|
+
```
|
|
133
|
+
|
|
126
134
|
The full guide is in Cauthy's documentation, under "Auth SDK".
|
|
127
135
|
|
|
128
136
|
## License
|
package/dist/client.d.mts
CHANGED
|
@@ -93,6 +93,13 @@ interface AuthMethods {
|
|
|
93
93
|
* page that cannot, or a browser that refuses to here, sends the person.
|
|
94
94
|
*/
|
|
95
95
|
passkeyOnCauthy: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The workspace's Cloudflare Turnstile site key, when it asks for the
|
|
98
|
+
* challenge: signing in, creating an account, and asking for a sign-in link
|
|
99
|
+
* or a new password then take its answer (`captchaToken`). The ready-made
|
|
100
|
+
* forms show it themselves.
|
|
101
|
+
*/
|
|
102
|
+
captchaSiteKey?: string;
|
|
96
103
|
}
|
|
97
104
|
/** A passkey of the signed-in account. Moments are UTC. */
|
|
98
105
|
interface Passkey {
|
|
@@ -114,6 +121,26 @@ interface Account {
|
|
|
114
121
|
mfaEnabled: boolean;
|
|
115
122
|
}
|
|
116
123
|
/** Somewhere the person is signed in. Moments are UTC. */
|
|
124
|
+
/** An AI agent the person allowed to act for them on one of the workspace's servers. */
|
|
125
|
+
interface ConnectedAgent {
|
|
126
|
+
id: string;
|
|
127
|
+
/** The name the agent gave itself (Claude, Cursor…): not checked by anyone. */
|
|
128
|
+
name: string;
|
|
129
|
+
/** Where the agent receives its access: the one thing about it that is sure. */
|
|
130
|
+
redirectHost: string;
|
|
131
|
+
resource: {
|
|
132
|
+
name: string;
|
|
133
|
+
uri: string;
|
|
134
|
+
};
|
|
135
|
+
/** What the person allowed it, in their words. */
|
|
136
|
+
scopes: {
|
|
137
|
+
name: string;
|
|
138
|
+
description: string;
|
|
139
|
+
}[];
|
|
140
|
+
/** UTC, ISO 8601. */
|
|
141
|
+
connectedAt: string;
|
|
142
|
+
lastUsedAt: string;
|
|
143
|
+
}
|
|
117
144
|
interface AccountSession {
|
|
118
145
|
/** "Mac · Chrome", or "" when the browser did not say. */
|
|
119
146
|
device: string;
|
|
@@ -134,6 +161,17 @@ interface LinkedIdentity {
|
|
|
134
161
|
/** When it was linked, in UTC (ISO 8601). */
|
|
135
162
|
linkedAt: string;
|
|
136
163
|
}
|
|
164
|
+
/** How an account takes its second step. */
|
|
165
|
+
interface SecondStep {
|
|
166
|
+
totp: boolean;
|
|
167
|
+
/** The phone codes are sent to, masked (`+57 ••• ••• 4567`). */
|
|
168
|
+
phone: {
|
|
169
|
+
number: string;
|
|
170
|
+
channel: string;
|
|
171
|
+
} | null;
|
|
172
|
+
/** The ways the workspace sends codes to phones. */
|
|
173
|
+
phoneChannels: string[];
|
|
174
|
+
}
|
|
137
175
|
interface AccountClient {
|
|
138
176
|
/** The account, or null when nobody is signed in. */
|
|
139
177
|
get(): Promise<Account | null>;
|
|
@@ -172,6 +210,30 @@ interface AccountClient {
|
|
|
172
210
|
}): Promise<AuthResult<'renewed', {
|
|
173
211
|
recoveryCodes: string[];
|
|
174
212
|
}>>;
|
|
213
|
+
/**
|
|
214
|
+
* How the account takes its second step: an authenticator app, a phone
|
|
215
|
+
* (masked), and the ways the workspace sends codes to phones (`sms`,
|
|
216
|
+
* `whatsapp`; none when it has no Twilio account for it).
|
|
217
|
+
*/
|
|
218
|
+
factors(): Promise<SecondStep | null>;
|
|
219
|
+
/** Adds a phone as the second step: a code is sent to it, for `verifyPhone`. */
|
|
220
|
+
addPhone(form: {
|
|
221
|
+
phone: string;
|
|
222
|
+
channel: 'sms' | 'whatsapp';
|
|
223
|
+
password: string;
|
|
224
|
+
}): Promise<AuthResult<'sent', {
|
|
225
|
+
sentTo: string;
|
|
226
|
+
channel: string;
|
|
227
|
+
}>>;
|
|
228
|
+
/** Proves the phone with the code it received. `recoveryCodes` come with a first second step, shown this once. */
|
|
229
|
+
verifyPhone(form: {
|
|
230
|
+
code: string;
|
|
231
|
+
}): Promise<AuthResult<'enabled', {
|
|
232
|
+
recoveryCodes: string[];
|
|
233
|
+
}>>;
|
|
234
|
+
removePhone(form: {
|
|
235
|
+
password: string;
|
|
236
|
+
}): Promise<AuthResult<'removed'>>;
|
|
175
237
|
};
|
|
176
238
|
/**
|
|
177
239
|
* Asks to sign in with another address. Nothing changes yet: the new address
|
|
@@ -205,6 +267,12 @@ interface AccountClient {
|
|
|
205
267
|
sessions(): Promise<AccountSession[]>;
|
|
206
268
|
/** Signs the account out everywhere, here too. */
|
|
207
269
|
signOutEverywhere(): Promise<AuthResult<'signed_out'>>;
|
|
270
|
+
/** The AI agents the person connected. */
|
|
271
|
+
agents(): Promise<ConnectedAgent[]>;
|
|
272
|
+
/** Disconnects an agent: it loses its access within minutes. */
|
|
273
|
+
disconnectAgent(id: string): Promise<AuthResult<'disconnected', {
|
|
274
|
+
id: string;
|
|
275
|
+
}>>;
|
|
208
276
|
/** The account's passkeys. */
|
|
209
277
|
passkeys(): Promise<Passkey[]>;
|
|
210
278
|
/**
|
|
@@ -228,6 +296,7 @@ interface AuthClient {
|
|
|
228
296
|
email(form: {
|
|
229
297
|
email: string;
|
|
230
298
|
password: string;
|
|
299
|
+
captchaToken?: string;
|
|
231
300
|
}): Promise<AuthResult<'signed_in', {
|
|
232
301
|
session: PublicSession;
|
|
233
302
|
}> | AuthResult<'mfa_required'>>;
|
|
@@ -237,9 +306,23 @@ interface AuthClient {
|
|
|
237
306
|
}): Promise<AuthResult<'signed_in', {
|
|
238
307
|
session: PublicSession;
|
|
239
308
|
}>>;
|
|
309
|
+
/** While the second step is asked for: whether the account has an authenticator app, and the phone (masked) a code can be sent to. */
|
|
310
|
+
mfaMethods(): Promise<AuthResult<'ok', {
|
|
311
|
+
totp: boolean;
|
|
312
|
+
phone: {
|
|
313
|
+
number: string;
|
|
314
|
+
channel: string;
|
|
315
|
+
} | null;
|
|
316
|
+
}>>;
|
|
317
|
+
/** Sends a code to the account's phone, by SMS or WhatsApp; `mfa` takes it. A few per sign-in. */
|
|
318
|
+
mfaSendCode(): Promise<AuthResult<'sent', {
|
|
319
|
+
sentTo: string;
|
|
320
|
+
channel: string;
|
|
321
|
+
}>>;
|
|
240
322
|
/** Mails a link that signs the person in. The answer is the same whether or not the address has an account. */
|
|
241
323
|
magicLink(form: {
|
|
242
324
|
email: string;
|
|
325
|
+
captchaToken?: string;
|
|
243
326
|
}): Promise<AuthResult<'sent'>>;
|
|
244
327
|
/** Signs in with the token the mailed link opened the page with (`ml_token`). */
|
|
245
328
|
magicLinkVerify(form: {
|
|
@@ -315,6 +398,7 @@ interface AuthClient {
|
|
|
315
398
|
email: string;
|
|
316
399
|
password: string;
|
|
317
400
|
name?: string;
|
|
401
|
+
captchaToken?: string;
|
|
318
402
|
}): Promise<AuthResult<'signed_in', {
|
|
319
403
|
session: PublicSession;
|
|
320
404
|
}> | AuthResult<'verification_required', {
|
|
@@ -324,6 +408,7 @@ interface AuthClient {
|
|
|
324
408
|
/** Mails a link to choose a new password. The answer is the same whether or not the address has an account. */
|
|
325
409
|
forgotPassword(form: {
|
|
326
410
|
email: string;
|
|
411
|
+
captchaToken?: string;
|
|
327
412
|
}): Promise<AuthResult<'sent'>>;
|
|
328
413
|
/** Sets the new password, with the token the mailed link opened the page with (`token`). */
|
|
329
414
|
resetPassword(form: {
|
|
@@ -360,4 +445,4 @@ interface AuthClientOptions {
|
|
|
360
445
|
}
|
|
361
446
|
declare function createAuthClient(options?: AuthClientOptions): AuthClient;
|
|
362
447
|
|
|
363
|
-
export { type Account, type AccountClient, type AccountSession, type AuthClient, type AuthClientOptions, type AuthError, AuthField, type AuthMethods, type AuthResult, type LinkedIdentity, type Passkey, type SessionState, type SessionStore, type SessionStoreOptions, canAutofillPasskeys, canUsePasskeys, createAuthClient, createSessionStore };
|
|
448
|
+
export { type Account, type AccountClient, type AccountSession, type AuthClient, type AuthClientOptions, type AuthError, AuthField, type AuthMethods, type AuthResult, type ConnectedAgent, type LinkedIdentity, type Passkey, type SecondStep, type SessionState, type SessionStore, type SessionStoreOptions, canAutofillPasskeys, canUsePasskeys, createAuthClient, createSessionStore };
|
package/dist/client.d.ts
CHANGED
|
@@ -93,6 +93,13 @@ interface AuthMethods {
|
|
|
93
93
|
* page that cannot, or a browser that refuses to here, sends the person.
|
|
94
94
|
*/
|
|
95
95
|
passkeyOnCauthy: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The workspace's Cloudflare Turnstile site key, when it asks for the
|
|
98
|
+
* challenge: signing in, creating an account, and asking for a sign-in link
|
|
99
|
+
* or a new password then take its answer (`captchaToken`). The ready-made
|
|
100
|
+
* forms show it themselves.
|
|
101
|
+
*/
|
|
102
|
+
captchaSiteKey?: string;
|
|
96
103
|
}
|
|
97
104
|
/** A passkey of the signed-in account. Moments are UTC. */
|
|
98
105
|
interface Passkey {
|
|
@@ -114,6 +121,26 @@ interface Account {
|
|
|
114
121
|
mfaEnabled: boolean;
|
|
115
122
|
}
|
|
116
123
|
/** Somewhere the person is signed in. Moments are UTC. */
|
|
124
|
+
/** An AI agent the person allowed to act for them on one of the workspace's servers. */
|
|
125
|
+
interface ConnectedAgent {
|
|
126
|
+
id: string;
|
|
127
|
+
/** The name the agent gave itself (Claude, Cursor…): not checked by anyone. */
|
|
128
|
+
name: string;
|
|
129
|
+
/** Where the agent receives its access: the one thing about it that is sure. */
|
|
130
|
+
redirectHost: string;
|
|
131
|
+
resource: {
|
|
132
|
+
name: string;
|
|
133
|
+
uri: string;
|
|
134
|
+
};
|
|
135
|
+
/** What the person allowed it, in their words. */
|
|
136
|
+
scopes: {
|
|
137
|
+
name: string;
|
|
138
|
+
description: string;
|
|
139
|
+
}[];
|
|
140
|
+
/** UTC, ISO 8601. */
|
|
141
|
+
connectedAt: string;
|
|
142
|
+
lastUsedAt: string;
|
|
143
|
+
}
|
|
117
144
|
interface AccountSession {
|
|
118
145
|
/** "Mac · Chrome", or "" when the browser did not say. */
|
|
119
146
|
device: string;
|
|
@@ -134,6 +161,17 @@ interface LinkedIdentity {
|
|
|
134
161
|
/** When it was linked, in UTC (ISO 8601). */
|
|
135
162
|
linkedAt: string;
|
|
136
163
|
}
|
|
164
|
+
/** How an account takes its second step. */
|
|
165
|
+
interface SecondStep {
|
|
166
|
+
totp: boolean;
|
|
167
|
+
/** The phone codes are sent to, masked (`+57 ••• ••• 4567`). */
|
|
168
|
+
phone: {
|
|
169
|
+
number: string;
|
|
170
|
+
channel: string;
|
|
171
|
+
} | null;
|
|
172
|
+
/** The ways the workspace sends codes to phones. */
|
|
173
|
+
phoneChannels: string[];
|
|
174
|
+
}
|
|
137
175
|
interface AccountClient {
|
|
138
176
|
/** The account, or null when nobody is signed in. */
|
|
139
177
|
get(): Promise<Account | null>;
|
|
@@ -172,6 +210,30 @@ interface AccountClient {
|
|
|
172
210
|
}): Promise<AuthResult<'renewed', {
|
|
173
211
|
recoveryCodes: string[];
|
|
174
212
|
}>>;
|
|
213
|
+
/**
|
|
214
|
+
* How the account takes its second step: an authenticator app, a phone
|
|
215
|
+
* (masked), and the ways the workspace sends codes to phones (`sms`,
|
|
216
|
+
* `whatsapp`; none when it has no Twilio account for it).
|
|
217
|
+
*/
|
|
218
|
+
factors(): Promise<SecondStep | null>;
|
|
219
|
+
/** Adds a phone as the second step: a code is sent to it, for `verifyPhone`. */
|
|
220
|
+
addPhone(form: {
|
|
221
|
+
phone: string;
|
|
222
|
+
channel: 'sms' | 'whatsapp';
|
|
223
|
+
password: string;
|
|
224
|
+
}): Promise<AuthResult<'sent', {
|
|
225
|
+
sentTo: string;
|
|
226
|
+
channel: string;
|
|
227
|
+
}>>;
|
|
228
|
+
/** Proves the phone with the code it received. `recoveryCodes` come with a first second step, shown this once. */
|
|
229
|
+
verifyPhone(form: {
|
|
230
|
+
code: string;
|
|
231
|
+
}): Promise<AuthResult<'enabled', {
|
|
232
|
+
recoveryCodes: string[];
|
|
233
|
+
}>>;
|
|
234
|
+
removePhone(form: {
|
|
235
|
+
password: string;
|
|
236
|
+
}): Promise<AuthResult<'removed'>>;
|
|
175
237
|
};
|
|
176
238
|
/**
|
|
177
239
|
* Asks to sign in with another address. Nothing changes yet: the new address
|
|
@@ -205,6 +267,12 @@ interface AccountClient {
|
|
|
205
267
|
sessions(): Promise<AccountSession[]>;
|
|
206
268
|
/** Signs the account out everywhere, here too. */
|
|
207
269
|
signOutEverywhere(): Promise<AuthResult<'signed_out'>>;
|
|
270
|
+
/** The AI agents the person connected. */
|
|
271
|
+
agents(): Promise<ConnectedAgent[]>;
|
|
272
|
+
/** Disconnects an agent: it loses its access within minutes. */
|
|
273
|
+
disconnectAgent(id: string): Promise<AuthResult<'disconnected', {
|
|
274
|
+
id: string;
|
|
275
|
+
}>>;
|
|
208
276
|
/** The account's passkeys. */
|
|
209
277
|
passkeys(): Promise<Passkey[]>;
|
|
210
278
|
/**
|
|
@@ -228,6 +296,7 @@ interface AuthClient {
|
|
|
228
296
|
email(form: {
|
|
229
297
|
email: string;
|
|
230
298
|
password: string;
|
|
299
|
+
captchaToken?: string;
|
|
231
300
|
}): Promise<AuthResult<'signed_in', {
|
|
232
301
|
session: PublicSession;
|
|
233
302
|
}> | AuthResult<'mfa_required'>>;
|
|
@@ -237,9 +306,23 @@ interface AuthClient {
|
|
|
237
306
|
}): Promise<AuthResult<'signed_in', {
|
|
238
307
|
session: PublicSession;
|
|
239
308
|
}>>;
|
|
309
|
+
/** While the second step is asked for: whether the account has an authenticator app, and the phone (masked) a code can be sent to. */
|
|
310
|
+
mfaMethods(): Promise<AuthResult<'ok', {
|
|
311
|
+
totp: boolean;
|
|
312
|
+
phone: {
|
|
313
|
+
number: string;
|
|
314
|
+
channel: string;
|
|
315
|
+
} | null;
|
|
316
|
+
}>>;
|
|
317
|
+
/** Sends a code to the account's phone, by SMS or WhatsApp; `mfa` takes it. A few per sign-in. */
|
|
318
|
+
mfaSendCode(): Promise<AuthResult<'sent', {
|
|
319
|
+
sentTo: string;
|
|
320
|
+
channel: string;
|
|
321
|
+
}>>;
|
|
240
322
|
/** Mails a link that signs the person in. The answer is the same whether or not the address has an account. */
|
|
241
323
|
magicLink(form: {
|
|
242
324
|
email: string;
|
|
325
|
+
captchaToken?: string;
|
|
243
326
|
}): Promise<AuthResult<'sent'>>;
|
|
244
327
|
/** Signs in with the token the mailed link opened the page with (`ml_token`). */
|
|
245
328
|
magicLinkVerify(form: {
|
|
@@ -315,6 +398,7 @@ interface AuthClient {
|
|
|
315
398
|
email: string;
|
|
316
399
|
password: string;
|
|
317
400
|
name?: string;
|
|
401
|
+
captchaToken?: string;
|
|
318
402
|
}): Promise<AuthResult<'signed_in', {
|
|
319
403
|
session: PublicSession;
|
|
320
404
|
}> | AuthResult<'verification_required', {
|
|
@@ -324,6 +408,7 @@ interface AuthClient {
|
|
|
324
408
|
/** Mails a link to choose a new password. The answer is the same whether or not the address has an account. */
|
|
325
409
|
forgotPassword(form: {
|
|
326
410
|
email: string;
|
|
411
|
+
captchaToken?: string;
|
|
327
412
|
}): Promise<AuthResult<'sent'>>;
|
|
328
413
|
/** Sets the new password, with the token the mailed link opened the page with (`token`). */
|
|
329
414
|
resetPassword(form: {
|
|
@@ -360,4 +445,4 @@ interface AuthClientOptions {
|
|
|
360
445
|
}
|
|
361
446
|
declare function createAuthClient(options?: AuthClientOptions): AuthClient;
|
|
362
447
|
|
|
363
|
-
export { type Account, type AccountClient, type AccountSession, type AuthClient, type AuthClientOptions, type AuthError, AuthField, type AuthMethods, type AuthResult, type LinkedIdentity, type Passkey, type SessionState, type SessionStore, type SessionStoreOptions, canAutofillPasskeys, canUsePasskeys, createAuthClient, createSessionStore };
|
|
448
|
+
export { type Account, type AccountClient, type AccountSession, type AuthClient, type AuthClientOptions, type AuthError, AuthField, type AuthMethods, type AuthResult, type ConnectedAgent, type LinkedIdentity, type Passkey, type SecondStep, type SessionState, type SessionStore, type SessionStoreOptions, canAutofillPasskeys, canUsePasskeys, createAuthClient, createSessionStore };
|
package/dist/client.js
CHANGED
|
@@ -317,13 +317,13 @@ function createAuthClient(options = {}) {
|
|
|
317
317
|
const said = typeof options.locale === "function" ? options.locale() : options.locale;
|
|
318
318
|
return (said ?? (typeof document === "undefined" ? "" : document.documentElement?.lang) ?? "").trim();
|
|
319
319
|
};
|
|
320
|
-
async function post(path, form, bad) {
|
|
320
|
+
async function post(path, form, bad, captchaToken) {
|
|
321
321
|
if (bad) return { ok: false, error: { code: bad.code, message: bad.message, field: bad.field } };
|
|
322
322
|
try {
|
|
323
323
|
const res = await doFetch(`${base}${path}`, {
|
|
324
324
|
method: "POST",
|
|
325
325
|
credentials: "same-origin",
|
|
326
|
-
headers: { "content-type": "application/json", accept: "application/json", ...locale() ? { "x-cauthy-locale": locale() } : {} },
|
|
326
|
+
headers: { "content-type": "application/json", accept: "application/json", ...locale() ? { "x-cauthy-locale": locale() } : {}, ...captchaToken ? { "x-cauthy-captcha": captchaToken } : {} },
|
|
327
327
|
body: JSON.stringify(form)
|
|
328
328
|
});
|
|
329
329
|
const body = await res.json().catch(() => null);
|
|
@@ -375,9 +375,11 @@ function createAuthClient(options = {}) {
|
|
|
375
375
|
}
|
|
376
376
|
return {
|
|
377
377
|
signIn: {
|
|
378
|
-
email: (f) => post("/sign-in/email", { email: f.email, password: f.password }, firstProblem(checkEmail(f.email), checkPassword(f.password))),
|
|
378
|
+
email: (f) => post("/sign-in/email", { email: f.email, password: f.password }, firstProblem(checkEmail(f.email), checkPassword(f.password)), f.captchaToken),
|
|
379
379
|
mfa: (f) => post("/sign-in/mfa", { code: f.code }, checkCode(f.code)),
|
|
380
|
-
|
|
380
|
+
mfaMethods: () => post("/sign-in/mfa/methods", {}, null),
|
|
381
|
+
mfaSendCode: () => post("/sign-in/mfa/send", {}, null),
|
|
382
|
+
magicLink: (f) => post("/sign-in/magic-link", { email: f.email }, checkEmail(f.email), f.captchaToken),
|
|
381
383
|
magicLinkVerify: (f) => post("/sign-in/magic-link/verify", { token: f.token }, null),
|
|
382
384
|
emailCode: (f) => post("/sign-in/email-code", { code: f.code }, checkCode(f.code)),
|
|
383
385
|
passkeyUrl,
|
|
@@ -458,9 +460,9 @@ function createAuthClient(options = {}) {
|
|
|
458
460
|
}
|
|
459
461
|
},
|
|
460
462
|
signUp: {
|
|
461
|
-
email: (f) => post("/sign-up/email", { email: f.email, password: f.password, name: f.name }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password)))
|
|
463
|
+
email: (f) => post("/sign-up/email", { email: f.email, password: f.password, name: f.name }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password)), f.captchaToken)
|
|
462
464
|
},
|
|
463
|
-
forgotPassword: (f) => post("/forgot-password", { email: f.email }, checkEmail(f.email)),
|
|
465
|
+
forgotPassword: (f) => post("/forgot-password", { email: f.email }, checkEmail(f.email), f.captchaToken),
|
|
464
466
|
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password)),
|
|
465
467
|
verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
|
|
466
468
|
signOut: () => post("/sign-out", {}, null),
|
|
@@ -478,7 +480,14 @@ function createAuthClient(options = {}) {
|
|
|
478
480
|
setup: (f) => post("/me/mfa/setup", { password: f.password }, null),
|
|
479
481
|
verify: (f) => post("/me/mfa/verify", { code: f.code }, checkCode(f.code)),
|
|
480
482
|
disable: (f) => post("/me/mfa/disable", { password: f.password }, null),
|
|
481
|
-
recoveryCodes: (f) => post("/me/mfa/recovery-codes", { password: f.password }, null)
|
|
483
|
+
recoveryCodes: (f) => post("/me/mfa/recovery-codes", { password: f.password }, null),
|
|
484
|
+
async factors() {
|
|
485
|
+
const body = await read("/me/mfa/factors");
|
|
486
|
+
return body && typeof body.totp === "boolean" ? body : null;
|
|
487
|
+
},
|
|
488
|
+
addPhone: (f) => post("/me/mfa/phone", { phone: f.phone, channel: f.channel, password: f.password }, null),
|
|
489
|
+
verifyPhone: (f) => post("/me/mfa/phone/verify", { code: f.code }, checkCode(f.code)),
|
|
490
|
+
removePhone: (f) => post("/me/mfa/phone/remove", { password: f.password }, null)
|
|
482
491
|
},
|
|
483
492
|
changeEmail: (f) => post("/me/email", { email: f.email, password: f.password }, checkEmail(f.email)),
|
|
484
493
|
async identities() {
|
|
@@ -495,6 +504,11 @@ function createAuthClient(options = {}) {
|
|
|
495
504
|
return body && Array.isArray(body.sessions) ? body.sessions : [];
|
|
496
505
|
},
|
|
497
506
|
signOutEverywhere: () => post("/me/sessions/end", {}, null),
|
|
507
|
+
async agents() {
|
|
508
|
+
const body = await read("/me/agents");
|
|
509
|
+
return body && Array.isArray(body.agents) ? body.agents : [];
|
|
510
|
+
},
|
|
511
|
+
disconnectAgent: (id) => post("/me/agents/disconnect", { id }, null),
|
|
498
512
|
async passkeys() {
|
|
499
513
|
const body = await read("/me/passkeys");
|
|
500
514
|
return body && Array.isArray(body.passkeys) ? body.passkeys : [];
|