@proveanything/smartlinks 1.15.18 → 1.15.19
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 +2 -2
- package/dist/api/authKit.d.ts +10 -0
- package/dist/api/authKit.js +10 -0
- package/dist/api/proof.d.ts +24 -1
- package/dist/api/proof.js +25 -2
- package/dist/docs/API_SUMMARY.md +85 -10
- package/dist/docs/auth-kit.md +73 -0
- package/dist/index.d.ts +2 -2
- package/dist/openapi.yaml +88 -7
- package/dist/types/authKit.d.ts +67 -1
- package/dist/types/proof.d.ts +60 -5
- package/docs/API_SUMMARY.md +85 -10
- package/docs/auth-kit.md +73 -0
- package/openapi.yaml +88 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,10 +41,10 @@ If you're new to the SDK, this is the easiest path:
|
|
|
41
41
|
- **Fetch collections/products** → see [Quick start](README.md#quick-start)
|
|
42
42
|
- **Authenticate admins or end users** → see [Authentication](README.md#authentication)
|
|
43
43
|
- **Upload and manage files** → see [Assets](README.md#assets)
|
|
44
|
-
- **Browse the full surface area** → use [API_SUMMARY.md](API_SUMMARY.md) as reference
|
|
44
|
+
- **Browse the full surface area** → use [API_SUMMARY.md](docs/API_SUMMARY.md) as reference
|
|
45
45
|
|
|
46
46
|
For the full list of functions and types, see the API summary:
|
|
47
|
-
→ [API Summary](API_SUMMARY.md)
|
|
47
|
+
→ [API Summary](docs/API_SUMMARY.md)
|
|
48
48
|
|
|
49
49
|
**Documentation:**
|
|
50
50
|
- [AI & Chat Completions](docs/ai.md) - Chat completions, RAG, voice integration
|
package/dist/api/authKit.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export declare namespace authKit {
|
|
|
18
18
|
* `trustDevice: true`), pass it here to skip the challenge entirely as long as it's
|
|
19
19
|
* still valid. If it's revoked/expired, the server silently falls back to requiring a
|
|
20
20
|
* fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
21
|
+
*
|
|
22
|
+
* Security errors (thrown as `SmartlinksApiError`, see {@link LoginSecurityErrorCode}):
|
|
23
|
+
* - `ACCOUNT_TEMPORARILY_LOCKED` (429) — `err.details.retryAfterSeconds` says how long to wait.
|
|
24
|
+
* - `PASSWORD_EXPIRED` (403) — `err.details.resetToken` is short-lived; route into
|
|
25
|
+
* {@link completePasswordReset} to change the password in place.
|
|
21
26
|
*/
|
|
22
27
|
function login(clientId: string, email: string, password: string, trustedDeviceToken?: string): Promise<AuthLoginResponse>;
|
|
23
28
|
/**
|
|
@@ -25,6 +30,11 @@ export declare namespace authKit {
|
|
|
25
30
|
*
|
|
26
31
|
* Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's
|
|
27
32
|
* nothing to challenge against.
|
|
33
|
+
*
|
|
34
|
+
* The new password is validated against the collection's `passwordPolicy` — may throw
|
|
35
|
+
* a {@link PasswordPolicyErrorCode} (400). The same validation applies to
|
|
36
|
+
* {@link completePasswordReset} and {@link changePassword}. Read the policy for a live
|
|
37
|
+
* checklist from `authKit.load(clientId)` → `config.security.passwordPolicy`.
|
|
28
38
|
*/
|
|
29
39
|
function register(clientId: string, data: {
|
|
30
40
|
email: string;
|
package/dist/api/authKit.js
CHANGED
|
@@ -22,6 +22,11 @@ export var authKit;
|
|
|
22
22
|
* `trustDevice: true`), pass it here to skip the challenge entirely as long as it's
|
|
23
23
|
* still valid. If it's revoked/expired, the server silently falls back to requiring a
|
|
24
24
|
* fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
25
|
+
*
|
|
26
|
+
* Security errors (thrown as `SmartlinksApiError`, see {@link LoginSecurityErrorCode}):
|
|
27
|
+
* - `ACCOUNT_TEMPORARILY_LOCKED` (429) — `err.details.retryAfterSeconds` says how long to wait.
|
|
28
|
+
* - `PASSWORD_EXPIRED` (403) — `err.details.resetToken` is short-lived; route into
|
|
29
|
+
* {@link completePasswordReset} to change the password in place.
|
|
25
30
|
*/
|
|
26
31
|
async function login(clientId, email, password, trustedDeviceToken) {
|
|
27
32
|
const body = { email, password };
|
|
@@ -40,6 +45,11 @@ export var authKit;
|
|
|
40
45
|
*
|
|
41
46
|
* Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's
|
|
42
47
|
* nothing to challenge against.
|
|
48
|
+
*
|
|
49
|
+
* The new password is validated against the collection's `passwordPolicy` — may throw
|
|
50
|
+
* a {@link PasswordPolicyErrorCode} (400). The same validation applies to
|
|
51
|
+
* {@link completePasswordReset} and {@link changePassword}. Read the policy for a live
|
|
52
|
+
* checklist from `authKit.load(clientId)` → `config.security.passwordPolicy`.
|
|
43
53
|
*/
|
|
44
54
|
async function register(clientId, data) {
|
|
45
55
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/register`, data);
|
package/dist/api/proof.d.ts
CHANGED
|
@@ -12,11 +12,34 @@ export declare namespace proof {
|
|
|
12
12
|
/**
|
|
13
13
|
* Create a proof for a product (admin only).
|
|
14
14
|
* POST /admin/collection/:collectionId/product/:productId/proof
|
|
15
|
+
*
|
|
16
|
+
* Pass the proof's content in a `proof` block, keyed by zone (see {@link ProofWrite}):
|
|
17
|
+
* ```ts
|
|
18
|
+
* proof.create(collectionId, productId, {
|
|
19
|
+
* proof: {
|
|
20
|
+
* values: { colour: 'red' }, // public + owner readable, owner + admin writable
|
|
21
|
+
* data: { serialNo: 1001 }, // public + owner readable, ADMIN-only writable
|
|
22
|
+
* admin: { costPrice: 4.20 }, // admin-only
|
|
23
|
+
* },
|
|
24
|
+
* claimable: true,
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
* Note: a top-level `data`/`admin` on the request body is legacy — top-level
|
|
28
|
+
* `data` gets folded into the values bag, so use `proof.data` for `proof.data`.
|
|
15
29
|
*/
|
|
16
|
-
function create(collectionId: string, productId: string,
|
|
30
|
+
function create(collectionId: string, productId: string, request: ProofCreateRequest): Promise<ProofResponse>;
|
|
17
31
|
/**
|
|
18
32
|
* Update a proof for a product (admin only).
|
|
19
33
|
* PUT /admin/collection/:collectionId/product/:productId/proof/:proofId
|
|
34
|
+
*
|
|
35
|
+
* Pass the fields to change **at the root**, keyed by zone (see {@link ProofWrite}):
|
|
36
|
+
* ```ts
|
|
37
|
+
* proof.update(collectionId, productId, proofId, {
|
|
38
|
+
* data: { serialNo: 1002 }, // → proof.data (admin-only writable)
|
|
39
|
+
* values: { colour: 'blue' }, // → proof.values
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
* Object zones deep-merge, so you can change one field without wiping the rest.
|
|
20
43
|
*/
|
|
21
44
|
function update(collectionId: string, productId: string, proofId: string, values: ProofUpdateRequest): Promise<ProofResponse>;
|
|
22
45
|
/**
|
package/dist/api/proof.js
CHANGED
|
@@ -26,15 +26,38 @@ export var proof;
|
|
|
26
26
|
/**
|
|
27
27
|
* Create a proof for a product (admin only).
|
|
28
28
|
* POST /admin/collection/:collectionId/product/:productId/proof
|
|
29
|
+
*
|
|
30
|
+
* Pass the proof's content in a `proof` block, keyed by zone (see {@link ProofWrite}):
|
|
31
|
+
* ```ts
|
|
32
|
+
* proof.create(collectionId, productId, {
|
|
33
|
+
* proof: {
|
|
34
|
+
* values: { colour: 'red' }, // public + owner readable, owner + admin writable
|
|
35
|
+
* data: { serialNo: 1001 }, // public + owner readable, ADMIN-only writable
|
|
36
|
+
* admin: { costPrice: 4.20 }, // admin-only
|
|
37
|
+
* },
|
|
38
|
+
* claimable: true,
|
|
39
|
+
* })
|
|
40
|
+
* ```
|
|
41
|
+
* Note: a top-level `data`/`admin` on the request body is legacy — top-level
|
|
42
|
+
* `data` gets folded into the values bag, so use `proof.data` for `proof.data`.
|
|
29
43
|
*/
|
|
30
|
-
async function create(collectionId, productId,
|
|
44
|
+
async function create(collectionId, productId, request) {
|
|
31
45
|
const path = `/admin/collection/${encodeURIComponent(collectionId)}/product/${encodeURIComponent(productId)}/proof`;
|
|
32
|
-
return post(path,
|
|
46
|
+
return post(path, request);
|
|
33
47
|
}
|
|
34
48
|
proof.create = create;
|
|
35
49
|
/**
|
|
36
50
|
* Update a proof for a product (admin only).
|
|
37
51
|
* PUT /admin/collection/:collectionId/product/:productId/proof/:proofId
|
|
52
|
+
*
|
|
53
|
+
* Pass the fields to change **at the root**, keyed by zone (see {@link ProofWrite}):
|
|
54
|
+
* ```ts
|
|
55
|
+
* proof.update(collectionId, productId, proofId, {
|
|
56
|
+
* data: { serialNo: 1002 }, // → proof.data (admin-only writable)
|
|
57
|
+
* values: { colour: 'blue' }, // → proof.values
|
|
58
|
+
* })
|
|
59
|
+
* ```
|
|
60
|
+
* Object zones deep-merge, so you can change one field without wiping the rest.
|
|
38
61
|
*/
|
|
39
62
|
async function update(collectionId, productId, proofId, values) {
|
|
40
63
|
const path = `/admin/collection/${encodeURIComponent(collectionId)}/product/${encodeURIComponent(productId)}/proof/${encodeURIComponent(proofId)}`;
|
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.15.
|
|
3
|
+
Version: 1.15.19 | Generated: 2026-08-20T18:06:08.134Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -3464,6 +3464,55 @@ interface AuthKitConfig {
|
|
|
3464
3464
|
supportEmail?: string
|
|
3465
3465
|
redirectUrl?: string
|
|
3466
3466
|
updatedAt?: string
|
|
3467
|
+
* Per-collection security policy. On the public config endpoint only
|
|
3468
|
+
* `passwordPolicy` + `session` are returned (the client renders password
|
|
3469
|
+
* checklists / idle sign-out from them); `lockout` is admin-only and enforced
|
|
3470
|
+
* server-side. See {@link AuthKitSecurityConfig}.
|
|
3471
|
+
security?: AuthKitSecurityConfig
|
|
3472
|
+
}
|
|
3473
|
+
```
|
|
3474
|
+
|
|
3475
|
+
**AuthKitSecurityConfig** (interface)
|
|
3476
|
+
```typescript
|
|
3477
|
+
interface AuthKitSecurityConfig {
|
|
3478
|
+
passwordPolicy?: AuthKitPasswordPolicy
|
|
3479
|
+
session?: AuthKitSessionPolicy
|
|
3480
|
+
lockout?: AuthKitLockoutPolicy
|
|
3481
|
+
}
|
|
3482
|
+
```
|
|
3483
|
+
|
|
3484
|
+
**AuthKitPasswordPolicy** (interface)
|
|
3485
|
+
```typescript
|
|
3486
|
+
interface AuthKitPasswordPolicy {
|
|
3487
|
+
minLength?: number
|
|
3488
|
+
requireUppercase?: boolean
|
|
3489
|
+
requireLowercase?: boolean
|
|
3490
|
+
requireNumber?: boolean
|
|
3491
|
+
requireSymbol?: boolean
|
|
3492
|
+
blockCommonPasswords?: boolean
|
|
3493
|
+
expiryDays?: number
|
|
3494
|
+
historyCount?: number
|
|
3495
|
+
}
|
|
3496
|
+
```
|
|
3497
|
+
|
|
3498
|
+
**AuthKitSessionPolicy** (interface)
|
|
3499
|
+
```typescript
|
|
3500
|
+
interface AuthKitSessionPolicy {
|
|
3501
|
+
inactivityTimeoutMinutes?: number
|
|
3502
|
+
inactivityWarningSeconds?: number
|
|
3503
|
+
absoluteTimeoutHours?: number
|
|
3504
|
+
rememberMe?: boolean
|
|
3505
|
+
}
|
|
3506
|
+
```
|
|
3507
|
+
|
|
3508
|
+
**AuthKitLockoutPolicy** (interface)
|
|
3509
|
+
```typescript
|
|
3510
|
+
interface AuthKitLockoutPolicy {
|
|
3511
|
+
enabled?: boolean
|
|
3512
|
+
maxFailedAttempts?: number
|
|
3513
|
+
attemptWindowMinutes?: number
|
|
3514
|
+
lockoutMinutes?: number
|
|
3515
|
+
notifyUserOnLockout?: boolean
|
|
3467
3516
|
}
|
|
3468
3517
|
```
|
|
3469
3518
|
|
|
@@ -3475,6 +3524,10 @@ interface AuthKitConfig {
|
|
|
3475
3524
|
|
|
3476
3525
|
**VerifyStatus** = `'pending' | 'verified' | 'failed' | 'expired' | 'unknown'`
|
|
3477
3526
|
|
|
3527
|
+
**PasswordPolicyErrorCode** = ``
|
|
3528
|
+
|
|
3529
|
+
**LoginSecurityErrorCode** = ``
|
|
3530
|
+
|
|
3478
3531
|
### batch
|
|
3479
3532
|
|
|
3480
3533
|
**FirebaseTimestamp** (interface)
|
|
@@ -7279,14 +7332,36 @@ interface Proof {
|
|
|
7279
7332
|
}
|
|
7280
7333
|
```
|
|
7281
7334
|
|
|
7282
|
-
**
|
|
7335
|
+
**ProofWrite** (interface)
|
|
7283
7336
|
```typescript
|
|
7284
|
-
interface
|
|
7285
|
-
|
|
7337
|
+
interface ProofWrite {
|
|
7338
|
+
* Choose the proof's ID (serial, NFC id, etc.). Honoured **on create only** —
|
|
7339
|
+
* the ledger doc becomes `{productId}-{id}`. Omit to auto-generate. Ignored on
|
|
7340
|
+
* update (a proof's ID is immutable).
|
|
7341
|
+
id?: string
|
|
7342
|
+
values?: ProofValues
|
|
7286
7343
|
data?: Record<string, JsonValue>
|
|
7287
7344
|
admin?: Record<string, JsonValue>
|
|
7345
|
+
owner?: Record<string, JsonValue>
|
|
7346
|
+
claimable?: boolean
|
|
7347
|
+
[key: string]: JsonValue | Record<string, JsonValue> | ProofValues | undefined
|
|
7348
|
+
}
|
|
7349
|
+
```
|
|
7350
|
+
|
|
7351
|
+
**ProofCreateRequest** (interface)
|
|
7352
|
+
```typescript
|
|
7353
|
+
interface ProofCreateRequest {
|
|
7354
|
+
* The proof to create, by zone (mirrors the proof document). This is the clear,
|
|
7355
|
+
* recommended shape — `create(collectionId, productId, { proof: {...} })`.
|
|
7356
|
+
proof?: ProofWrite
|
|
7357
|
+
values?: ProofValues
|
|
7288
7358
|
claimable?: boolean
|
|
7289
7359
|
virtual?: boolean
|
|
7360
|
+
core?: ProofWrite
|
|
7361
|
+
* @deprecated On the request body this is folded into the **values bag**
|
|
7362
|
+
* (public + owner-writable) — NOT `proof.data`. Use `proof.data`.
|
|
7363
|
+
data?: Record<string, JsonValue>
|
|
7364
|
+
admin?: Record<string, JsonValue>
|
|
7290
7365
|
}
|
|
7291
7366
|
```
|
|
7292
7367
|
|
|
@@ -7343,7 +7418,7 @@ interface RedeemGrantOptions {
|
|
|
7343
7418
|
|
|
7344
7419
|
**ProofResponse** = `Proof`
|
|
7345
7420
|
|
|
7346
|
-
**ProofUpdateRequest** = `Partial<
|
|
7421
|
+
**ProofUpdateRequest** = `Partial<ProofWrite> & { proof?: ProofWrite }`
|
|
7347
7422
|
|
|
7348
7423
|
**ProofClaimRequest** = `Record<string, any>`
|
|
7349
7424
|
|
|
@@ -8748,10 +8823,10 @@ Gets current account information for the logged in user. Returns user, owner, ac
|
|
|
8748
8823
|
### authKit
|
|
8749
8824
|
|
|
8750
8825
|
**login**(clientId: string, email: string, password: string, trustedDeviceToken?: string) → `Promise<AuthLoginResponse>`
|
|
8751
|
-
Login with email + password (public). When the client's MFA policy requires a step-up, the server returns **403 `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in `err.details` (see {@link MfaRequiredDetails}). Route the caller to {@link mfaChallengeSend} on that error; this method's return type is unchanged. returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with `trustDevice: true`), pass it here to skip the challenge entirely as long as it's still valid. If it's revoked/expired, the server silently falls back to requiring a fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
8826
|
+
Login with email + password (public). When the client's MFA policy requires a step-up, the server returns **403 `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in `err.details` (see {@link MfaRequiredDetails}). Route the caller to {@link mfaChallengeSend} on that error; this method's return type is unchanged. returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with `trustDevice: true`), pass it here to skip the challenge entirely as long as it's still valid. If it's revoked/expired, the server silently falls back to requiring a fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling. Security errors (thrown as `SmartlinksApiError`, see {@link LoginSecurityErrorCode}): - `ACCOUNT_TEMPORARILY_LOCKED` (429) — `err.details.retryAfterSeconds` says how long to wait. - `PASSWORD_EXPIRED` (403) — `err.details.resetToken` is short-lived; route into {@link completePasswordReset} to change the password in place.
|
|
8752
8827
|
|
|
8753
8828
|
**register**(clientId: string, data: { email: string; password: string; displayName?: string; accountData?: Record<string, any> }) → `Promise<AuthLoginResponse>`
|
|
8754
|
-
Register a new user (public). Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's nothing to challenge against.
|
|
8829
|
+
Register a new user (public). Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's nothing to challenge against. The new password is validated against the collection's `passwordPolicy` — may throw a {@link PasswordPolicyErrorCode} (400). The same validation applies to {@link completePasswordReset} and {@link changePassword}. Read the policy for a live checklist from `authKit.load(clientId)` → `config.security.passwordPolicy`.
|
|
8755
8830
|
|
|
8756
8831
|
**googleLogin**(clientId: string, idToken: string, trustedDeviceToken?: string) → `Promise<AuthLoginResponse>`
|
|
8757
8832
|
Google OAuth login via ID token (public). Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. {@link mfaChallengeVerify}/{@link mfaRecoveryCode} (with `trustDevice: true`) to skip the challenge on this device, same as {@link login}.
|
|
@@ -9952,14 +10027,14 @@ List all Proofs for a Collection.
|
|
|
9952
10027
|
|
|
9953
10028
|
**create**(collectionId: string,
|
|
9954
10029
|
productId: string,
|
|
9955
|
-
|
|
9956
|
-
Create a proof for a product (admin only). POST /admin/collection/:collectionId/product/:productId/proof
|
|
10030
|
+
request: ProofCreateRequest) → `Promise<ProofResponse>`
|
|
10031
|
+
Create a proof for a product (admin only). POST /admin/collection/:collectionId/product/:productId/proof Pass the proof's content in a `proof` block, keyed by zone (see {@link ProofWrite}): ```ts proof.create(collectionId, productId, { proof: { values: { colour: 'red' }, // public + owner readable, owner + admin writable data: { serialNo: 1001 }, // public + owner readable, ADMIN-only writable admin: { costPrice: 4.20 }, // admin-only }, claimable: true, }) ``` Note: a top-level `data`/`admin` on the request body is legacy — top-level `data` gets folded into the values bag, so use `proof.data` for `proof.data`.
|
|
9957
10032
|
|
|
9958
10033
|
**update**(collectionId: string,
|
|
9959
10034
|
productId: string,
|
|
9960
10035
|
proofId: string,
|
|
9961
10036
|
values: ProofUpdateRequest) → `Promise<ProofResponse>`
|
|
9962
|
-
Update a proof for a product (admin only). PUT /admin/collection/:collectionId/product/:productId/proof/:proofId
|
|
10037
|
+
Update a proof for a product (admin only). PUT /admin/collection/:collectionId/product/:productId/proof/:proofId Pass the fields to change **at the root**, keyed by zone (see {@link ProofWrite}): ```ts proof.update(collectionId, productId, proofId, { data: { serialNo: 1002 }, // → proof.data (admin-only writable) values: { colour: 'blue' }, // → proof.values }) ``` Object zones deep-merge, so you can change one field without wiping the rest.
|
|
9963
10038
|
|
|
9964
10039
|
**claim**(collectionId: string,
|
|
9965
10040
|
productId: string,
|
package/dist/docs/auth-kit.md
CHANGED
|
@@ -502,6 +502,79 @@ await authKit.completePasswordReset(clientId, tokenFromUrl, 'newSecurePassword')
|
|
|
502
502
|
|
|
503
503
|
---
|
|
504
504
|
|
|
505
|
+
## Account security policy
|
|
506
|
+
|
|
507
|
+
Each collection can configure account-security rules (via the admin console). **The API
|
|
508
|
+
enforces all of it**; your login UI reads the policy for UX only (a live password checklist,
|
|
509
|
+
idle sign-out). Read it from the config:
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
const config = await authKit.load(clientId);
|
|
513
|
+
const policy = config.security?.passwordPolicy; // min length, char classes, block-common
|
|
514
|
+
const session = config.security?.session; // inactivity + absolute timeouts, rememberMe
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
`lockout` values are admin-only and never returned here.
|
|
518
|
+
|
|
519
|
+
### Password policy
|
|
520
|
+
|
|
521
|
+
`register`, `completePasswordReset`, and `changePassword` validate the new password
|
|
522
|
+
server-side and throw a `SmartlinksApiError` with a {@link PasswordPolicyErrorCode}:
|
|
523
|
+
|
|
524
|
+
| `errorCode` (400) | Meaning |
|
|
525
|
+
|---|---|
|
|
526
|
+
| `PASSWORD_TOO_SHORT` | below `minLength` |
|
|
527
|
+
| `PASSWORD_REQUIREMENTS_NOT_MET` | missing a required character class |
|
|
528
|
+
| `PASSWORD_TOO_COMMON` | on the common/breached list |
|
|
529
|
+
| `PASSWORD_RECENTLY_USED` | matched one of the last `historyCount` passwords |
|
|
530
|
+
|
|
531
|
+
Render a live checklist from `policy` so users see the rules before submitting.
|
|
532
|
+
|
|
533
|
+
### Lockout
|
|
534
|
+
|
|
535
|
+
After too many failed logins the account is temporarily locked. `login` throws:
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
try {
|
|
539
|
+
await authKit.login(clientId, email, password);
|
|
540
|
+
} catch (err) {
|
|
541
|
+
if (err.errorCode === 'ACCOUNT_TEMPORARILY_LOCKED') {
|
|
542
|
+
const mins = Math.ceil(err.details.retryAfterSeconds / 60);
|
|
543
|
+
show(`Too many attempts. Try again in ${mins} minute(s).`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Failed MFA challenges count toward the same lock. Locking responds identically for unknown
|
|
549
|
+
accounts (no enumeration).
|
|
550
|
+
|
|
551
|
+
### Password expiry
|
|
552
|
+
|
|
553
|
+
If a password is older than `passwordPolicy.expiryDays`, a valid login is refused with
|
|
554
|
+
**403 `PASSWORD_EXPIRED`** carrying a short-lived `resetToken` — send the user straight into
|
|
555
|
+
the reset form to change it in place:
|
|
556
|
+
|
|
557
|
+
```ts
|
|
558
|
+
catch (err) {
|
|
559
|
+
if (err.errorCode === 'PASSWORD_EXPIRED') {
|
|
560
|
+
await authKit.completePasswordReset(clientId, err.details.resetToken, newPassword);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Session lifetime
|
|
566
|
+
|
|
567
|
+
- **Absolute timeout** (`session.absoluteTimeoutHours`) is enforced server-side on the native
|
|
568
|
+
refresh path: once the session is too old, `refreshToken` throws **401 `SESSION_EXPIRED`**
|
|
569
|
+
(see {@link RefreshErrorCode}) — clear storage and route to login. Web sessions use the
|
|
570
|
+
stateless bearer token and rely on inactivity sign-out below.
|
|
571
|
+
- **Inactivity timeout** (`session.inactivityTimeoutMinutes` / `inactivityWarningSeconds`) is
|
|
572
|
+
**client-enforced** — sign the user out after idle, warning first. Sync across tabs.
|
|
573
|
+
- **`session.rememberMe: false`** → don't persist tokens to durable storage; treat the session
|
|
574
|
+
as browser-scoped.
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
505
578
|
## Relationship to other parts of the SDK
|
|
506
579
|
|
|
507
580
|
| Concern | Where it lives |
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type { AdditionalGtin, ISODateString, JsonPrimitive, JsonValue, ProductCr
|
|
|
17
17
|
export type { TranslationLookupMode, TranslationContentType, TranslationQuality, TranslationItemStatus, TranslationContextValue, TranslationContext, TranslationLookupRequestBase, TranslationLookupSingleRequest, TranslationLookupBatchRequest, TranslationLookupRequest, TranslationLookupItem, TranslationLookupResponse, ResolvedTranslationItem, ResolvedTranslationResponse, TranslationHashOptions, TranslationResolveOptions, TranslationRecord, TranslationListParams, TranslationListResponse, TranslationUpdateRequest, } from "./types/translations";
|
|
18
18
|
export type { FacetBucket, FacetDefinition, FacetDefinitionWriteInput, FacetGetParams, FacetListParams, FacetListResponse, FacetNamespaceListResponse, FacetQueryRequest, FacetQueryResponse, FacetValue, FacetValueDefinition, FacetValueGetParams, FacetValueListParams, FacetValueListResponse, FacetValueResponse, FacetValueWriteInput, PublicFacetListParams, } from "./types/facets";
|
|
19
19
|
export type { Collection, CollectionResponse, CollectionCreateRequest, CollectionUpdateRequest, DomainTarget, HubAvailabilityResponse, } from "./types/collection";
|
|
20
|
-
export type { Proof, ProofResponse, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, ProofGrant, GrantScope, GrantAudience, CreateGrantOptions, RedeemGrantOptions, RedeemGrantResult, } from "./types/proof";
|
|
20
|
+
export type { Proof, ProofResponse, ProofWrite, ProofCreateRequest, ProofUpdateRequest, ProofClaimRequest, ProofGrant, GrantScope, GrantAudience, CreateGrantOptions, RedeemGrantOptions, RedeemGrantResult, } from "./types/proof";
|
|
21
21
|
export type { QrShortCodeLookupResponse, } from "./types/qr";
|
|
22
22
|
export type { ReverseTagLookupParams, ReverseTagLookupResponse, } from "./types/tags";
|
|
23
23
|
export type { AdminMobileCapability, ActionableCapability, AdminMobileHostId, AdminMobileEvent, AdminMobileEventCallback, AdminMobileEventSubscriber, ScannerEventSubscriber, // @deprecated — use AdminMobileEventCallback
|
|
@@ -25,4 +25,4 @@ AdminMobileHostContext, AdminMobileComponentManifest, AdminMobileBundleManifest,
|
|
|
25
25
|
MobileAdminBundleManifest, } from './mobile-admin/types';
|
|
26
26
|
export { HostCapabilityUnavailableError, HostPermissionDeniedError, HostTimeoutError, } from './mobile-admin/errors';
|
|
27
27
|
export type { NativeCapability, NativeFacade, ShareFacade, ClipboardFacade, HapticImpactStyle, HapticNotificationStyle, HapticsFacade, NetworkStatus, NetworkFacade, DeviceInfo, DeviceFacade, StorageFacade, QrScanOptions, QrFacade, AuthFacade, NfcReadResult, NfcFacade, RfidScanOptions, RfidFacade, EventsFacade, WebSourceMode, WebSourceConfig, WebSourceFacade, } from './native/types';
|
|
28
|
-
export type { AuthKitUser, UserProfile, ProfileUpdateData, UpdateProfileResponse, SuccessResponse, AuthLoginResponse, AppleLoginOptions, AuthKitErrorCode, RefreshResponse, LogoutResponse, RefreshErrorCode, MagicLinkSendResponse, MagicLinkVerifyResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, VerifyStatus, WhatsAppReplyCta, WhatsAppReplyOptions, WhatsAppContactData, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, AuthKitBrandingConfig, AuthKitConfig, } from './types/authKit';
|
|
28
|
+
export type { AuthKitUser, UserProfile, ProfileUpdateData, UpdateProfileResponse, SuccessResponse, AuthLoginResponse, AppleLoginOptions, AuthKitErrorCode, RefreshResponse, LogoutResponse, RefreshErrorCode, MagicLinkSendResponse, MagicLinkVerifyResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, VerifyStatus, WhatsAppReplyCta, WhatsAppReplyOptions, WhatsAppContactData, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, AuthKitBrandingConfig, AuthKitConfig, AuthKitSecurityConfig, AuthKitPasswordPolicy, AuthKitSessionPolicy, AuthKitLockoutPolicy, PasswordPolicyErrorCode, LoginSecurityErrorCode, } from './types/authKit';
|
package/dist/openapi.yaml
CHANGED
|
@@ -8401,7 +8401,7 @@ paths:
|
|
|
8401
8401
|
post:
|
|
8402
8402
|
tags:
|
|
8403
8403
|
- authKit
|
|
8404
|
-
summary:
|
|
8404
|
+
summary: authKit.login
|
|
8405
8405
|
operationId: authKit_login
|
|
8406
8406
|
security: []
|
|
8407
8407
|
parameters:
|
|
@@ -19381,8 +19381,69 @@ components:
|
|
|
19381
19381
|
type: string
|
|
19382
19382
|
updatedAt:
|
|
19383
19383
|
type: string
|
|
19384
|
+
security:
|
|
19385
|
+
$ref: "#/components/schemas/AuthKitSecurityConfig"
|
|
19384
19386
|
required:
|
|
19385
19387
|
- id
|
|
19388
|
+
AuthKitSecurityConfig:
|
|
19389
|
+
type: object
|
|
19390
|
+
properties:
|
|
19391
|
+
passwordPolicy:
|
|
19392
|
+
$ref: "#/components/schemas/AuthKitPasswordPolicy"
|
|
19393
|
+
session:
|
|
19394
|
+
$ref: "#/components/schemas/AuthKitSessionPolicy"
|
|
19395
|
+
lockout:
|
|
19396
|
+
$ref: "#/components/schemas/AuthKitLockoutPolicy"
|
|
19397
|
+
AuthKitPasswordPolicy:
|
|
19398
|
+
type: object
|
|
19399
|
+
properties:
|
|
19400
|
+
minLength:
|
|
19401
|
+
type: number
|
|
19402
|
+
requireUppercase:
|
|
19403
|
+
type: boolean
|
|
19404
|
+
requireLowercase:
|
|
19405
|
+
type: boolean
|
|
19406
|
+
requireNumber:
|
|
19407
|
+
type: boolean
|
|
19408
|
+
requireSymbol:
|
|
19409
|
+
type: boolean
|
|
19410
|
+
blockCommonPasswords:
|
|
19411
|
+
type: boolean
|
|
19412
|
+
expiryDays:
|
|
19413
|
+
type: number
|
|
19414
|
+
historyCount:
|
|
19415
|
+
type: number
|
|
19416
|
+
AuthKitSessionPolicy:
|
|
19417
|
+
type: object
|
|
19418
|
+
properties:
|
|
19419
|
+
inactivityTimeoutMinutes:
|
|
19420
|
+
type: number
|
|
19421
|
+
inactivityWarningSeconds:
|
|
19422
|
+
type: number
|
|
19423
|
+
absoluteTimeoutHours:
|
|
19424
|
+
type: number
|
|
19425
|
+
rememberMe:
|
|
19426
|
+
type: boolean
|
|
19427
|
+
AuthKitLockoutPolicy:
|
|
19428
|
+
type: object
|
|
19429
|
+
properties:
|
|
19430
|
+
enabled:
|
|
19431
|
+
type: boolean
|
|
19432
|
+
maxFailedAttempts:
|
|
19433
|
+
type: number
|
|
19434
|
+
attemptWindowMinutes:
|
|
19435
|
+
type: number
|
|
19436
|
+
lockoutMinutes:
|
|
19437
|
+
type: number
|
|
19438
|
+
notifyUserOnLockout:
|
|
19439
|
+
type: boolean
|
|
19440
|
+
PasswordPolicyErrorCode:
|
|
19441
|
+
type: string
|
|
19442
|
+
enum:
|
|
19443
|
+
- PASSWORD_TOO_SHORT
|
|
19444
|
+
- PASSWORD_REQUIREMENTS_NOT_MET
|
|
19445
|
+
- PASSWORD_TOO_COMMON
|
|
19446
|
+
- PASSWORD_RECENTLY_USED
|
|
19386
19447
|
FirebaseTimestamp:
|
|
19387
19448
|
type: object
|
|
19388
19449
|
properties:
|
|
@@ -24994,9 +25055,11 @@ components:
|
|
|
24994
25055
|
- tokenId
|
|
24995
25056
|
- userId
|
|
24996
25057
|
- values
|
|
24997
|
-
|
|
25058
|
+
ProofWrite:
|
|
24998
25059
|
type: object
|
|
24999
25060
|
properties:
|
|
25061
|
+
id:
|
|
25062
|
+
type: string
|
|
25000
25063
|
values:
|
|
25001
25064
|
$ref: "#/components/schemas/ProofValues"
|
|
25002
25065
|
data:
|
|
@@ -25007,12 +25070,33 @@ components:
|
|
|
25007
25070
|
type: object
|
|
25008
25071
|
additionalProperties:
|
|
25009
25072
|
$ref: "#/components/schemas/JsonValue"
|
|
25073
|
+
owner:
|
|
25074
|
+
type: object
|
|
25075
|
+
additionalProperties:
|
|
25076
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25077
|
+
claimable:
|
|
25078
|
+
type: boolean
|
|
25079
|
+
ProofCreateRequest:
|
|
25080
|
+
type: object
|
|
25081
|
+
properties:
|
|
25082
|
+
proof:
|
|
25083
|
+
$ref: "#/components/schemas/ProofWrite"
|
|
25084
|
+
values:
|
|
25085
|
+
$ref: "#/components/schemas/ProofValues"
|
|
25010
25086
|
claimable:
|
|
25011
25087
|
type: boolean
|
|
25012
25088
|
virtual:
|
|
25013
25089
|
type: boolean
|
|
25014
|
-
|
|
25015
|
-
|
|
25090
|
+
core:
|
|
25091
|
+
$ref: "#/components/schemas/ProofWrite"
|
|
25092
|
+
data:
|
|
25093
|
+
type: object
|
|
25094
|
+
additionalProperties:
|
|
25095
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25096
|
+
admin:
|
|
25097
|
+
type: object
|
|
25098
|
+
additionalProperties:
|
|
25099
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25016
25100
|
ProofFieldsConfig:
|
|
25017
25101
|
type: object
|
|
25018
25102
|
properties:
|
|
@@ -25096,9 +25180,6 @@ components:
|
|
|
25096
25180
|
properties:
|
|
25097
25181
|
guestName:
|
|
25098
25182
|
type: string
|
|
25099
|
-
ProofResponse:
|
|
25100
|
-
type: object
|
|
25101
|
-
additionalProperties: true
|
|
25102
25183
|
QrShortCodeLookupResponse:
|
|
25103
25184
|
type: object
|
|
25104
25185
|
properties:
|
package/dist/types/authKit.d.ts
CHANGED
|
@@ -89,8 +89,11 @@ export interface LogoutResponse {
|
|
|
89
89
|
* - `INVALID_REFRESH_TOKEN` (401) — unknown / expired / revoked / wrong client → `logout()` + route to login.
|
|
90
90
|
* - `REFRESH_TOKEN_REUSE_DETECTED` (401) — a consumed token was replayed; the **entire session
|
|
91
91
|
* family was revoked server-side**. Hard logout: clear storage, force re-login.
|
|
92
|
+
* - `SESSION_EXPIRED` (401) — the session hit the collection's absolute session timeout
|
|
93
|
+
* (`security.session.absoluteTimeoutHours`). Clear storage and route to login. Distinct from
|
|
94
|
+
* `INVALID_REFRESH_TOKEN` so the UI can message "your session expired" rather than an error.
|
|
92
95
|
*/
|
|
93
|
-
export type RefreshErrorCode = 'MISSING_REFRESH_TOKEN' | 'INVALID_REFRESH_TOKEN' | 'REFRESH_TOKEN_REUSE_DETECTED';
|
|
96
|
+
export type RefreshErrorCode = 'MISSING_REFRESH_TOKEN' | 'INVALID_REFRESH_TOKEN' | 'REFRESH_TOKEN_REUSE_DETECTED' | 'SESSION_EXPIRED';
|
|
94
97
|
/**
|
|
95
98
|
* Options for {@link authKit.appleLogin}. All fields are optional — only the
|
|
96
99
|
* `identityToken` (passed as a positional argument) is required by the server.
|
|
@@ -397,4 +400,67 @@ export interface AuthKitConfig {
|
|
|
397
400
|
supportEmail?: string;
|
|
398
401
|
redirectUrl?: string;
|
|
399
402
|
updatedAt?: string;
|
|
403
|
+
/**
|
|
404
|
+
* Per-collection security policy. On the public config endpoint only
|
|
405
|
+
* `passwordPolicy` + `session` are returned (the client renders password
|
|
406
|
+
* checklists / idle sign-out from them); `lockout` is admin-only and enforced
|
|
407
|
+
* server-side. See {@link AuthKitSecurityConfig}.
|
|
408
|
+
*/
|
|
409
|
+
security?: AuthKitSecurityConfig;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Per-collection account-security policy. The API **enforces** all of this; the
|
|
413
|
+
* client uses `passwordPolicy` (live checklist) and `session` (idle sign-out) for UX.
|
|
414
|
+
*/
|
|
415
|
+
export interface AuthKitSecurityConfig {
|
|
416
|
+
passwordPolicy?: AuthKitPasswordPolicy;
|
|
417
|
+
session?: AuthKitSessionPolicy;
|
|
418
|
+
/** Admin-only; never returned on the public config endpoint. */
|
|
419
|
+
lockout?: AuthKitLockoutPolicy;
|
|
420
|
+
}
|
|
421
|
+
export interface AuthKitPasswordPolicy {
|
|
422
|
+
minLength?: number;
|
|
423
|
+
requireUppercase?: boolean;
|
|
424
|
+
requireLowercase?: boolean;
|
|
425
|
+
requireNumber?: boolean;
|
|
426
|
+
requireSymbol?: boolean;
|
|
427
|
+
blockCommonPasswords?: boolean;
|
|
428
|
+
/** 0 = never expires. */
|
|
429
|
+
expiryDays?: number;
|
|
430
|
+
/** 0 = reuse allowed. */
|
|
431
|
+
historyCount?: number;
|
|
432
|
+
}
|
|
433
|
+
export interface AuthKitSessionPolicy {
|
|
434
|
+
/** 0 = never (client-enforced idle sign-out). */
|
|
435
|
+
inactivityTimeoutMinutes?: number;
|
|
436
|
+
inactivityWarningSeconds?: number;
|
|
437
|
+
/** 0 = use token lifetime. Enforced server-side on the native refresh path (→ `SESSION_EXPIRED`). */
|
|
438
|
+
absoluteTimeoutHours?: number;
|
|
439
|
+
rememberMe?: boolean;
|
|
440
|
+
}
|
|
441
|
+
/** Admin-only lockout policy (operational; not exposed publicly). */
|
|
442
|
+
export interface AuthKitLockoutPolicy {
|
|
443
|
+
enabled?: boolean;
|
|
444
|
+
maxFailedAttempts?: number;
|
|
445
|
+
attemptWindowMinutes?: number;
|
|
446
|
+
lockoutMinutes?: number;
|
|
447
|
+
notifyUserOnLockout?: boolean;
|
|
400
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Password-policy validation errors (400) returned by `register`, `completePasswordReset`,
|
|
451
|
+
* and `changePassword`. Surfaced via `SmartlinksApiError.errorCode`.
|
|
452
|
+
* - `PASSWORD_TOO_SHORT` — below `passwordPolicy.minLength`.
|
|
453
|
+
* - `PASSWORD_REQUIREMENTS_NOT_MET` — missing a required character class.
|
|
454
|
+
* - `PASSWORD_TOO_COMMON` — matched the common/breached list.
|
|
455
|
+
* - `PASSWORD_RECENTLY_USED` — matched one of the last `historyCount` passwords.
|
|
456
|
+
*/
|
|
457
|
+
export type PasswordPolicyErrorCode = 'PASSWORD_TOO_SHORT' | 'PASSWORD_REQUIREMENTS_NOT_MET' | 'PASSWORD_TOO_COMMON' | 'PASSWORD_RECENTLY_USED';
|
|
458
|
+
/**
|
|
459
|
+
* Security errors returned by `login`. Surfaced via `SmartlinksApiError.errorCode`,
|
|
460
|
+
* with extra fields in `SmartlinksApiError.details`:
|
|
461
|
+
* - `ACCOUNT_TEMPORARILY_LOCKED` (429) — too many failed attempts; `details.retryAfterSeconds`
|
|
462
|
+
* says how long to wait. Show a "try again in N minutes" message.
|
|
463
|
+
* - `PASSWORD_EXPIRED` (403) — password older than `passwordPolicy.expiryDays`; `details.resetToken`
|
|
464
|
+
* is a short-lived token — send the user straight into `completePasswordReset()` to change it in place.
|
|
465
|
+
*/
|
|
466
|
+
export type LoginSecurityErrorCode = 'ACCOUNT_TEMPORARILY_LOCKED' | 'PASSWORD_EXPIRED';
|
package/dist/types/proof.d.ts
CHANGED
|
@@ -40,16 +40,71 @@ export interface Proof {
|
|
|
40
40
|
values: ProofValues;
|
|
41
41
|
}
|
|
42
42
|
export type ProofResponse = Proof;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
/**
|
|
44
|
+
* The proof's writable content, addressed by zone. Its keys mirror the proof
|
|
45
|
+
* document, so what you pass is what the proof looks like. Each zone has its own
|
|
46
|
+
* read/write visibility:
|
|
47
|
+
*
|
|
48
|
+
* | Zone | Stored at | Readable by | Writable by |
|
|
49
|
+
* |----------|----------------|------------------------|---------------|
|
|
50
|
+
* | `values` | `proof.values` | public + owner + admin | owner + admin |
|
|
51
|
+
* | `data` | `proof.data` | public + owner + admin | admin only |
|
|
52
|
+
* | `admin` | `proof.admin` | admin only | admin only |
|
|
53
|
+
* | `owner` | `proof.owner` | admin only | admin only |
|
|
54
|
+
*
|
|
55
|
+
* Use `data` for business fields everyone should *see* but only the business
|
|
56
|
+
* should *set* (e.g. a serial number). Use `admin` for fields only the business
|
|
57
|
+
* should see at all. On update, object zones deep-merge.
|
|
58
|
+
*/
|
|
59
|
+
export interface ProofWrite {
|
|
60
|
+
/**
|
|
61
|
+
* Choose the proof's ID (serial, NFC id, etc.). Honoured **on create only** —
|
|
62
|
+
* the ledger doc becomes `{productId}-{id}`. Omit to auto-generate. Ignored on
|
|
63
|
+
* update (a proof's ID is immutable).
|
|
64
|
+
*/
|
|
65
|
+
id?: string;
|
|
66
|
+
/** Owner + business-writable consumer data. Public + owner readable. → `proof.values` */
|
|
67
|
+
values?: ProofValues;
|
|
68
|
+
/** Business spec data (e.g. serialNo). Public + owner readable, admin-only writable. → `proof.data` */
|
|
46
69
|
data?: Record<string, JsonValue>;
|
|
47
|
-
/** Business-only spec data. */
|
|
70
|
+
/** Business-only spec data — admin-only read & write (stripped from public + owner). → `proof.admin` */
|
|
48
71
|
admin?: Record<string, JsonValue>;
|
|
72
|
+
/** Business-only root data — admin-only. → `proof.owner` */
|
|
73
|
+
owner?: Record<string, JsonValue>;
|
|
74
|
+
/** Is this proof available to be claimed. */
|
|
75
|
+
claimable?: boolean;
|
|
76
|
+
/** Any other named root field. */
|
|
77
|
+
[key: string]: JsonValue | Record<string, JsonValue> | ProofValues | undefined;
|
|
78
|
+
}
|
|
79
|
+
export interface ProofCreateRequest {
|
|
80
|
+
/**
|
|
81
|
+
* The proof to create, by zone (mirrors the proof document). This is the clear,
|
|
82
|
+
* recommended shape — `create(collectionId, productId, { proof: {...} })`.
|
|
83
|
+
*/
|
|
84
|
+
proof?: ProofWrite;
|
|
85
|
+
/** Owner + business-writable consumer data (→ `proof.values`). Same as `proof.values`. */
|
|
86
|
+
values?: ProofValues;
|
|
87
|
+
/** Canonical root `claimable` flag (also accepted as `proof.claimable`). */
|
|
49
88
|
claimable?: boolean;
|
|
50
89
|
virtual?: boolean;
|
|
90
|
+
/** @deprecated Legacy alias for `proof`. Use `proof`. */
|
|
91
|
+
core?: ProofWrite;
|
|
92
|
+
/**
|
|
93
|
+
* @deprecated On the request body this is folded into the **values bag**
|
|
94
|
+
* (public + owner-writable) — NOT `proof.data`. Use `proof.data`.
|
|
95
|
+
*/
|
|
96
|
+
data?: Record<string, JsonValue>;
|
|
97
|
+
/** @deprecated Not routed to `proof.admin` on create — use `proof.admin`. */
|
|
98
|
+
admin?: Record<string, JsonValue>;
|
|
51
99
|
}
|
|
52
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Update passes the proof's fields **at the root** — `update(c, p, id, { data: {...} })`
|
|
102
|
+
* sets `proof.data`, `{ values: {...} }` sets `proof.values`, etc. (A `proof` block is
|
|
103
|
+
* also accepted and routed the same way.) Object zones deep-merge.
|
|
104
|
+
*/
|
|
105
|
+
export type ProofUpdateRequest = Partial<ProofWrite> & {
|
|
106
|
+
proof?: ProofWrite;
|
|
107
|
+
};
|
|
53
108
|
export type ProofClaimRequest = Record<string, any>;
|
|
54
109
|
/**
|
|
55
110
|
* `'public'` (default, omitted) reads/writes `proof.values[key]`.
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.15.
|
|
3
|
+
Version: 1.15.19 | Generated: 2026-08-20T18:06:08.134Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -3464,6 +3464,55 @@ interface AuthKitConfig {
|
|
|
3464
3464
|
supportEmail?: string
|
|
3465
3465
|
redirectUrl?: string
|
|
3466
3466
|
updatedAt?: string
|
|
3467
|
+
* Per-collection security policy. On the public config endpoint only
|
|
3468
|
+
* `passwordPolicy` + `session` are returned (the client renders password
|
|
3469
|
+
* checklists / idle sign-out from them); `lockout` is admin-only and enforced
|
|
3470
|
+
* server-side. See {@link AuthKitSecurityConfig}.
|
|
3471
|
+
security?: AuthKitSecurityConfig
|
|
3472
|
+
}
|
|
3473
|
+
```
|
|
3474
|
+
|
|
3475
|
+
**AuthKitSecurityConfig** (interface)
|
|
3476
|
+
```typescript
|
|
3477
|
+
interface AuthKitSecurityConfig {
|
|
3478
|
+
passwordPolicy?: AuthKitPasswordPolicy
|
|
3479
|
+
session?: AuthKitSessionPolicy
|
|
3480
|
+
lockout?: AuthKitLockoutPolicy
|
|
3481
|
+
}
|
|
3482
|
+
```
|
|
3483
|
+
|
|
3484
|
+
**AuthKitPasswordPolicy** (interface)
|
|
3485
|
+
```typescript
|
|
3486
|
+
interface AuthKitPasswordPolicy {
|
|
3487
|
+
minLength?: number
|
|
3488
|
+
requireUppercase?: boolean
|
|
3489
|
+
requireLowercase?: boolean
|
|
3490
|
+
requireNumber?: boolean
|
|
3491
|
+
requireSymbol?: boolean
|
|
3492
|
+
blockCommonPasswords?: boolean
|
|
3493
|
+
expiryDays?: number
|
|
3494
|
+
historyCount?: number
|
|
3495
|
+
}
|
|
3496
|
+
```
|
|
3497
|
+
|
|
3498
|
+
**AuthKitSessionPolicy** (interface)
|
|
3499
|
+
```typescript
|
|
3500
|
+
interface AuthKitSessionPolicy {
|
|
3501
|
+
inactivityTimeoutMinutes?: number
|
|
3502
|
+
inactivityWarningSeconds?: number
|
|
3503
|
+
absoluteTimeoutHours?: number
|
|
3504
|
+
rememberMe?: boolean
|
|
3505
|
+
}
|
|
3506
|
+
```
|
|
3507
|
+
|
|
3508
|
+
**AuthKitLockoutPolicy** (interface)
|
|
3509
|
+
```typescript
|
|
3510
|
+
interface AuthKitLockoutPolicy {
|
|
3511
|
+
enabled?: boolean
|
|
3512
|
+
maxFailedAttempts?: number
|
|
3513
|
+
attemptWindowMinutes?: number
|
|
3514
|
+
lockoutMinutes?: number
|
|
3515
|
+
notifyUserOnLockout?: boolean
|
|
3467
3516
|
}
|
|
3468
3517
|
```
|
|
3469
3518
|
|
|
@@ -3475,6 +3524,10 @@ interface AuthKitConfig {
|
|
|
3475
3524
|
|
|
3476
3525
|
**VerifyStatus** = `'pending' | 'verified' | 'failed' | 'expired' | 'unknown'`
|
|
3477
3526
|
|
|
3527
|
+
**PasswordPolicyErrorCode** = ``
|
|
3528
|
+
|
|
3529
|
+
**LoginSecurityErrorCode** = ``
|
|
3530
|
+
|
|
3478
3531
|
### batch
|
|
3479
3532
|
|
|
3480
3533
|
**FirebaseTimestamp** (interface)
|
|
@@ -7279,14 +7332,36 @@ interface Proof {
|
|
|
7279
7332
|
}
|
|
7280
7333
|
```
|
|
7281
7334
|
|
|
7282
|
-
**
|
|
7335
|
+
**ProofWrite** (interface)
|
|
7283
7336
|
```typescript
|
|
7284
|
-
interface
|
|
7285
|
-
|
|
7337
|
+
interface ProofWrite {
|
|
7338
|
+
* Choose the proof's ID (serial, NFC id, etc.). Honoured **on create only** —
|
|
7339
|
+
* the ledger doc becomes `{productId}-{id}`. Omit to auto-generate. Ignored on
|
|
7340
|
+
* update (a proof's ID is immutable).
|
|
7341
|
+
id?: string
|
|
7342
|
+
values?: ProofValues
|
|
7286
7343
|
data?: Record<string, JsonValue>
|
|
7287
7344
|
admin?: Record<string, JsonValue>
|
|
7345
|
+
owner?: Record<string, JsonValue>
|
|
7346
|
+
claimable?: boolean
|
|
7347
|
+
[key: string]: JsonValue | Record<string, JsonValue> | ProofValues | undefined
|
|
7348
|
+
}
|
|
7349
|
+
```
|
|
7350
|
+
|
|
7351
|
+
**ProofCreateRequest** (interface)
|
|
7352
|
+
```typescript
|
|
7353
|
+
interface ProofCreateRequest {
|
|
7354
|
+
* The proof to create, by zone (mirrors the proof document). This is the clear,
|
|
7355
|
+
* recommended shape — `create(collectionId, productId, { proof: {...} })`.
|
|
7356
|
+
proof?: ProofWrite
|
|
7357
|
+
values?: ProofValues
|
|
7288
7358
|
claimable?: boolean
|
|
7289
7359
|
virtual?: boolean
|
|
7360
|
+
core?: ProofWrite
|
|
7361
|
+
* @deprecated On the request body this is folded into the **values bag**
|
|
7362
|
+
* (public + owner-writable) — NOT `proof.data`. Use `proof.data`.
|
|
7363
|
+
data?: Record<string, JsonValue>
|
|
7364
|
+
admin?: Record<string, JsonValue>
|
|
7290
7365
|
}
|
|
7291
7366
|
```
|
|
7292
7367
|
|
|
@@ -7343,7 +7418,7 @@ interface RedeemGrantOptions {
|
|
|
7343
7418
|
|
|
7344
7419
|
**ProofResponse** = `Proof`
|
|
7345
7420
|
|
|
7346
|
-
**ProofUpdateRequest** = `Partial<
|
|
7421
|
+
**ProofUpdateRequest** = `Partial<ProofWrite> & { proof?: ProofWrite }`
|
|
7347
7422
|
|
|
7348
7423
|
**ProofClaimRequest** = `Record<string, any>`
|
|
7349
7424
|
|
|
@@ -8748,10 +8823,10 @@ Gets current account information for the logged in user. Returns user, owner, ac
|
|
|
8748
8823
|
### authKit
|
|
8749
8824
|
|
|
8750
8825
|
**login**(clientId: string, email: string, password: string, trustedDeviceToken?: string) → `Promise<AuthLoginResponse>`
|
|
8751
|
-
Login with email + password (public). When the client's MFA policy requires a step-up, the server returns **403 `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in `err.details` (see {@link MfaRequiredDetails}). Route the caller to {@link mfaChallengeSend} on that error; this method's return type is unchanged. returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with `trustDevice: true`), pass it here to skip the challenge entirely as long as it's still valid. If it's revoked/expired, the server silently falls back to requiring a fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling.
|
|
8826
|
+
Login with email + password (public). When the client's MFA policy requires a step-up, the server returns **403 `MFA_REQUIRED`** instead of a session — `login()` throws a `SmartlinksApiError` with `err.errorResponse?.errorCode === 'MFA_REQUIRED'` and the challenge details in `err.details` (see {@link MfaRequiredDetails}). Route the caller to {@link mfaChallengeSend} on that error; this method's return type is unchanged. returned one (via {@link mfaChallengeVerify}/{@link mfaRecoveryCode} with `trustDevice: true`), pass it here to skip the challenge entirely as long as it's still valid. If it's revoked/expired, the server silently falls back to requiring a fresh challenge — `login()` just returns `MFA_REQUIRED` again, no special handling. Security errors (thrown as `SmartlinksApiError`, see {@link LoginSecurityErrorCode}): - `ACCOUNT_TEMPORARILY_LOCKED` (429) — `err.details.retryAfterSeconds` says how long to wait. - `PASSWORD_EXPIRED` (403) — `err.details.resetToken` is short-lived; route into {@link completePasswordReset} to change the password in place.
|
|
8752
8827
|
|
|
8753
8828
|
**register**(clientId: string, data: { email: string; password: string; displayName?: string; accountData?: Record<string, any> }) → `Promise<AuthLoginResponse>`
|
|
8754
|
-
Register a new user (public). Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's nothing to challenge against.
|
|
8829
|
+
Register a new user (public). Not gated by step-up MFA — a brand-new user has no enrolled factors yet, so there's nothing to challenge against. The new password is validated against the collection's `passwordPolicy` — may throw a {@link PasswordPolicyErrorCode} (400). The same validation applies to {@link completePasswordReset} and {@link changePassword}. Read the policy for a live checklist from `authKit.load(clientId)` → `config.security.passwordPolicy`.
|
|
8755
8830
|
|
|
8756
8831
|
**googleLogin**(clientId: string, idToken: string, trustedDeviceToken?: string) → `Promise<AuthLoginResponse>`
|
|
8757
8832
|
Google OAuth login via ID token (public). Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. {@link mfaChallengeVerify}/{@link mfaRecoveryCode} (with `trustDevice: true`) to skip the challenge on this device, same as {@link login}.
|
|
@@ -9952,14 +10027,14 @@ List all Proofs for a Collection.
|
|
|
9952
10027
|
|
|
9953
10028
|
**create**(collectionId: string,
|
|
9954
10029
|
productId: string,
|
|
9955
|
-
|
|
9956
|
-
Create a proof for a product (admin only). POST /admin/collection/:collectionId/product/:productId/proof
|
|
10030
|
+
request: ProofCreateRequest) → `Promise<ProofResponse>`
|
|
10031
|
+
Create a proof for a product (admin only). POST /admin/collection/:collectionId/product/:productId/proof Pass the proof's content in a `proof` block, keyed by zone (see {@link ProofWrite}): ```ts proof.create(collectionId, productId, { proof: { values: { colour: 'red' }, // public + owner readable, owner + admin writable data: { serialNo: 1001 }, // public + owner readable, ADMIN-only writable admin: { costPrice: 4.20 }, // admin-only }, claimable: true, }) ``` Note: a top-level `data`/`admin` on the request body is legacy — top-level `data` gets folded into the values bag, so use `proof.data` for `proof.data`.
|
|
9957
10032
|
|
|
9958
10033
|
**update**(collectionId: string,
|
|
9959
10034
|
productId: string,
|
|
9960
10035
|
proofId: string,
|
|
9961
10036
|
values: ProofUpdateRequest) → `Promise<ProofResponse>`
|
|
9962
|
-
Update a proof for a product (admin only). PUT /admin/collection/:collectionId/product/:productId/proof/:proofId
|
|
10037
|
+
Update a proof for a product (admin only). PUT /admin/collection/:collectionId/product/:productId/proof/:proofId Pass the fields to change **at the root**, keyed by zone (see {@link ProofWrite}): ```ts proof.update(collectionId, productId, proofId, { data: { serialNo: 1002 }, // → proof.data (admin-only writable) values: { colour: 'blue' }, // → proof.values }) ``` Object zones deep-merge, so you can change one field without wiping the rest.
|
|
9963
10038
|
|
|
9964
10039
|
**claim**(collectionId: string,
|
|
9965
10040
|
productId: string,
|
package/docs/auth-kit.md
CHANGED
|
@@ -502,6 +502,79 @@ await authKit.completePasswordReset(clientId, tokenFromUrl, 'newSecurePassword')
|
|
|
502
502
|
|
|
503
503
|
---
|
|
504
504
|
|
|
505
|
+
## Account security policy
|
|
506
|
+
|
|
507
|
+
Each collection can configure account-security rules (via the admin console). **The API
|
|
508
|
+
enforces all of it**; your login UI reads the policy for UX only (a live password checklist,
|
|
509
|
+
idle sign-out). Read it from the config:
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
const config = await authKit.load(clientId);
|
|
513
|
+
const policy = config.security?.passwordPolicy; // min length, char classes, block-common
|
|
514
|
+
const session = config.security?.session; // inactivity + absolute timeouts, rememberMe
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
`lockout` values are admin-only and never returned here.
|
|
518
|
+
|
|
519
|
+
### Password policy
|
|
520
|
+
|
|
521
|
+
`register`, `completePasswordReset`, and `changePassword` validate the new password
|
|
522
|
+
server-side and throw a `SmartlinksApiError` with a {@link PasswordPolicyErrorCode}:
|
|
523
|
+
|
|
524
|
+
| `errorCode` (400) | Meaning |
|
|
525
|
+
|---|---|
|
|
526
|
+
| `PASSWORD_TOO_SHORT` | below `minLength` |
|
|
527
|
+
| `PASSWORD_REQUIREMENTS_NOT_MET` | missing a required character class |
|
|
528
|
+
| `PASSWORD_TOO_COMMON` | on the common/breached list |
|
|
529
|
+
| `PASSWORD_RECENTLY_USED` | matched one of the last `historyCount` passwords |
|
|
530
|
+
|
|
531
|
+
Render a live checklist from `policy` so users see the rules before submitting.
|
|
532
|
+
|
|
533
|
+
### Lockout
|
|
534
|
+
|
|
535
|
+
After too many failed logins the account is temporarily locked. `login` throws:
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
try {
|
|
539
|
+
await authKit.login(clientId, email, password);
|
|
540
|
+
} catch (err) {
|
|
541
|
+
if (err.errorCode === 'ACCOUNT_TEMPORARILY_LOCKED') {
|
|
542
|
+
const mins = Math.ceil(err.details.retryAfterSeconds / 60);
|
|
543
|
+
show(`Too many attempts. Try again in ${mins} minute(s).`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Failed MFA challenges count toward the same lock. Locking responds identically for unknown
|
|
549
|
+
accounts (no enumeration).
|
|
550
|
+
|
|
551
|
+
### Password expiry
|
|
552
|
+
|
|
553
|
+
If a password is older than `passwordPolicy.expiryDays`, a valid login is refused with
|
|
554
|
+
**403 `PASSWORD_EXPIRED`** carrying a short-lived `resetToken` — send the user straight into
|
|
555
|
+
the reset form to change it in place:
|
|
556
|
+
|
|
557
|
+
```ts
|
|
558
|
+
catch (err) {
|
|
559
|
+
if (err.errorCode === 'PASSWORD_EXPIRED') {
|
|
560
|
+
await authKit.completePasswordReset(clientId, err.details.resetToken, newPassword);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Session lifetime
|
|
566
|
+
|
|
567
|
+
- **Absolute timeout** (`session.absoluteTimeoutHours`) is enforced server-side on the native
|
|
568
|
+
refresh path: once the session is too old, `refreshToken` throws **401 `SESSION_EXPIRED`**
|
|
569
|
+
(see {@link RefreshErrorCode}) — clear storage and route to login. Web sessions use the
|
|
570
|
+
stateless bearer token and rely on inactivity sign-out below.
|
|
571
|
+
- **Inactivity timeout** (`session.inactivityTimeoutMinutes` / `inactivityWarningSeconds`) is
|
|
572
|
+
**client-enforced** — sign the user out after idle, warning first. Sync across tabs.
|
|
573
|
+
- **`session.rememberMe: false`** → don't persist tokens to durable storage; treat the session
|
|
574
|
+
as browser-scoped.
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
505
578
|
## Relationship to other parts of the SDK
|
|
506
579
|
|
|
507
580
|
| Concern | Where it lives |
|
package/openapi.yaml
CHANGED
|
@@ -8401,7 +8401,7 @@ paths:
|
|
|
8401
8401
|
post:
|
|
8402
8402
|
tags:
|
|
8403
8403
|
- authKit
|
|
8404
|
-
summary:
|
|
8404
|
+
summary: authKit.login
|
|
8405
8405
|
operationId: authKit_login
|
|
8406
8406
|
security: []
|
|
8407
8407
|
parameters:
|
|
@@ -19381,8 +19381,69 @@ components:
|
|
|
19381
19381
|
type: string
|
|
19382
19382
|
updatedAt:
|
|
19383
19383
|
type: string
|
|
19384
|
+
security:
|
|
19385
|
+
$ref: "#/components/schemas/AuthKitSecurityConfig"
|
|
19384
19386
|
required:
|
|
19385
19387
|
- id
|
|
19388
|
+
AuthKitSecurityConfig:
|
|
19389
|
+
type: object
|
|
19390
|
+
properties:
|
|
19391
|
+
passwordPolicy:
|
|
19392
|
+
$ref: "#/components/schemas/AuthKitPasswordPolicy"
|
|
19393
|
+
session:
|
|
19394
|
+
$ref: "#/components/schemas/AuthKitSessionPolicy"
|
|
19395
|
+
lockout:
|
|
19396
|
+
$ref: "#/components/schemas/AuthKitLockoutPolicy"
|
|
19397
|
+
AuthKitPasswordPolicy:
|
|
19398
|
+
type: object
|
|
19399
|
+
properties:
|
|
19400
|
+
minLength:
|
|
19401
|
+
type: number
|
|
19402
|
+
requireUppercase:
|
|
19403
|
+
type: boolean
|
|
19404
|
+
requireLowercase:
|
|
19405
|
+
type: boolean
|
|
19406
|
+
requireNumber:
|
|
19407
|
+
type: boolean
|
|
19408
|
+
requireSymbol:
|
|
19409
|
+
type: boolean
|
|
19410
|
+
blockCommonPasswords:
|
|
19411
|
+
type: boolean
|
|
19412
|
+
expiryDays:
|
|
19413
|
+
type: number
|
|
19414
|
+
historyCount:
|
|
19415
|
+
type: number
|
|
19416
|
+
AuthKitSessionPolicy:
|
|
19417
|
+
type: object
|
|
19418
|
+
properties:
|
|
19419
|
+
inactivityTimeoutMinutes:
|
|
19420
|
+
type: number
|
|
19421
|
+
inactivityWarningSeconds:
|
|
19422
|
+
type: number
|
|
19423
|
+
absoluteTimeoutHours:
|
|
19424
|
+
type: number
|
|
19425
|
+
rememberMe:
|
|
19426
|
+
type: boolean
|
|
19427
|
+
AuthKitLockoutPolicy:
|
|
19428
|
+
type: object
|
|
19429
|
+
properties:
|
|
19430
|
+
enabled:
|
|
19431
|
+
type: boolean
|
|
19432
|
+
maxFailedAttempts:
|
|
19433
|
+
type: number
|
|
19434
|
+
attemptWindowMinutes:
|
|
19435
|
+
type: number
|
|
19436
|
+
lockoutMinutes:
|
|
19437
|
+
type: number
|
|
19438
|
+
notifyUserOnLockout:
|
|
19439
|
+
type: boolean
|
|
19440
|
+
PasswordPolicyErrorCode:
|
|
19441
|
+
type: string
|
|
19442
|
+
enum:
|
|
19443
|
+
- PASSWORD_TOO_SHORT
|
|
19444
|
+
- PASSWORD_REQUIREMENTS_NOT_MET
|
|
19445
|
+
- PASSWORD_TOO_COMMON
|
|
19446
|
+
- PASSWORD_RECENTLY_USED
|
|
19386
19447
|
FirebaseTimestamp:
|
|
19387
19448
|
type: object
|
|
19388
19449
|
properties:
|
|
@@ -24994,9 +25055,11 @@ components:
|
|
|
24994
25055
|
- tokenId
|
|
24995
25056
|
- userId
|
|
24996
25057
|
- values
|
|
24997
|
-
|
|
25058
|
+
ProofWrite:
|
|
24998
25059
|
type: object
|
|
24999
25060
|
properties:
|
|
25061
|
+
id:
|
|
25062
|
+
type: string
|
|
25000
25063
|
values:
|
|
25001
25064
|
$ref: "#/components/schemas/ProofValues"
|
|
25002
25065
|
data:
|
|
@@ -25007,12 +25070,33 @@ components:
|
|
|
25007
25070
|
type: object
|
|
25008
25071
|
additionalProperties:
|
|
25009
25072
|
$ref: "#/components/schemas/JsonValue"
|
|
25073
|
+
owner:
|
|
25074
|
+
type: object
|
|
25075
|
+
additionalProperties:
|
|
25076
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25077
|
+
claimable:
|
|
25078
|
+
type: boolean
|
|
25079
|
+
ProofCreateRequest:
|
|
25080
|
+
type: object
|
|
25081
|
+
properties:
|
|
25082
|
+
proof:
|
|
25083
|
+
$ref: "#/components/schemas/ProofWrite"
|
|
25084
|
+
values:
|
|
25085
|
+
$ref: "#/components/schemas/ProofValues"
|
|
25010
25086
|
claimable:
|
|
25011
25087
|
type: boolean
|
|
25012
25088
|
virtual:
|
|
25013
25089
|
type: boolean
|
|
25014
|
-
|
|
25015
|
-
|
|
25090
|
+
core:
|
|
25091
|
+
$ref: "#/components/schemas/ProofWrite"
|
|
25092
|
+
data:
|
|
25093
|
+
type: object
|
|
25094
|
+
additionalProperties:
|
|
25095
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25096
|
+
admin:
|
|
25097
|
+
type: object
|
|
25098
|
+
additionalProperties:
|
|
25099
|
+
$ref: "#/components/schemas/JsonValue"
|
|
25016
25100
|
ProofFieldsConfig:
|
|
25017
25101
|
type: object
|
|
25018
25102
|
properties:
|
|
@@ -25096,9 +25180,6 @@ components:
|
|
|
25096
25180
|
properties:
|
|
25097
25181
|
guestName:
|
|
25098
25182
|
type: string
|
|
25099
|
-
ProofResponse:
|
|
25100
|
-
type: object
|
|
25101
|
-
additionalProperties: true
|
|
25102
25183
|
QrShortCodeLookupResponse:
|
|
25103
25184
|
type: object
|
|
25104
25185
|
properties:
|