@proveanything/smartlinks 1.15.11 → 1.15.14
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/api/authKit.d.ts +110 -13
- package/dist/api/authKit.js +172 -18
- package/dist/docs/API_SUMMARY.md +148 -20
- package/dist/docs/analytics-metadata-conventions.md +4 -0
- package/dist/docs/analytics.md +37 -3
- package/dist/docs/auth-kit.md +132 -0
- package/dist/openapi.yaml +435 -2
- package/dist/types/analytics.d.ts +37 -2
- package/dist/types/authKit.d.ts +99 -0
- package/dist/types/collection.d.ts +23 -0
- package/docs/API_SUMMARY.md +148 -20
- package/docs/analytics-metadata-conventions.md +4 -0
- package/docs/analytics.md +37 -3
- package/docs/auth-kit.md +132 -0
- package/openapi.yaml +435 -2
- package/package.json +1 -1
package/dist/api/authKit.d.ts
CHANGED
|
@@ -1,20 +1,47 @@
|
|
|
1
|
-
import type { AuthLoginResponse, AppleLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse } from "../types/authKit";
|
|
1
|
+
import type { AuthLoginResponse, AppleLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, MfaChallengeSendResponse, MfaFinalizeResponse, MfaEnrollSendResponse, MfaEnrolledResponse, MfaFactorsResponse, TrustedDevice } from "../types/authKit";
|
|
2
2
|
/**
|
|
3
3
|
* Namespace containing helper functions for the new AuthKit API.
|
|
4
4
|
* Legacy collection-based authKit helpers retained (marked as *Legacy*).
|
|
5
5
|
*/
|
|
6
6
|
export declare namespace authKit {
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Login with email + password (public).
|
|
9
|
+
*
|
|
10
|
+
* When the client's MFA policy requires a step-up, the server returns **403
|
|
11
|
+
* `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with
|
|
12
|
+
* `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in
|
|
13
|
+
* `err.details` (see {@link MfaRequiredDetails}). Route the caller to
|
|
14
|
+
* {@link mfaChallengeSend} on that error; this method's return type is unchanged.
|
|
15
|
+
*
|
|
16
|
+
* @param trustedDeviceToken - Optional. If a previous MFA challenge on this device
|
|
17
|
+
* returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with
|
|
18
|
+
* `trustDevice: true`), pass it here to skip the challenge entirely as long as it's
|
|
19
|
+
* still valid. If it's revoked/expired, the server silently falls back to requiring a
|
|
20
|
+
* fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
21
|
+
*/
|
|
22
|
+
function login(clientId: string, email: string, password: string, trustedDeviceToken?: string): Promise<AuthLoginResponse>;
|
|
23
|
+
/**
|
|
24
|
+
* Register a new user (public).
|
|
25
|
+
*
|
|
26
|
+
* Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's
|
|
27
|
+
* nothing to challenge against.
|
|
28
|
+
*/
|
|
10
29
|
function register(clientId: string, data: {
|
|
11
30
|
email: string;
|
|
12
31
|
password: string;
|
|
13
32
|
displayName?: string;
|
|
14
33
|
accountData?: Record<string, any>;
|
|
15
34
|
}): Promise<AuthLoginResponse>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Google OAuth login via ID token (public).
|
|
37
|
+
*
|
|
38
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
39
|
+
*
|
|
40
|
+
* @param trustedDeviceToken - Optional. Pass a token previously returned by
|
|
41
|
+
* {@link mfaChallengeVerify}/{@link mfaRecoveryCode} (with `trustDevice: true`) to skip
|
|
42
|
+
* the challenge on this device, same as {@link login}.
|
|
43
|
+
*/
|
|
44
|
+
function googleLogin(clientId: string, idToken: string, trustedDeviceToken?: string): Promise<AuthLoginResponse>;
|
|
18
45
|
/** Google OAuth login via server-side authorization code (public). */
|
|
19
46
|
function googleCodeLogin(clientId: string, code: string, redirectUri: string): Promise<AuthLoginResponse>;
|
|
20
47
|
/**
|
|
@@ -32,6 +59,9 @@ export declare namespace authKit {
|
|
|
32
59
|
* then link Apple from settings. **The same 409 can now come back from
|
|
33
60
|
* {@link googleLogin}** under the shared verified-to-verified linking policy.
|
|
34
61
|
*
|
|
62
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. Pass
|
|
63
|
+
* `opts.trustedDeviceToken` to skip the challenge on a recognized device.
|
|
64
|
+
*
|
|
35
65
|
* @see AppleLoginOptions
|
|
36
66
|
*/
|
|
37
67
|
function appleLogin(clientId: string, identityToken: string, opts?: AppleLoginOptions): Promise<AuthLoginResponse>;
|
|
@@ -70,20 +100,46 @@ export declare namespace authKit {
|
|
|
70
100
|
redirectUrl: string;
|
|
71
101
|
accountData?: Record<string, any>;
|
|
72
102
|
}): Promise<MagicLinkSendResponse>;
|
|
73
|
-
/**
|
|
74
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Verify a magic link token and authenticate/create the user (public).
|
|
105
|
+
*
|
|
106
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
107
|
+
*
|
|
108
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
109
|
+
*/
|
|
110
|
+
function verifyMagicLink(clientId: string, token: string, trustedDeviceToken?: string): Promise<MagicLinkVerifyResponse>;
|
|
75
111
|
/** Send phone verification code (public). */
|
|
76
112
|
function sendPhoneCode(clientId: string, phoneNumber: string): Promise<PhoneSendCodeResponse>;
|
|
77
|
-
/**
|
|
78
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Verify phone verification code (public).
|
|
115
|
+
*
|
|
116
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
117
|
+
*
|
|
118
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
119
|
+
*/
|
|
120
|
+
function verifyPhoneCode(clientId: string, phoneNumber: string, code: string, trustedDeviceToken?: string): Promise<PhoneVerifyResponse>;
|
|
79
121
|
/** Send a WhatsApp verification deep-link (public). */
|
|
80
122
|
function sendWhatsApp(clientId: string, body?: SendWhatsAppRequest): Promise<SendWhatsAppResponse>;
|
|
81
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* Manually verify WhatsApp token if inbound webhook path is unavailable (legacy/public fallback).
|
|
125
|
+
*
|
|
126
|
+
* Not gated by step-up MFA — this endpoint only confirms the code, it never issues a
|
|
127
|
+
* session/bearer token, so there is nothing to challenge. {@link exchangeWhatsAppSession}
|
|
128
|
+
* is the WhatsApp method that's gated.
|
|
129
|
+
*/
|
|
82
130
|
function verifyWhatsApp(clientId: string, token: string, phoneNumber: string): Promise<VerifyWhatsAppResponse>;
|
|
83
131
|
/** Poll WhatsApp verification status for a token (public). */
|
|
84
132
|
function getWhatsAppStatus(clientId: string, token: string): Promise<WhatsAppStatusResponse>;
|
|
85
|
-
/**
|
|
86
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Exchange a verified WhatsApp token for an Auth Kit session (public).
|
|
135
|
+
*
|
|
136
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. This is
|
|
137
|
+
* the WhatsApp method that needs `trustedDeviceToken`, not {@link verifyWhatsApp} (which
|
|
138
|
+
* never issues a session).
|
|
139
|
+
*
|
|
140
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
141
|
+
*/
|
|
142
|
+
function exchangeWhatsAppSession(clientId: string, token: string, sessionKey: string, trustedDeviceToken?: string): Promise<ExchangeWhatsAppSessionResponse>;
|
|
87
143
|
/** Send an SMS click-to-verify link (public). */
|
|
88
144
|
function sendSmsVerify(clientId: string, body: SendSmsVerifyRequest): Promise<SendSmsVerifyResponse>;
|
|
89
145
|
/** Verify an SMS click-to-verify token via API (public). */
|
|
@@ -124,6 +180,47 @@ export declare namespace authKit {
|
|
|
124
180
|
function verifyEmailChange(clientId: string, token: string): Promise<SuccessResponse>;
|
|
125
181
|
function updatePhone(clientId: string, phoneNumber: string, verificationCode: string): Promise<SuccessResponse>;
|
|
126
182
|
function deleteAccount(clientId: string, password: string, confirmText: string): Promise<SuccessResponse>;
|
|
183
|
+
/** Send (or resend) an MFA challenge code to the given factor (public). */
|
|
184
|
+
function mfaChallengeSend(clientId: string, mfaSessionToken: string, factor: 'email' | 'sms'): Promise<MfaChallengeSendResponse>;
|
|
185
|
+
/**
|
|
186
|
+
* Verify an MFA challenge code and finalize the login (public). On success this behaves
|
|
187
|
+
* like {@link login} — the bearer token is adopted and the cache invalidated.
|
|
188
|
+
*
|
|
189
|
+
* @param trustDevice - When `true`, the response includes `trustedDeviceToken` — persist
|
|
190
|
+
* it and pass it to future {@link login} calls to skip the challenge on this device.
|
|
191
|
+
*/
|
|
192
|
+
function mfaChallengeVerify(clientId: string, mfaSessionToken: string, code: string, trustDevice?: boolean, deviceLabel?: string): Promise<MfaFinalizeResponse>;
|
|
193
|
+
/**
|
|
194
|
+
* Finalize a challenged login using a single-use recovery code instead of a sent code
|
|
195
|
+
* (public). Same finalize-session behaviour as {@link mfaChallengeVerify}.
|
|
196
|
+
*/
|
|
197
|
+
function mfaRecoveryCode(clientId: string, mfaSessionToken: string, code: string, trustDevice?: boolean, deviceLabel?: string): Promise<MfaFinalizeResponse>;
|
|
198
|
+
/** List enrolled factors and recovery-code count for the current user (authenticated). */
|
|
199
|
+
function getMfaFactors(clientId: string): Promise<MfaFactorsResponse>;
|
|
200
|
+
/** Begin email-factor enrollment; sends a code to the account's existing email (authenticated). */
|
|
201
|
+
function enrollEmailMfa(clientId: string): Promise<MfaEnrollSendResponse>;
|
|
202
|
+
/** Confirm email-factor enrollment with the code sent by {@link enrollEmailMfa} (authenticated). */
|
|
203
|
+
function confirmEmailMfa(clientId: string, mfaSessionToken: string, code: string): Promise<MfaEnrolledResponse>;
|
|
204
|
+
/** Begin SMS-factor enrollment; sends a code to the given phone number (authenticated). */
|
|
205
|
+
function enrollSmsMfa(clientId: string, phoneNumber: string): Promise<MfaEnrollSendResponse>;
|
|
206
|
+
/** Confirm SMS-factor enrollment with the code sent by {@link enrollSmsMfa} (authenticated). */
|
|
207
|
+
function confirmSmsMfa(clientId: string, mfaSessionToken: string, code: string): Promise<MfaEnrolledResponse>;
|
|
208
|
+
/**
|
|
209
|
+
* Generate a fresh set of recovery codes, invalidating any previous set (authenticated).
|
|
210
|
+
* Returned **in plaintext, exactly once** — nothing else in the API ever returns them
|
|
211
|
+
* again, so the caller must display/export them immediately.
|
|
212
|
+
*/
|
|
213
|
+
function generateMfaRecoveryCodes(clientId: string, password: string): Promise<{
|
|
214
|
+
recoveryCodes: string[];
|
|
215
|
+
}>;
|
|
216
|
+
/** Remove an enrolled MFA factor (authenticated). Server route is DELETE with a body. */
|
|
217
|
+
function removeMfaFactor(clientId: string, factor: 'email' | 'sms', password: string): Promise<SuccessResponse>;
|
|
218
|
+
/** List devices trusted to skip MFA challenges for the current user (authenticated). */
|
|
219
|
+
function listTrustedDevices(clientId: string): Promise<{
|
|
220
|
+
devices: TrustedDevice[];
|
|
221
|
+
}>;
|
|
222
|
+
/** Revoke a single trusted device by id (authenticated). */
|
|
223
|
+
function revokeTrustedDevice(clientId: string, id: string): Promise<SuccessResponse>;
|
|
127
224
|
function load(authKitId: string): Promise<AuthKitConfig>;
|
|
128
225
|
function get(collectionId: string, authKitId: string): Promise<AuthKitConfig>;
|
|
129
226
|
function list(collectionId: string, admin?: boolean): Promise<AuthKitConfig[]>;
|
package/dist/api/authKit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { request, post, put, del, setBearerToken, invalidateCache } from "../http";
|
|
1
|
+
import { request, post, put, del, requestWithOptions, setBearerToken, invalidateCache } from "../http";
|
|
2
2
|
/**
|
|
3
3
|
* Namespace containing helper functions for the new AuthKit API.
|
|
4
4
|
* Legacy collection-based authKit helpers retained (marked as *Legacy*).
|
|
@@ -8,9 +8,26 @@ export var authKit;
|
|
|
8
8
|
/* ===================================
|
|
9
9
|
* Authentication (Per client)
|
|
10
10
|
* =================================== */
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Login with email + password (public).
|
|
13
|
+
*
|
|
14
|
+
* When the client's MFA policy requires a step-up, the server returns **403
|
|
15
|
+
* `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with
|
|
16
|
+
* `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in
|
|
17
|
+
* `err.details` (see {@link MfaRequiredDetails}). Route the caller to
|
|
18
|
+
* {@link mfaChallengeSend} on that error; this method's return type is unchanged.
|
|
19
|
+
*
|
|
20
|
+
* @param trustedDeviceToken - Optional. If a previous MFA challenge on this device
|
|
21
|
+
* returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with
|
|
22
|
+
* `trustDevice: true`), pass it here to skip the challenge entirely as long as it's
|
|
23
|
+
* still valid. If it's revoked/expired, the server silently falls back to requiring a
|
|
24
|
+
* fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
25
|
+
*/
|
|
26
|
+
async function login(clientId, email, password, trustedDeviceToken) {
|
|
27
|
+
const body = { email, password };
|
|
28
|
+
if (trustedDeviceToken)
|
|
29
|
+
body.trustedDeviceToken = trustedDeviceToken;
|
|
30
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/login`, body);
|
|
14
31
|
if (res.token) {
|
|
15
32
|
setBearerToken(res.token);
|
|
16
33
|
invalidateCache();
|
|
@@ -18,14 +35,27 @@ export var authKit;
|
|
|
18
35
|
return res;
|
|
19
36
|
}
|
|
20
37
|
authKit.login = login;
|
|
21
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Register a new user (public).
|
|
40
|
+
*
|
|
41
|
+
* Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's
|
|
42
|
+
* nothing to challenge against.
|
|
43
|
+
*/
|
|
22
44
|
async function register(clientId, data) {
|
|
23
45
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/register`, data);
|
|
24
46
|
}
|
|
25
47
|
authKit.register = register;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Google OAuth login via ID token (public).
|
|
50
|
+
*
|
|
51
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
52
|
+
*
|
|
53
|
+
* @param trustedDeviceToken - Optional. Pass a token previously returned by
|
|
54
|
+
* {@link mfaChallengeVerify}/{@link mfaRecoveryCode} (with `trustDevice: true`) to skip
|
|
55
|
+
* the challenge on this device, same as {@link login}.
|
|
56
|
+
*/
|
|
57
|
+
async function googleLogin(clientId, idToken, trustedDeviceToken) {
|
|
58
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/google`, { idToken, trustedDeviceToken });
|
|
29
59
|
if (res.token) {
|
|
30
60
|
setBearerToken(res.token);
|
|
31
61
|
invalidateCache();
|
|
@@ -58,6 +88,9 @@ export var authKit;
|
|
|
58
88
|
* then link Apple from settings. **The same 409 can now come back from
|
|
59
89
|
* {@link googleLogin}** under the shared verified-to-verified linking policy.
|
|
60
90
|
*
|
|
91
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. Pass
|
|
92
|
+
* `opts.trustedDeviceToken` to skip the challenge on a recognized device.
|
|
93
|
+
*
|
|
61
94
|
* @see AppleLoginOptions
|
|
62
95
|
*/
|
|
63
96
|
async function appleLogin(clientId, identityToken, opts) {
|
|
@@ -121,9 +154,15 @@ export var authKit;
|
|
|
121
154
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/magic-link/send`, data);
|
|
122
155
|
}
|
|
123
156
|
authKit.sendMagicLink = sendMagicLink;
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Verify a magic link token and authenticate/create the user (public).
|
|
159
|
+
*
|
|
160
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
161
|
+
*
|
|
162
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
163
|
+
*/
|
|
164
|
+
async function verifyMagicLink(clientId, token, trustedDeviceToken) {
|
|
165
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/magic-link/verify`, { token, trustedDeviceToken });
|
|
127
166
|
if (res.token) {
|
|
128
167
|
setBearerToken(res.token);
|
|
129
168
|
invalidateCache();
|
|
@@ -136,9 +175,15 @@ export var authKit;
|
|
|
136
175
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/phone/send-code`, { phoneNumber });
|
|
137
176
|
}
|
|
138
177
|
authKit.sendPhoneCode = sendPhoneCode;
|
|
139
|
-
/**
|
|
140
|
-
|
|
141
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Verify phone verification code (public).
|
|
180
|
+
*
|
|
181
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape.
|
|
182
|
+
*
|
|
183
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
184
|
+
*/
|
|
185
|
+
async function verifyPhoneCode(clientId, phoneNumber, code, trustedDeviceToken) {
|
|
186
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/phone/verify`, { phoneNumber, code, trustedDeviceToken });
|
|
142
187
|
setBearerToken(res.token);
|
|
143
188
|
invalidateCache();
|
|
144
189
|
return res;
|
|
@@ -149,7 +194,13 @@ export var authKit;
|
|
|
149
194
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/send`, body);
|
|
150
195
|
}
|
|
151
196
|
authKit.sendWhatsApp = sendWhatsApp;
|
|
152
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Manually verify WhatsApp token if inbound webhook path is unavailable (legacy/public fallback).
|
|
199
|
+
*
|
|
200
|
+
* Not gated by step-up MFA — this endpoint only confirms the code, it never issues a
|
|
201
|
+
* session/bearer token, so there is nothing to challenge. {@link exchangeWhatsAppSession}
|
|
202
|
+
* is the WhatsApp method that's gated.
|
|
203
|
+
*/
|
|
153
204
|
async function verifyWhatsApp(clientId, token, phoneNumber) {
|
|
154
205
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/verify`, { token, phoneNumber });
|
|
155
206
|
}
|
|
@@ -160,9 +211,17 @@ export var authKit;
|
|
|
160
211
|
return request(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/status?token=${encodedToken}`);
|
|
161
212
|
}
|
|
162
213
|
authKit.getWhatsAppStatus = getWhatsAppStatus;
|
|
163
|
-
/**
|
|
164
|
-
|
|
165
|
-
|
|
214
|
+
/**
|
|
215
|
+
* Exchange a verified WhatsApp token for an Auth Kit session (public).
|
|
216
|
+
*
|
|
217
|
+
* Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. This is
|
|
218
|
+
* the WhatsApp method that needs `trustedDeviceToken`, not {@link verifyWhatsApp} (which
|
|
219
|
+
* never issues a session).
|
|
220
|
+
*
|
|
221
|
+
* @param trustedDeviceToken - Optional. See {@link login}.
|
|
222
|
+
*/
|
|
223
|
+
async function exchangeWhatsAppSession(clientId, token, sessionKey, trustedDeviceToken) {
|
|
224
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/exchange-session`, { token, sessionKey, trustedDeviceToken });
|
|
166
225
|
setBearerToken(res.token);
|
|
167
226
|
invalidateCache();
|
|
168
227
|
return res;
|
|
@@ -277,6 +336,101 @@ export var authKit;
|
|
|
277
336
|
return res;
|
|
278
337
|
}
|
|
279
338
|
authKit.deleteAccount = deleteAccount;
|
|
339
|
+
/* ===================================
|
|
340
|
+
* Step-up MFA — completing a challenged login (public)
|
|
341
|
+
*
|
|
342
|
+
* Called after login() throws MFA_REQUIRED. mfaSessionToken is short-lived (10 min) and
|
|
343
|
+
* single-use — burned on 5 failed attempts (MFA_TOO_MANY_ATTEMPTS) or on success.
|
|
344
|
+
* challenge/send can be called again on the same token (while unexpired/unburned) to
|
|
345
|
+
* switch factors or resend.
|
|
346
|
+
* =================================== */
|
|
347
|
+
/** Send (or resend) an MFA challenge code to the given factor (public). */
|
|
348
|
+
async function mfaChallengeSend(clientId, mfaSessionToken, factor) {
|
|
349
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/challenge/send`, { mfaSessionToken, factor });
|
|
350
|
+
}
|
|
351
|
+
authKit.mfaChallengeSend = mfaChallengeSend;
|
|
352
|
+
/**
|
|
353
|
+
* Verify an MFA challenge code and finalize the login (public). On success this behaves
|
|
354
|
+
* like {@link login} — the bearer token is adopted and the cache invalidated.
|
|
355
|
+
*
|
|
356
|
+
* @param trustDevice - When `true`, the response includes `trustedDeviceToken` — persist
|
|
357
|
+
* it and pass it to future {@link login} calls to skip the challenge on this device.
|
|
358
|
+
*/
|
|
359
|
+
async function mfaChallengeVerify(clientId, mfaSessionToken, code, trustDevice, deviceLabel) {
|
|
360
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/mfa/challenge/verify`, { mfaSessionToken, code, trustDevice, deviceLabel });
|
|
361
|
+
if (res.token) {
|
|
362
|
+
setBearerToken(res.token);
|
|
363
|
+
invalidateCache();
|
|
364
|
+
}
|
|
365
|
+
return res;
|
|
366
|
+
}
|
|
367
|
+
authKit.mfaChallengeVerify = mfaChallengeVerify;
|
|
368
|
+
/**
|
|
369
|
+
* Finalize a challenged login using a single-use recovery code instead of a sent code
|
|
370
|
+
* (public). Same finalize-session behaviour as {@link mfaChallengeVerify}.
|
|
371
|
+
*/
|
|
372
|
+
async function mfaRecoveryCode(clientId, mfaSessionToken, code, trustDevice, deviceLabel) {
|
|
373
|
+
const res = await post(`/authkit/${encodeURIComponent(clientId)}/mfa/challenge/recovery-code`, { mfaSessionToken, code, trustDevice, deviceLabel });
|
|
374
|
+
if (res.token) {
|
|
375
|
+
setBearerToken(res.token);
|
|
376
|
+
invalidateCache();
|
|
377
|
+
}
|
|
378
|
+
return res;
|
|
379
|
+
}
|
|
380
|
+
authKit.mfaRecoveryCode = mfaRecoveryCode;
|
|
381
|
+
/* ===================================
|
|
382
|
+
* Step-up MFA — factor management (Authenticated)
|
|
383
|
+
* =================================== */
|
|
384
|
+
/** List enrolled factors and recovery-code count for the current user (authenticated). */
|
|
385
|
+
async function getMfaFactors(clientId) {
|
|
386
|
+
return request(`/authkit/${encodeURIComponent(clientId)}/mfa/factors`);
|
|
387
|
+
}
|
|
388
|
+
authKit.getMfaFactors = getMfaFactors;
|
|
389
|
+
/** Begin email-factor enrollment; sends a code to the account's existing email (authenticated). */
|
|
390
|
+
async function enrollEmailMfa(clientId) {
|
|
391
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/email/enroll`, {});
|
|
392
|
+
}
|
|
393
|
+
authKit.enrollEmailMfa = enrollEmailMfa;
|
|
394
|
+
/** Confirm email-factor enrollment with the code sent by {@link enrollEmailMfa} (authenticated). */
|
|
395
|
+
async function confirmEmailMfa(clientId, mfaSessionToken, code) {
|
|
396
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/email/confirm`, { mfaSessionToken, code });
|
|
397
|
+
}
|
|
398
|
+
authKit.confirmEmailMfa = confirmEmailMfa;
|
|
399
|
+
/** Begin SMS-factor enrollment; sends a code to the given phone number (authenticated). */
|
|
400
|
+
async function enrollSmsMfa(clientId, phoneNumber) {
|
|
401
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/sms/enroll`, { phoneNumber });
|
|
402
|
+
}
|
|
403
|
+
authKit.enrollSmsMfa = enrollSmsMfa;
|
|
404
|
+
/** Confirm SMS-factor enrollment with the code sent by {@link enrollSmsMfa} (authenticated). */
|
|
405
|
+
async function confirmSmsMfa(clientId, mfaSessionToken, code) {
|
|
406
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/sms/confirm`, { mfaSessionToken, code });
|
|
407
|
+
}
|
|
408
|
+
authKit.confirmSmsMfa = confirmSmsMfa;
|
|
409
|
+
/**
|
|
410
|
+
* Generate a fresh set of recovery codes, invalidating any previous set (authenticated).
|
|
411
|
+
* Returned **in plaintext, exactly once** — nothing else in the API ever returns them
|
|
412
|
+
* again, so the caller must display/export them immediately.
|
|
413
|
+
*/
|
|
414
|
+
async function generateMfaRecoveryCodes(clientId, password) {
|
|
415
|
+
return post(`/authkit/${encodeURIComponent(clientId)}/mfa/recovery-codes/generate`, { password });
|
|
416
|
+
}
|
|
417
|
+
authKit.generateMfaRecoveryCodes = generateMfaRecoveryCodes;
|
|
418
|
+
/** Remove an enrolled MFA factor (authenticated). Server route is DELETE with a body. */
|
|
419
|
+
async function removeMfaFactor(clientId, factor, password) {
|
|
420
|
+
const path = `/authkit/${encodeURIComponent(clientId)}/mfa/factors/${factor}`;
|
|
421
|
+
return requestWithOptions(path, { method: 'DELETE', body: JSON.stringify({ password }) });
|
|
422
|
+
}
|
|
423
|
+
authKit.removeMfaFactor = removeMfaFactor;
|
|
424
|
+
/** List devices trusted to skip MFA challenges for the current user (authenticated). */
|
|
425
|
+
async function listTrustedDevices(clientId) {
|
|
426
|
+
return request(`/authkit/${encodeURIComponent(clientId)}/mfa/trusted-devices`);
|
|
427
|
+
}
|
|
428
|
+
authKit.listTrustedDevices = listTrustedDevices;
|
|
429
|
+
/** Revoke a single trusted device by id (authenticated). */
|
|
430
|
+
async function revokeTrustedDevice(clientId, id) {
|
|
431
|
+
return del(`/authkit/${encodeURIComponent(clientId)}/mfa/trusted-devices/${encodeURIComponent(id)}`);
|
|
432
|
+
}
|
|
433
|
+
authKit.revokeTrustedDevice = revokeTrustedDevice;
|
|
280
434
|
/* ===================================
|
|
281
435
|
* Collection-based AuthKit
|
|
282
436
|
* =================================== */
|