@sparkvault/sdk-mobile 6.0.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/account.d.ts +4 -3
- package/dist/account.js +16 -11
- package/dist/account.js.map +1 -1
- package/dist/app-sdk/email-address.d.ts +37 -0
- package/dist/app-sdk/email-address.js +91 -0
- package/dist/app-sdk/email-address.js.map +1 -0
- package/dist/app-sdk/encoding.d.ts +64 -0
- package/dist/app-sdk/encoding.js +245 -0
- package/dist/app-sdk/encoding.js.map +1 -0
- package/dist/app-sdk/entropy-contract.d.ts +33 -0
- package/dist/app-sdk/entropy-contract.js +51 -0
- package/dist/app-sdk/entropy-contract.js.map +1 -0
- package/dist/app-sdk/filename.d.ts +93 -0
- package/dist/app-sdk/filename.js +161 -0
- package/dist/app-sdk/filename.js.map +1 -0
- package/dist/app-sdk/forge-url.d.ts +107 -0
- package/dist/app-sdk/forge-url.js +222 -0
- package/dist/app-sdk/forge-url.js.map +1 -0
- package/dist/app-sdk/ids.d.ts +48 -0
- package/dist/app-sdk/ids.js +65 -0
- package/dist/app-sdk/ids.js.map +1 -0
- package/dist/app-sdk/ingot-access-log.d.ts +29 -0
- package/dist/app-sdk/ingot-access-log.js +49 -0
- package/dist/app-sdk/ingot-access-log.js.map +1 -0
- package/dist/app-sdk/phone.d.ts +37 -0
- package/dist/app-sdk/phone.js +134 -0
- package/dist/app-sdk/phone.js.map +1 -0
- package/dist/app-sdk/platform-domains.d.ts +41 -0
- package/dist/app-sdk/platform-domains.js +82 -0
- package/dist/app-sdk/platform-domains.js.map +1 -0
- package/dist/app-sdk/request-path.d.ts +49 -0
- package/dist/app-sdk/request-path.js +81 -0
- package/dist/app-sdk/request-path.js.map +1 -0
- package/dist/app-sdk/transient.d.ts +23 -0
- package/dist/app-sdk/transient.js +29 -0
- package/dist/app-sdk/transient.js.map +1 -0
- package/dist/app-sdk/vat-refusal.d.ts +66 -0
- package/dist/app-sdk/vat-refusal.js +69 -0
- package/dist/app-sdk/vat-refusal.js.map +1 -0
- package/dist/billing.d.ts +9 -17
- package/dist/billing.js +14 -17
- package/dist/billing.js.map +1 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.js +10 -17
- package/dist/config.js.map +1 -1
- package/dist/encoding.d.ts +30 -4
- package/dist/encoding.js +89 -83
- package/dist/encoding.js.map +1 -1
- package/dist/entropy.d.ts +25 -4
- package/dist/entropy.js +62 -15
- package/dist/entropy.js.map +1 -1
- package/dist/entropy.test-d.d.ts +40 -0
- package/dist/entropy.test-d.js +12 -0
- package/dist/entropy.test-d.js.map +1 -0
- package/dist/errors.d.ts +67 -17
- package/dist/errors.js +70 -27
- package/dist/errors.js.map +1 -1
- package/dist/folders.js +8 -7
- package/dist/folders.js.map +1 -1
- package/dist/http.d.ts +57 -15
- package/dist/http.js +125 -138
- package/dist/http.js.map +1 -1
- package/dist/identity-dialog.js +4 -30
- package/dist/identity-dialog.js.map +1 -1
- package/dist/identity-input.d.ts +39 -0
- package/dist/identity-input.js +59 -0
- package/dist/identity-input.js.map +1 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/ingots.d.ts +58 -19
- package/dist/ingots.js +145 -125
- package/dist/ingots.js.map +1 -1
- package/dist/mutex.d.ts +1 -2
- package/dist/mutex.js +0 -6
- package/dist/mutex.js.map +1 -1
- package/dist/notify.d.ts +7 -2
- package/dist/notify.js +12 -15
- package/dist/notify.js.map +1 -1
- package/dist/notify.test-d.d.ts +3 -2
- package/dist/notify.test-d.js +1 -1
- package/dist/products/identity.d.ts +5 -0
- package/dist/products/identity.js +40 -35
- package/dist/products/identity.js.map +1 -1
- package/dist/request-path.d.ts +32 -0
- package/dist/request-path.js +35 -0
- package/dist/request-path.js.map +1 -0
- package/dist/sparks.js +16 -15
- package/dist/sparks.js.map +1 -1
- package/dist/tus.d.ts +19 -2
- package/dist/tus.js +86 -35
- package/dist/tus.js.map +1 -1
- package/dist/types.d.ts +169 -15
- package/dist/users.d.ts +12 -5
- package/dist/users.js +27 -19
- package/dist/users.js.map +1 -1
- package/dist/validation.d.ts +20 -5
- package/dist/validation.js +29 -27
- package/dist/validation.js.map +1 -1
- package/dist/vaults.d.ts +34 -83
- package/dist/vaults.js +64 -44
- package/dist/vaults.js.map +1 -1
- package/dist/vaults.test-d.d.ts +22 -0
- package/dist/vaults.test-d.js +14 -0
- package/dist/vaults.test-d.js.map +1 -0
- package/package.json +4 -2
- package/src/account.ts +16 -11
- package/src/app-sdk/email-address.js +94 -0
- package/src/app-sdk/encoding.js +250 -0
- package/src/app-sdk/entropy-contract.js +56 -0
- package/src/app-sdk/filename.js +174 -0
- package/src/app-sdk/forge-url.js +224 -0
- package/src/app-sdk/ids.js +71 -0
- package/src/app-sdk/ingot-access-log.js +51 -0
- package/src/app-sdk/phone.js +139 -0
- package/src/app-sdk/platform-domains.js +99 -0
- package/src/app-sdk/request-path.js +81 -0
- package/src/app-sdk/transient.js +30 -0
- package/src/app-sdk/vat-refusal.js +74 -0
- package/src/billing.ts +16 -25
- package/src/config.ts +16 -23
- package/src/encoding.ts +91 -103
- package/src/entropy.test-d.ts +47 -0
- package/src/entropy.ts +86 -20
- package/src/errors.ts +93 -33
- package/src/folders.ts +8 -7
- package/src/http.ts +145 -150
- package/src/identity-dialog.tsx +4 -37
- package/src/identity-input.ts +70 -0
- package/src/index.ts +11 -3
- package/src/ingots.ts +191 -163
- package/src/mutex.ts +1 -8
- package/src/notify.test-d.ts +3 -1
- package/src/notify.ts +19 -17
- package/src/products/identity.ts +45 -39
- package/src/request-path.ts +45 -0
- package/src/sparks.ts +16 -13
- package/src/tus.ts +90 -37
- package/src/types.ts +167 -15
- package/src/users.ts +27 -17
- package/src/validation.ts +30 -24
- package/src/vaults.test-d.ts +29 -0
- package/src/vaults.ts +87 -153
- package/dist/platform-domains.generated.d.ts +0 -2
- package/dist/platform-domains.generated.js +0 -16
- package/dist/platform-domains.generated.js.map +0 -1
- package/src/platform-domains.generated.ts +0 -17
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ The SDK depends on `tweetnacl` for Ed25519 Identity JWT verification and declare
|
|
|
59
59
|
| Adapter | Required | Default if omitted |
|
|
60
60
|
|---------|----------|--------------------|
|
|
61
61
|
| `tokenStorage` | Yes | Throws at client construction |
|
|
62
|
-
| `identityAccountId` | Yes (
|
|
62
|
+
| `identityAccountId` | Yes (a SparkVault account id, `acc_…`, by the platform's resource-id grammar) | Throws at client construction |
|
|
63
63
|
| `fetch` | No | Falls back to `globalThis.fetch`; throws if neither exists |
|
|
64
64
|
| `fileReader` | Only for `ingots.uploadFromUri` | Throws on first upload-from-URI call |
|
|
65
65
|
| `fileDownloader` | Only for `ingots.downloadToFile` | Throws on first file-download call |
|
|
@@ -69,18 +69,18 @@ The SDK depends on `tweetnacl` for Ed25519 Identity JWT verification and declare
|
|
|
69
69
|
|
|
70
70
|
- `products.identity`: Identity Product config, OTP/passkey login, JWKS/JWT verification, second-factor submission, and post-login backup/recommendation flows.
|
|
71
71
|
- `account`: First-party Core session — Identity-token exchange, signup completion, profile, and account APIs.
|
|
72
|
-
- `vaults`: Vault CRUD, unseal
|
|
72
|
+
- `vaults`: Vault CRUD, unseal, ending one session (`endSession`) or every session (`seal`), sharing, access retention, and upload portal/widget settings.
|
|
73
73
|
- `folders`: Folder CRUD, breadcrumbs, folder moves, and ingot moves.
|
|
74
74
|
- `ingots`: List/search/get, URI streaming upload/replace, rename/delete/move, sharing, read-only audit logs, SDK-managed file downloads, and the discrete `createUpload` (Forge upload URL + token) / `createDownloadLink` primitives.
|
|
75
75
|
- `health`: Root API availability checks.
|
|
76
76
|
- `sparks`: SparkSync ephemeral secrets — list/get/create/delete and SparkLink sharing (`share`/`getShare`/`unshare`).
|
|
77
|
-
- `entropy`: HSM-backed entropy generation.
|
|
77
|
+
- `entropy`: HSM-backed entropy generation (`generate`, `generateBytes`), and `drawFirstParty` for the signed-in app's own working values (`POST /v1/entropy/first-party`: a SparkVault session's draw, never plan- or bandwidth-gated or recorded as the account's usage).
|
|
78
78
|
- `pushTokens`: Expo push-token registration/removal.
|
|
79
|
-
- `billing`: Subscription status and usage,
|
|
79
|
+
- `billing`: Subscription status and usage, and native in-app purchase receipt validation.
|
|
80
80
|
|
|
81
81
|
## Identity Dialog
|
|
82
82
|
|
|
83
|
-
`SparkVaultIdentityDialog` is the mobile equivalent of the web SDK Identity popup. It fetches Identity Product config, derives email/phone input from enabled delivery methods, offers the enabled one-time-code methods (`otp_email`, `otp_sms`, `otp_voice`), applies configured branding and light/dark mode, and returns the raw signed Identity JWT plus JWKS metadata. Configured branding drives the header: a logo replaces the company name and is drawn at its own proportions; without one (or if it fails to load) the header shows the company lettermark and name.
|
|
83
|
+
`SparkVaultIdentityDialog` is the mobile equivalent of the web SDK Identity popup. It fetches Identity Product config, derives email/phone input from enabled delivery methods, offers the enabled one-time-code methods (`otp_email`, `otp_sms`, `otp_voice`), applies configured branding and light/dark mode, and returns the raw signed Identity JWT plus JWKS metadata. Input reads as a phone number only when it has no `@` and holds phone characters only, so an email that starts with a digit (`2024user@gmail.com`) signs in by email; while email is enabled the field keeps the email keyboard. Configured branding drives the header: a logo replaces the company name and is drawn at its own proportions; without one (or if it fails to load) the header shows the company lettermark and name.
|
|
84
84
|
|
|
85
85
|
Sign-in is code-only. The native passkey ceremony does not work in the mobile app, so the dialog never offers `passkey` even when the tenant has it enabled; `products.identity` still exposes the passkey APIs for a host that drives the ceremony itself.
|
|
86
86
|
|
package/dist/account.d.ts
CHANGED
|
@@ -24,9 +24,10 @@ export declare class MobileAccountClient {
|
|
|
24
24
|
getAccount(): Promise<SparkVaultAccount>;
|
|
25
25
|
/**
|
|
26
26
|
* Update organization settings (member admins only). Sends a JSON body — the
|
|
27
|
-
* logo-upload variant of PUT /account is web-only. The PUT
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* logo-upload variant of PUT /account is web-only. The PUT answers with the
|
|
28
|
+
* account as it now stands (the same projection GET /account serves), which
|
|
29
|
+
* refreshes the cache as is: a read right after the write could land on a
|
|
30
|
+
* replica that has not seen it yet.
|
|
30
31
|
*/
|
|
31
32
|
updateAccount(updates: UpdateAccountRequest): Promise<SparkVaultAccount>;
|
|
32
33
|
revokeRefreshToken(refreshToken?: string): Promise<void>;
|
package/dist/account.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SparkVaultValidationError } from './errors.js';
|
|
2
|
+
import { apiPath } from './request-path.js';
|
|
2
3
|
/**
|
|
3
4
|
* First-party SparkVault Core session, profile, and account client. Exchanges a
|
|
4
5
|
* verified Identity token for an app session and owns the authenticated
|
|
@@ -10,7 +11,7 @@ export class MobileAccountClient {
|
|
|
10
11
|
this.http = http;
|
|
11
12
|
}
|
|
12
13
|
async exchangeIdentityToken(identityToken) {
|
|
13
|
-
const sessionResponse = await this.http.post(
|
|
14
|
+
const sessionResponse = await this.http.post(apiPath `/auth/identity/verify`, { token: identityToken }, { skipAuth: true });
|
|
14
15
|
const session = sessionResponse.data;
|
|
15
16
|
if (session.user) {
|
|
16
17
|
await this.storeSession(session);
|
|
@@ -30,7 +31,7 @@ export class MobileAccountClient {
|
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
async completeSignup(signupToken, request) {
|
|
33
|
-
const response = await this.http.post(
|
|
34
|
+
const response = await this.http.post(apiPath `/auth/complete-signup`, request, {
|
|
34
35
|
skipAuth: true,
|
|
35
36
|
headers: { Authorization: `Bearer ${signupToken}` },
|
|
36
37
|
});
|
|
@@ -44,21 +45,21 @@ export class MobileAccountClient {
|
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
async getProfile() {
|
|
47
|
-
const response = await this.http.get(
|
|
48
|
+
const response = await this.http.get(apiPath `/profile`);
|
|
48
49
|
if (this.config.tokenStorage.setUser) {
|
|
49
50
|
await this.config.tokenStorage.setUser(response.data);
|
|
50
51
|
}
|
|
51
52
|
return response.data;
|
|
52
53
|
}
|
|
53
54
|
async updateProfile(updates) {
|
|
54
|
-
const response = await this.http.put(
|
|
55
|
+
const response = await this.http.put(apiPath `/profile`, updates);
|
|
55
56
|
if (this.config.tokenStorage.setUser) {
|
|
56
57
|
await this.config.tokenStorage.setUser(response.data);
|
|
57
58
|
}
|
|
58
59
|
return response.data;
|
|
59
60
|
}
|
|
60
61
|
async getAccount() {
|
|
61
|
-
const response = await this.http.get(
|
|
62
|
+
const response = await this.http.get(apiPath `/account`);
|
|
62
63
|
if (this.config.tokenStorage.setAccount) {
|
|
63
64
|
await this.config.tokenStorage.setAccount(response.data);
|
|
64
65
|
}
|
|
@@ -66,19 +67,23 @@ export class MobileAccountClient {
|
|
|
66
67
|
}
|
|
67
68
|
/**
|
|
68
69
|
* Update organization settings (member admins only). Sends a JSON body — the
|
|
69
|
-
* logo-upload variant of PUT /account is web-only. The PUT
|
|
70
|
-
*
|
|
71
|
-
*
|
|
70
|
+
* logo-upload variant of PUT /account is web-only. The PUT answers with the
|
|
71
|
+
* account as it now stands (the same projection GET /account serves), which
|
|
72
|
+
* refreshes the cache as is: a read right after the write could land on a
|
|
73
|
+
* replica that has not seen it yet.
|
|
72
74
|
*/
|
|
73
75
|
async updateAccount(updates) {
|
|
74
|
-
await this.http.put(
|
|
75
|
-
|
|
76
|
+
const response = await this.http.put(apiPath `/account`, updates);
|
|
77
|
+
if (this.config.tokenStorage.setAccount) {
|
|
78
|
+
await this.config.tokenStorage.setAccount(response.data);
|
|
79
|
+
}
|
|
80
|
+
return response.data;
|
|
76
81
|
}
|
|
77
82
|
async revokeRefreshToken(refreshToken) {
|
|
78
83
|
const token = refreshToken ?? await this.config.tokenStorage.getRefreshToken();
|
|
79
84
|
if (!token)
|
|
80
85
|
return;
|
|
81
|
-
await this.http.post(
|
|
86
|
+
await this.http.post(apiPath `/auth/logout`, { refresh_token: token }).catch(err => {
|
|
82
87
|
this.config.logger.warn('Logout API call failed', { error: String(err) });
|
|
83
88
|
});
|
|
84
89
|
}
|
package/dist/account.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canonical form of an address: trimmed and lowercased.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} value
|
|
5
|
+
* @returns {string}
|
|
6
|
+
* @throws {TypeError} when `value` is not a string: it has no canonical form,
|
|
7
|
+
* and a caller that would key or compare by one must not carry on without it
|
|
8
|
+
*/
|
|
9
|
+
export function canonicalEmailAddress(value: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* What makes `value` an address SparkVault cannot deliver to, or null when
|
|
12
|
+
* nothing does.
|
|
13
|
+
*
|
|
14
|
+
* @param {*} value
|
|
15
|
+
* @returns {string|null} One of EMAIL_ADDRESS_PROBLEMS, or null
|
|
16
|
+
*/
|
|
17
|
+
export function emailAddressProblem(value: any): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Whether SparkVault can deliver to `value`.
|
|
20
|
+
*
|
|
21
|
+
* @param {*} value
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
export function isValidEmailAddress(value: any): boolean;
|
|
25
|
+
/** RFC 5321 length limits, in characters. */
|
|
26
|
+
export const EMAIL_ADDRESS_LIMITS: Readonly<{
|
|
27
|
+
ADDRESS: 320;
|
|
28
|
+
LOCAL_PART: 64;
|
|
29
|
+
DOMAIN: 255;
|
|
30
|
+
}>;
|
|
31
|
+
/** Why an address is not valid, as emailAddressProblem reports it. */
|
|
32
|
+
export const EMAIL_ADDRESS_PROBLEMS: Readonly<{
|
|
33
|
+
FORMAT: "format";
|
|
34
|
+
TOO_LONG: "too_long";
|
|
35
|
+
LOCAL_PART_TOO_LONG: "local_part_too_long";
|
|
36
|
+
DOMAIN_TOO_LONG: "domain_too_long";
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// GENERATED FILE — do not edit by hand.
|
|
2
|
+
// Source of truth: packages/app-sdk/src/email-address.js
|
|
3
|
+
// Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
|
|
4
|
+
/**
|
|
5
|
+
* The one email-address grammar: the addresses SparkVault can deliver to, so
|
|
6
|
+
* the only ones a front door may accept. A door that took an address the
|
|
7
|
+
* email transport then refuses answers its caller with a success while the
|
|
8
|
+
* recipient gets nothing (a Notify send, a SparkLink invite, a share), so the
|
|
9
|
+
* accepting doors and the transport ask this one question.
|
|
10
|
+
*
|
|
11
|
+
* An address is read in its canonical form (trimmed, lowercased) and is valid
|
|
12
|
+
* when it has an RFC 5322 dot-atom-text local part in ASCII, exactly one `@`,
|
|
13
|
+
* a domain of at least two labels of letters, digits and inner hyphens, and
|
|
14
|
+
* fits the RFC 5321 lengths (address 320, local part 64, domain 255).
|
|
15
|
+
*
|
|
16
|
+
* The canonical form is also the one every stored email key is spelled in:
|
|
17
|
+
* Identity's directory normalizes an email identifier through
|
|
18
|
+
* canonicalEmailAddress, and Core keys its account and login-claim rows and
|
|
19
|
+
* compares a signed-in address through it, so one spelling of an address
|
|
20
|
+
* finds every row another spelling wrote.
|
|
21
|
+
*
|
|
22
|
+
* Pure and import-free, so every runtime that decides deliverability loads it
|
|
23
|
+
* alike.
|
|
24
|
+
*/
|
|
25
|
+
const LOCAL_PART = /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/;
|
|
26
|
+
const DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
27
|
+
/** RFC 5321 length limits, in characters. */
|
|
28
|
+
export const EMAIL_ADDRESS_LIMITS = Object.freeze({
|
|
29
|
+
ADDRESS: 320,
|
|
30
|
+
LOCAL_PART: 64,
|
|
31
|
+
DOMAIN: 255
|
|
32
|
+
});
|
|
33
|
+
/** Why an address is not valid, as emailAddressProblem reports it. */
|
|
34
|
+
export const EMAIL_ADDRESS_PROBLEMS = Object.freeze({
|
|
35
|
+
FORMAT: 'format',
|
|
36
|
+
TOO_LONG: 'too_long',
|
|
37
|
+
LOCAL_PART_TOO_LONG: 'local_part_too_long',
|
|
38
|
+
DOMAIN_TOO_LONG: 'domain_too_long'
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* The canonical form of an address: trimmed and lowercased.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} value
|
|
44
|
+
* @returns {string}
|
|
45
|
+
* @throws {TypeError} when `value` is not a string: it has no canonical form,
|
|
46
|
+
* and a caller that would key or compare by one must not carry on without it
|
|
47
|
+
*/
|
|
48
|
+
export function canonicalEmailAddress(value) {
|
|
49
|
+
if (typeof value !== 'string') {
|
|
50
|
+
throw new TypeError('An email address is a string');
|
|
51
|
+
}
|
|
52
|
+
return value.trim().toLowerCase();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* What makes `value` an address SparkVault cannot deliver to, or null when
|
|
56
|
+
* nothing does.
|
|
57
|
+
*
|
|
58
|
+
* @param {*} value
|
|
59
|
+
* @returns {string|null} One of EMAIL_ADDRESS_PROBLEMS, or null
|
|
60
|
+
*/
|
|
61
|
+
export function emailAddressProblem(value) {
|
|
62
|
+
if (typeof value !== 'string')
|
|
63
|
+
return EMAIL_ADDRESS_PROBLEMS.FORMAT;
|
|
64
|
+
const address = canonicalEmailAddress(value);
|
|
65
|
+
const at = address.indexOf('@');
|
|
66
|
+
if (at <= 0 || at !== address.lastIndexOf('@'))
|
|
67
|
+
return EMAIL_ADDRESS_PROBLEMS.FORMAT;
|
|
68
|
+
const localPart = address.slice(0, at);
|
|
69
|
+
const domain = address.slice(at + 1);
|
|
70
|
+
const labels = domain.split('.');
|
|
71
|
+
if (!LOCAL_PART.test(localPart) || labels.length < 2 || !labels.every((label) => DOMAIN_LABEL.test(label))) {
|
|
72
|
+
return EMAIL_ADDRESS_PROBLEMS.FORMAT;
|
|
73
|
+
}
|
|
74
|
+
if (address.length > EMAIL_ADDRESS_LIMITS.ADDRESS)
|
|
75
|
+
return EMAIL_ADDRESS_PROBLEMS.TOO_LONG;
|
|
76
|
+
if (localPart.length > EMAIL_ADDRESS_LIMITS.LOCAL_PART)
|
|
77
|
+
return EMAIL_ADDRESS_PROBLEMS.LOCAL_PART_TOO_LONG;
|
|
78
|
+
if (domain.length > EMAIL_ADDRESS_LIMITS.DOMAIN)
|
|
79
|
+
return EMAIL_ADDRESS_PROBLEMS.DOMAIN_TOO_LONG;
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Whether SparkVault can deliver to `value`.
|
|
84
|
+
*
|
|
85
|
+
* @param {*} value
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
*/
|
|
88
|
+
export function isValidEmailAddress(value) {
|
|
89
|
+
return emailAddressProblem(value) === null;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=email-address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-address.js","sourceRoot":"","sources":["../../src/app-sdk/email-address.js"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,yDAAyD;AACzD,8DAA8D;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,UAAU,GAAG,iCAAiC,CAAC;AACrD,MAAM,YAAY,GAAG,wCAAwC,CAAC;AAE9D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,EAAE;IACd,MAAM,EAAE,GAAG;CACZ,CAAC,CAAC;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;CACnC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAK;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAK;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,sBAAsB,CAAC,MAAM,CAAC;IACpE,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC;QAAE,OAAO,sBAAsB,CAAC,MAAM,CAAC;IAErF,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3G,OAAO,sBAAsB,CAAC,MAAM,CAAC;IACvC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,oBAAoB,CAAC,OAAO;QAAE,OAAO,sBAAsB,CAAC,QAAQ,CAAC;IAC1F,IAAI,SAAS,CAAC,MAAM,GAAG,oBAAoB,CAAC,UAAU;QAAE,OAAO,sBAAsB,CAAC,mBAAmB,CAAC;IAC1G,IAAI,MAAM,CAAC,MAAM,GAAG,oBAAoB,CAAC,MAAM;QAAE,OAAO,sBAAsB,CAAC,eAAe,CAAC;IAC/F,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAK;IACvC,OAAO,mBAAmB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a value is a Uint8Array from any realm (a browser frame, a test
|
|
3
|
+
* DOM), a Node Buffer included: the platform's one Uint8Array test, since a
|
|
4
|
+
* realm's own `instanceof Uint8Array` refuses another realm's arrays.
|
|
5
|
+
* @param {unknown} value
|
|
6
|
+
* @returns {boolean}
|
|
7
|
+
*/
|
|
8
|
+
export function isUint8Array(value: unknown): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Encode bytes as standard base64, padded.
|
|
11
|
+
* @param {Uint8Array} bytes
|
|
12
|
+
* @returns {string}
|
|
13
|
+
* @throws {TypeError} when `bytes` is not a Uint8Array
|
|
14
|
+
*/
|
|
15
|
+
export function bytesToBase64(bytes: Uint8Array): string;
|
|
16
|
+
/**
|
|
17
|
+
* Encode bytes as base64url, unpadded.
|
|
18
|
+
* @param {Uint8Array} bytes
|
|
19
|
+
* @returns {string}
|
|
20
|
+
* @throws {TypeError} when `bytes` is not a Uint8Array
|
|
21
|
+
*/
|
|
22
|
+
export function bytesToBase64url(bytes: Uint8Array): string;
|
|
23
|
+
/**
|
|
24
|
+
* Decode standard base64.
|
|
25
|
+
* @param {unknown} text
|
|
26
|
+
* @param {{ canonical?: boolean }} [options] - `canonical`: accept only what `bytesToBase64` writes
|
|
27
|
+
* @returns {Uint8Array | null} the bytes, or null when the text is not base64
|
|
28
|
+
*/
|
|
29
|
+
export function base64ToBytes(text: unknown, { canonical }?: {
|
|
30
|
+
canonical?: boolean;
|
|
31
|
+
}): Uint8Array | null;
|
|
32
|
+
/**
|
|
33
|
+
* Decode base64url.
|
|
34
|
+
* @param {unknown} text
|
|
35
|
+
* @param {{ canonical?: boolean }} [options] - `canonical`: accept only what `bytesToBase64url` writes
|
|
36
|
+
* @returns {Uint8Array | null} the bytes, or null when the text is not base64url
|
|
37
|
+
*/
|
|
38
|
+
export function base64urlToBytes(text: unknown, { canonical }?: {
|
|
39
|
+
canonical?: boolean;
|
|
40
|
+
}): Uint8Array | null;
|
|
41
|
+
/**
|
|
42
|
+
* Encode a string as standard base64, padded, of its UTF-8 bytes.
|
|
43
|
+
* @param {string} value
|
|
44
|
+
* @returns {string}
|
|
45
|
+
*/
|
|
46
|
+
export function base64EncodeUtf8(value: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Decode what `base64EncodeUtf8` writes, strictly: canonical standard base64
|
|
49
|
+
* of well-formed UTF-8, so a mangled value is refused rather than read as
|
|
50
|
+
* whatever text a lenient decoder makes of it.
|
|
51
|
+
* @param {unknown} text
|
|
52
|
+
* @returns {string | null} the string, or null when the text is not canonical base64 of UTF-8
|
|
53
|
+
*/
|
|
54
|
+
export function base64DecodeUtf8(text: unknown): string | null;
|
|
55
|
+
/**
|
|
56
|
+
* This module's codec as the source of a classic browser script, for a page
|
|
57
|
+
* that cannot import an ES module (Identity's passkey popup, the x.sv reveal
|
|
58
|
+
* page): it declares `bytesToBase64`, `bytesToBase64url`, `base64ToBytes` and
|
|
59
|
+
* `base64urlToBytes` and everything they read at the script's top level, built
|
|
60
|
+
* from the functions and constants above, so the page runs this codec, not a
|
|
61
|
+
* copy. A new module-scope binding any of them reads must be added here.
|
|
62
|
+
* Marked pure so a bundle that never reads it (the browser SDK's) drops it.
|
|
63
|
+
*/
|
|
64
|
+
export const ENCODING_SCRIPT: string;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// GENERATED FILE — do not edit by hand.
|
|
2
|
+
// Source of truth: packages/app-sdk/src/encoding.js
|
|
3
|
+
// Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
|
|
4
|
+
/**
|
|
5
|
+
* Base64 and base64url (RFC 4648 §4 and §5): the platform's one codec.
|
|
6
|
+
*
|
|
7
|
+
* Dependency-free, and the codec uses no runtime globals (no Buffer, atob or
|
|
8
|
+
* btoa), so the same code runs on the server, in browsers and in React Native:
|
|
9
|
+
* sdk-js bundles this module, and sdk-mobile (which publishes standalone)
|
|
10
|
+
* carries a build-time copy pinned byte-for-byte by its drift test.
|
|
11
|
+
*
|
|
12
|
+
* - `bytesToBase64` writes the standard alphabet with `=` padding;
|
|
13
|
+
* `bytesToBase64url` writes the URL-safe alphabet without padding.
|
|
14
|
+
* - `base64ToBytes` and `base64urlToBytes` each read one alphabet, by the WHATWG
|
|
15
|
+
* forgiving-base64 rules `atob` implements: ASCII whitespace is ignored,
|
|
16
|
+
* padding is optional but, when present, is one or two `=` completing the
|
|
17
|
+
* final quartet, and bits past the last whole byte are dropped. Any other
|
|
18
|
+
* character (the other alphabet's included), `=` anywhere else, or a single
|
|
19
|
+
* character left over after the last whole quartet refuses the text.
|
|
20
|
+
* - `{ canonical: true }` accepts only the exact text the matching encoder
|
|
21
|
+
* writes (no whitespace, the encoder's padding, zero trailing bits), for a
|
|
22
|
+
* value whose spelling is itself compared or signed.
|
|
23
|
+
*
|
|
24
|
+
* - `base64EncodeUtf8` writes standard base64 of a string's UTF-8 bytes, the
|
|
25
|
+
* one form that carries any Unicode through an HTTP header value (a header
|
|
26
|
+
* holds latin1 bytes only); `base64DecodeUtf8` reads back exactly what it
|
|
27
|
+
* writes. These two use TextEncoder and TextDecoder, which Node and every
|
|
28
|
+
* browser provide; sdk-mobile converts UTF-8 itself for the React Native
|
|
29
|
+
* engines that need not.
|
|
30
|
+
* - `isUint8Array` is the platform's one Uint8Array test; every app-sdk check
|
|
31
|
+
* for a Uint8Array applies it.
|
|
32
|
+
*
|
|
33
|
+
* A refused text decodes to null, never to other bytes: each caller raises its
|
|
34
|
+
* own error at its own trust boundary.
|
|
35
|
+
*
|
|
36
|
+
* A page that cannot import an ES module runs this module's own codec
|
|
37
|
+
* (ENCODING_SCRIPT).
|
|
38
|
+
*/
|
|
39
|
+
const PAD = 0x3d; // '='
|
|
40
|
+
/** Characters per String.fromCharCode call: far below every engine's argument limit. */
|
|
41
|
+
const CHAR_CODE_CHUNK = 0x2000;
|
|
42
|
+
function alphabet(characters, padded) {
|
|
43
|
+
const codes = new Uint8Array(64);
|
|
44
|
+
const values = new Int8Array(128).fill(-1);
|
|
45
|
+
for (let index = 0; index < 64; index += 1) {
|
|
46
|
+
codes[index] = characters.charCodeAt(index);
|
|
47
|
+
values[codes[index]] = index;
|
|
48
|
+
}
|
|
49
|
+
return { codes, values, padded };
|
|
50
|
+
}
|
|
51
|
+
const BASE64_CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
52
|
+
const BASE64URL_CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
53
|
+
const BASE64 = alphabet(BASE64_CHARACTERS, true);
|
|
54
|
+
const BASE64URL = alphabet(BASE64URL_CHARACTERS, false);
|
|
55
|
+
/** Tab, line feed, form feed, carriage return or space. */
|
|
56
|
+
function isAsciiWhitespace(code) {
|
|
57
|
+
return code === 0x09 || code === 0x0a || code === 0x0c || code === 0x0d || code === 0x20;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether a value is a Uint8Array from any realm (a browser frame, a test
|
|
61
|
+
* DOM), a Node Buffer included: the platform's one Uint8Array test, since a
|
|
62
|
+
* realm's own `instanceof Uint8Array` refuses another realm's arrays.
|
|
63
|
+
* @param {unknown} value
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
export function isUint8Array(value) {
|
|
67
|
+
return ArrayBuffer.isView(value) && Object.prototype.toString.call(value) === '[object Uint8Array]';
|
|
68
|
+
}
|
|
69
|
+
function fromCharCodes(codes) {
|
|
70
|
+
let text = '';
|
|
71
|
+
for (let start = 0; start < codes.length; start += CHAR_CODE_CHUNK) {
|
|
72
|
+
text += String.fromCharCode.apply(null, codes.subarray(start, start + CHAR_CODE_CHUNK));
|
|
73
|
+
}
|
|
74
|
+
return text;
|
|
75
|
+
}
|
|
76
|
+
function encode(bytes, table) {
|
|
77
|
+
if (!isUint8Array(bytes)) {
|
|
78
|
+
throw new TypeError('Base64 encoding takes a Uint8Array');
|
|
79
|
+
}
|
|
80
|
+
const { codes } = table;
|
|
81
|
+
const tail = bytes.length % 3;
|
|
82
|
+
const whole = bytes.length - tail;
|
|
83
|
+
let tailLength = 0;
|
|
84
|
+
if (tail > 0)
|
|
85
|
+
tailLength = table.padded ? 4 : tail + 1;
|
|
86
|
+
const chars = new Uint8Array((whole / 3) * 4 + tailLength);
|
|
87
|
+
let out = 0;
|
|
88
|
+
for (let index = 0; index < whole; index += 3) {
|
|
89
|
+
const group = (bytes[index] << 16) | (bytes[index + 1] << 8) | bytes[index + 2];
|
|
90
|
+
chars[out++] = codes[group >> 18];
|
|
91
|
+
chars[out++] = codes[(group >> 12) & 63];
|
|
92
|
+
chars[out++] = codes[(group >> 6) & 63];
|
|
93
|
+
chars[out++] = codes[group & 63];
|
|
94
|
+
}
|
|
95
|
+
if (tail > 0) {
|
|
96
|
+
const group = (bytes[whole] << 16) | (tail === 2 ? bytes[whole + 1] << 8 : 0);
|
|
97
|
+
chars[out++] = codes[group >> 18];
|
|
98
|
+
chars[out++] = codes[(group >> 12) & 63];
|
|
99
|
+
if (tail === 2)
|
|
100
|
+
chars[out++] = codes[(group >> 6) & 63];
|
|
101
|
+
chars.fill(PAD, out);
|
|
102
|
+
}
|
|
103
|
+
return fromCharCodes(chars);
|
|
104
|
+
}
|
|
105
|
+
function decode(text, table, canonical) {
|
|
106
|
+
if (typeof text !== 'string')
|
|
107
|
+
return null;
|
|
108
|
+
const { values } = table;
|
|
109
|
+
// First pass: refuse anything malformed and count the digits, so the output
|
|
110
|
+
// is allocated once at its exact size (multi-megabyte reads decode here).
|
|
111
|
+
let digits = 0;
|
|
112
|
+
let padding = 0;
|
|
113
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
114
|
+
const code = text.charCodeAt(index);
|
|
115
|
+
if (isAsciiWhitespace(code)) {
|
|
116
|
+
if (canonical)
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
else if (code === PAD) {
|
|
120
|
+
padding += 1;
|
|
121
|
+
}
|
|
122
|
+
else if (padding > 0 || code > 127 || values[code] < 0) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
digits += 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const remainder = digits % 4;
|
|
130
|
+
if (remainder === 1)
|
|
131
|
+
return null;
|
|
132
|
+
if (padding > 0 && (padding > 2 || (digits + padding) % 4 !== 0))
|
|
133
|
+
return null;
|
|
134
|
+
if (canonical && padding !== (table.padded ? (4 - remainder) % 4 : 0))
|
|
135
|
+
return null;
|
|
136
|
+
const bytes = new Uint8Array((digits * 3) >> 2);
|
|
137
|
+
let buffer = 0;
|
|
138
|
+
let bits = 0;
|
|
139
|
+
let out = 0;
|
|
140
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
141
|
+
const code = text.charCodeAt(index);
|
|
142
|
+
if (code === PAD)
|
|
143
|
+
break;
|
|
144
|
+
if (isAsciiWhitespace(code))
|
|
145
|
+
continue;
|
|
146
|
+
buffer = ((buffer << 6) | values[code]) & 0xfff;
|
|
147
|
+
bits += 6;
|
|
148
|
+
if (bits >= 8) {
|
|
149
|
+
bits -= 8;
|
|
150
|
+
bytes[out++] = buffer >> bits;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (canonical && (buffer & ((1 << bits) - 1)) !== 0)
|
|
154
|
+
return null;
|
|
155
|
+
return bytes;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Encode bytes as standard base64, padded.
|
|
159
|
+
* @param {Uint8Array} bytes
|
|
160
|
+
* @returns {string}
|
|
161
|
+
* @throws {TypeError} when `bytes` is not a Uint8Array
|
|
162
|
+
*/
|
|
163
|
+
export function bytesToBase64(bytes) {
|
|
164
|
+
return encode(bytes, BASE64);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Encode bytes as base64url, unpadded.
|
|
168
|
+
* @param {Uint8Array} bytes
|
|
169
|
+
* @returns {string}
|
|
170
|
+
* @throws {TypeError} when `bytes` is not a Uint8Array
|
|
171
|
+
*/
|
|
172
|
+
export function bytesToBase64url(bytes) {
|
|
173
|
+
return encode(bytes, BASE64URL);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Decode standard base64.
|
|
177
|
+
* @param {unknown} text
|
|
178
|
+
* @param {{ canonical?: boolean }} [options] - `canonical`: accept only what `bytesToBase64` writes
|
|
179
|
+
* @returns {Uint8Array | null} the bytes, or null when the text is not base64
|
|
180
|
+
*/
|
|
181
|
+
export function base64ToBytes(text, { canonical = false } = {}) {
|
|
182
|
+
return decode(text, BASE64, canonical);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Decode base64url.
|
|
186
|
+
* @param {unknown} text
|
|
187
|
+
* @param {{ canonical?: boolean }} [options] - `canonical`: accept only what `bytesToBase64url` writes
|
|
188
|
+
* @returns {Uint8Array | null} the bytes, or null when the text is not base64url
|
|
189
|
+
*/
|
|
190
|
+
export function base64urlToBytes(text, { canonical = false } = {}) {
|
|
191
|
+
return decode(text, BASE64URL, canonical);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Encode a string as standard base64, padded, of its UTF-8 bytes.
|
|
195
|
+
* @param {string} value
|
|
196
|
+
* @returns {string}
|
|
197
|
+
*/
|
|
198
|
+
export function base64EncodeUtf8(value) {
|
|
199
|
+
return bytesToBase64(new TextEncoder().encode(value));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Decode what `base64EncodeUtf8` writes, strictly: canonical standard base64
|
|
203
|
+
* of well-formed UTF-8, so a mangled value is refused rather than read as
|
|
204
|
+
* whatever text a lenient decoder makes of it.
|
|
205
|
+
* @param {unknown} text
|
|
206
|
+
* @returns {string | null} the string, or null when the text is not canonical base64 of UTF-8
|
|
207
|
+
*/
|
|
208
|
+
export function base64DecodeUtf8(text) {
|
|
209
|
+
const bytes = base64ToBytes(text, { canonical: true });
|
|
210
|
+
if (bytes === null)
|
|
211
|
+
return null;
|
|
212
|
+
try {
|
|
213
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// A fatal decoder signals bytes that are not UTF-8 only by throwing.
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* This module's codec as the source of a classic browser script, for a page
|
|
222
|
+
* that cannot import an ES module (Identity's passkey popup, the x.sv reveal
|
|
223
|
+
* page): it declares `bytesToBase64`, `bytesToBase64url`, `base64ToBytes` and
|
|
224
|
+
* `base64urlToBytes` and everything they read at the script's top level, built
|
|
225
|
+
* from the functions and constants above, so the page runs this codec, not a
|
|
226
|
+
* copy. A new module-scope binding any of them reads must be added here.
|
|
227
|
+
* Marked pure so a bundle that never reads it (the browser SDK's) drops it.
|
|
228
|
+
*/
|
|
229
|
+
export const ENCODING_SCRIPT = /* @__PURE__ */ [
|
|
230
|
+
`var PAD = ${PAD};`,
|
|
231
|
+
`var CHAR_CODE_CHUNK = ${CHAR_CODE_CHUNK};`,
|
|
232
|
+
alphabet,
|
|
233
|
+
`var BASE64 = alphabet(${JSON.stringify(BASE64_CHARACTERS)}, true);`,
|
|
234
|
+
`var BASE64URL = alphabet(${JSON.stringify(BASE64URL_CHARACTERS)}, false);`,
|
|
235
|
+
isAsciiWhitespace,
|
|
236
|
+
isUint8Array,
|
|
237
|
+
fromCharCodes,
|
|
238
|
+
encode,
|
|
239
|
+
decode,
|
|
240
|
+
bytesToBase64,
|
|
241
|
+
bytesToBase64url,
|
|
242
|
+
base64ToBytes,
|
|
243
|
+
base64urlToBytes
|
|
244
|
+
].join('\n');
|
|
245
|
+
//# sourceMappingURL=encoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/app-sdk/encoding.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {unknown} format
|
|
3
|
+
* @returns {boolean} Whether the endpoint serves this output format
|
|
4
|
+
*/
|
|
5
|
+
export function isEntropyFormat(format: unknown): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* The most bytes one request may ask for in a format (`num_bytes` runs from 1
|
|
8
|
+
* to this). A `uuid` always draws 16 bytes, whatever the request names.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} format - One of ENTROPY_FORMATS
|
|
11
|
+
* @returns {number}
|
|
12
|
+
*/
|
|
13
|
+
export function maxBytesFor(format: string): number;
|
|
14
|
+
/**
|
|
15
|
+
* The request contract of the entropy endpoint (POST /v1/entropy/generate):
|
|
16
|
+
* the output formats it serves and how many bytes one request may ask for.
|
|
17
|
+
*
|
|
18
|
+
* Core's route enforces it; the console and both SDKs hold a request to it
|
|
19
|
+
* before sending, so a request the server would refuse is refused where it is
|
|
20
|
+
* made. Dependency-free: sdk-js bundles it and sdk-mobile carries a generated
|
|
21
|
+
* copy.
|
|
22
|
+
*/
|
|
23
|
+
/** Output formats the endpoint serves. `bytes` returns a number array; every other format a string. */
|
|
24
|
+
export const ENTROPY_FORMATS: readonly string[];
|
|
25
|
+
/** The hardware ceiling on one entropy draw, in bytes. */
|
|
26
|
+
export const MAX_DRAW_BYTES: 1024;
|
|
27
|
+
/**
|
|
28
|
+
* Formats whose characters are drawn from an alphabet by rejection sampling.
|
|
29
|
+
* They open with two raw bytes per output character, so one request's output
|
|
30
|
+
* caps at half a draw. `numeric` rejects so few bytes that it opens with one
|
|
31
|
+
* byte per digit and keeps the full ceiling.
|
|
32
|
+
*/
|
|
33
|
+
export const CHARSET_FORMATS: readonly string[];
|