@sparkvault/sdk-mobile 1.0.2 → 1.0.4
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 +1 -1
- package/dist/auth.d.ts +29 -1
- package/dist/auth.js +56 -0
- package/dist/auth.js.map +1 -1
- package/dist/billing.d.ts +21 -15
- package/dist/billing.js +28 -2
- package/dist/billing.js.map +1 -1
- package/dist/errors.d.ts +35 -1
- package/dist/errors.js +61 -0
- package/dist/errors.js.map +1 -1
- package/dist/http.d.ts +7 -0
- package/dist/http.js +25 -17
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tus.js +34 -1
- package/dist/tus.js.map +1 -1
- package/dist/types.d.ts +85 -2
- package/package.json +1 -1
- package/src/auth.ts +81 -0
- package/src/billing.ts +38 -16
- package/src/errors.ts +83 -1
- package/src/http.ts +31 -23
- package/src/index.ts +4 -1
- package/src/tus.ts +40 -2
- package/src/types.ts +93 -2
package/dist/index.d.ts
CHANGED
|
@@ -15,10 +15,10 @@ export type { EntropyFormat, EntropyResponse, GenerateEntropyOptions, } from './
|
|
|
15
15
|
export { MobilePushTokensClient, } from './push-tokens.js';
|
|
16
16
|
export type { RegisterPushTokenResponse, } from './push-tokens.js';
|
|
17
17
|
export { MobileBillingClient, } from './billing.js';
|
|
18
|
-
export type {
|
|
18
|
+
export type { PortalSession, } from './billing.js';
|
|
19
19
|
export { MobileTusUploader, parseForgeUrl, } from './tus.js';
|
|
20
20
|
export type { TusUploadFromUriOptions, ParsedForgeUrl, } from './tus.js';
|
|
21
21
|
export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
|
|
22
|
-
export { SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
|
|
22
|
+
export { gateErrorFromBody, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
|
|
23
23
|
export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
|
|
24
24
|
export type * from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,6 @@ export { MobilePushTokensClient, } from './push-tokens.js';
|
|
|
10
10
|
export { MobileBillingClient, } from './billing.js';
|
|
11
11
|
export { MobileTusUploader, parseForgeUrl, } from './tus.js';
|
|
12
12
|
export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
|
|
13
|
-
export { SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
|
|
13
|
+
export { gateErrorFromBody, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
|
|
14
14
|
export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
|
|
15
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAQrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAQrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
|
package/dist/tus.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { base64EncodeUtf8, base64ToBytes } from './encoding.js';
|
|
2
|
-
import { SparkVaultValidationError, TusUploadError } from './errors.js';
|
|
2
|
+
import { gateErrorFromBody, SparkVaultMobileError, SparkVaultValidationError, TusUploadError, } from './errors.js';
|
|
3
3
|
const TUS_VERSION = '1.0.0';
|
|
4
4
|
export function parseForgeUrl(forgeUrl) {
|
|
5
5
|
let url;
|
|
@@ -23,6 +23,22 @@ export function parseForgeUrl(forgeUrl) {
|
|
|
23
23
|
istk,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse a Forge error response body (JSON text) into the shared ApiErrorBody
|
|
28
|
+
* shape so gate mapping can read its `error.code` / `error.details.resource`.
|
|
29
|
+
* Returns an empty body on non-JSON text, which simply matches no gate.
|
|
30
|
+
*/
|
|
31
|
+
function parseErrorBody(text) {
|
|
32
|
+
if (!text)
|
|
33
|
+
return {};
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(text);
|
|
36
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
26
42
|
function getErrorName(err) {
|
|
27
43
|
return err instanceof Error ? err.name : 'UnknownError';
|
|
28
44
|
}
|
|
@@ -87,6 +103,13 @@ async function createTusUpload(config, parsed, fileSize, filename, contentType,
|
|
|
87
103
|
});
|
|
88
104
|
if (!response.ok) {
|
|
89
105
|
const errorText = await response.text().catch(() => '');
|
|
106
|
+
// A 402 here is a billable gate hit mid-create (e.g. storage/bandwidth pool
|
|
107
|
+
// exhausted). Route it through the same typed-gate mapping as the JSON HTTP
|
|
108
|
+
// path so callers handle subscribe / add-on UX off one set of error types.
|
|
109
|
+
const gateError = gateErrorFromBody(response.status, parseErrorBody(errorText));
|
|
110
|
+
if (gateError) {
|
|
111
|
+
throw gateError;
|
|
112
|
+
}
|
|
90
113
|
throw new TusUploadError(`TUS create failed: ${response.status} - ${errorText}`, {
|
|
91
114
|
httpStatus: response.status,
|
|
92
115
|
filename,
|
|
@@ -143,6 +166,11 @@ function uploadChunk(uploadUrl, istk, chunk, offset, timeoutMs, signal, onChunkP
|
|
|
143
166
|
finish(() => resolve(newOffset));
|
|
144
167
|
}
|
|
145
168
|
else {
|
|
169
|
+
const gateError = gateErrorFromBody(xhr.status, parseErrorBody(xhr.responseText));
|
|
170
|
+
if (gateError) {
|
|
171
|
+
finish(() => reject(gateError));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
146
174
|
finish(() => reject(new TusUploadError(`Chunk upload failed: ${xhr.status} - ${xhr.responseText.substring(0, 200)}`, {
|
|
147
175
|
httpStatus: xhr.status,
|
|
148
176
|
phase: 'upload',
|
|
@@ -210,6 +238,11 @@ export class MobileTusUploader {
|
|
|
210
238
|
}
|
|
211
239
|
if (err instanceof TusUploadError)
|
|
212
240
|
throw err;
|
|
241
|
+
// Typed gate errors (PlanRequiredError / QuotaExceededError) must reach
|
|
242
|
+
// the caller intact so the subscribe / add-on UX fires; never bury them
|
|
243
|
+
// in a generic TusUploadError.
|
|
244
|
+
if (err instanceof SparkVaultMobileError)
|
|
245
|
+
throw err;
|
|
213
246
|
throw TusUploadError.fromError(error, {
|
|
214
247
|
filename: options.filename,
|
|
215
248
|
fileSize: options.fileSize,
|
package/dist/tus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
/** Utilization state shared by storage, bandwidth, and Identity pools. */
|
|
2
|
+
export type PoolState = 'ok' | 'notice' | 'warning' | 'exhausted';
|
|
3
|
+
/** Live usage for a single capacity pool. `limit_gb` is null on unlimited plans. */
|
|
4
|
+
export interface PoolStatus {
|
|
5
|
+
used_gb: number;
|
|
6
|
+
limit_gb: number | null;
|
|
7
|
+
pct: number;
|
|
8
|
+
state: PoolState;
|
|
9
|
+
}
|
|
10
|
+
/** Bandwidth pool additionally reports when the metered cycle resets. */
|
|
11
|
+
export interface BandwidthPoolStatus extends PoolStatus {
|
|
12
|
+
cycle_resets_at: number | null;
|
|
13
|
+
}
|
|
14
|
+
/** Storage + bandwidth pool snapshot; rides responses on `meta.pools`. */
|
|
15
|
+
export interface SubscriptionPools {
|
|
16
|
+
storage: PoolStatus;
|
|
17
|
+
bandwidth: BandwidthPoolStatus;
|
|
18
|
+
}
|
|
1
19
|
export interface ApiMeta {
|
|
2
20
|
request_id: string;
|
|
3
21
|
response_ms: number;
|
|
4
22
|
timestamp: number;
|
|
5
23
|
api_version: string;
|
|
6
|
-
|
|
24
|
+
pools?: SubscriptionPools;
|
|
7
25
|
quota?: {
|
|
8
26
|
limit: number;
|
|
9
27
|
used: number;
|
|
@@ -43,11 +61,45 @@ export interface SparkVaultAccount {
|
|
|
43
61
|
organization_name: string;
|
|
44
62
|
email: string;
|
|
45
63
|
status: 'active' | 'suspended';
|
|
46
|
-
balance: string;
|
|
47
64
|
logo_url?: string;
|
|
48
65
|
logo_dark_url?: string;
|
|
49
66
|
created_at: number;
|
|
50
67
|
}
|
|
68
|
+
/** Identity attempts usage against the purchased tier cap. */
|
|
69
|
+
export interface SubscriptionIdentityStatus {
|
|
70
|
+
attempts_cap: number | null;
|
|
71
|
+
attempts_used: number;
|
|
72
|
+
soft_cap: number | null;
|
|
73
|
+
state: PoolState;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* GET /v1/billing/subscription — the account's current plan, licensed vs. used
|
|
77
|
+
* seats, capacity blocks, live pool usage, and Identity attempts. Drives the
|
|
78
|
+
* subscription / usage view. `renewal_amount_usd` is a formatted dollars string;
|
|
79
|
+
* `renewal_date` is an epoch (seconds) or null when there is no active plan.
|
|
80
|
+
*/
|
|
81
|
+
export interface SparkVaultSubscription {
|
|
82
|
+
plan: 'subscription' | 'internal' | 'unsubscribed';
|
|
83
|
+
unlimited: boolean;
|
|
84
|
+
subscription_status: string | null;
|
|
85
|
+
past_due: boolean;
|
|
86
|
+
renewal_date: number | null;
|
|
87
|
+
renewal_amount_usd: string;
|
|
88
|
+
seats: {
|
|
89
|
+
full: number;
|
|
90
|
+
viewer: number;
|
|
91
|
+
licensed: number;
|
|
92
|
+
used: number;
|
|
93
|
+
};
|
|
94
|
+
blocks: {
|
|
95
|
+
storage: number;
|
|
96
|
+
bandwidth: number;
|
|
97
|
+
};
|
|
98
|
+
pools: SubscriptionPools;
|
|
99
|
+
identity: SubscriptionIdentityStatus;
|
|
100
|
+
}
|
|
101
|
+
/** Native in-app purchase store channel for receipt validation. */
|
|
102
|
+
export type IapPlatform = 'ios' | 'android';
|
|
51
103
|
export type IdentityType = 'email' | 'phone';
|
|
52
104
|
export type VerifiedIdentityType = IdentityType | 'social';
|
|
53
105
|
export type IdentityMethodId = 'totp_email' | 'totp_sms' | 'totp_voice' | 'passkey' | 'sparklink' | 'social_google' | 'social_apple' | 'social_microsoft' | 'social_github' | 'social_facebook' | 'social_linkedin' | 'enterprise_okta' | 'enterprise_entra' | 'enterprise_onelogin' | 'enterprise_ping' | 'enterprise_jumpcloud';
|
|
@@ -89,6 +141,18 @@ export interface IdentityTokenClaims {
|
|
|
89
141
|
verified_at: number;
|
|
90
142
|
method: string;
|
|
91
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* A server-decided post-login nudge. Computed once per login (default mode);
|
|
146
|
+
* clients act on the steps they support, in order.
|
|
147
|
+
*/
|
|
148
|
+
export type Recommendation = {
|
|
149
|
+
type: 'passkey';
|
|
150
|
+
} | {
|
|
151
|
+
type: 'backup_identifier';
|
|
152
|
+
missingType: 'email' | 'phone';
|
|
153
|
+
};
|
|
154
|
+
/** Canonical dismiss key for a recommendation (suppresses it server-side 30d). */
|
|
155
|
+
export type RecommendationKey = 'passkey' | 'backup_email' | 'backup_phone';
|
|
92
156
|
export interface IdentityVerifyResult {
|
|
93
157
|
token: string;
|
|
94
158
|
identity: string;
|
|
@@ -97,6 +161,25 @@ export interface IdentityVerifyResult {
|
|
|
97
161
|
redirect?: string;
|
|
98
162
|
jwksUri: string;
|
|
99
163
|
jwks?: IdentityJwks;
|
|
164
|
+
/** Ordered post-login nudges (default-mode logins only). */
|
|
165
|
+
recommendations?: Recommendation[];
|
|
166
|
+
}
|
|
167
|
+
/** Response to POST /backup-verification/send. */
|
|
168
|
+
export interface BackupSendResponse {
|
|
169
|
+
/** Opaque pending-attach session id (present when a code was sent). */
|
|
170
|
+
session_id?: string;
|
|
171
|
+
/** Delivery channel actually used. */
|
|
172
|
+
method?: 'email' | 'sms' | 'voice';
|
|
173
|
+
/** Code expiry (Unix seconds). */
|
|
174
|
+
expires_at?: number;
|
|
175
|
+
/** True when the identifier is already on the identity — no code was sent. */
|
|
176
|
+
already_verified?: boolean;
|
|
177
|
+
}
|
|
178
|
+
/** Response to POST /backup-verification/verify. */
|
|
179
|
+
export interface BackupVerifyResponse {
|
|
180
|
+
verified: boolean;
|
|
181
|
+
type: 'email' | 'phone';
|
|
182
|
+
value: string;
|
|
100
183
|
}
|
|
101
184
|
export interface SendTotpRequest {
|
|
102
185
|
identity: string;
|
package/package.json
CHANGED
package/src/auth.ts
CHANGED
|
@@ -4,6 +4,10 @@ import { SparkVaultAuthenticationError, SparkVaultMobileError, SparkVaultValidat
|
|
|
4
4
|
import type { MobileHttpClient } from './http.js';
|
|
5
5
|
import type {
|
|
6
6
|
ApiErrorBody,
|
|
7
|
+
BackupSendResponse,
|
|
8
|
+
BackupVerifyResponse,
|
|
9
|
+
Recommendation,
|
|
10
|
+
RecommendationKey,
|
|
7
11
|
CompleteSignupRequest,
|
|
8
12
|
CompleteSignupResponse,
|
|
9
13
|
IdentityConfig,
|
|
@@ -30,6 +34,12 @@ import type {
|
|
|
30
34
|
} from './types.js';
|
|
31
35
|
import nacl from 'tweetnacl';
|
|
32
36
|
|
|
37
|
+
/** Raw snake_case recommendation as the API returns it. */
|
|
38
|
+
interface RawRecommendation {
|
|
39
|
+
type?: string;
|
|
40
|
+
missing_type?: 'email' | 'phone' | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
interface IdentityVerificationResponse {
|
|
34
44
|
verified: boolean;
|
|
35
45
|
token?: string;
|
|
@@ -46,6 +56,8 @@ interface IdentityVerificationResponse {
|
|
|
46
56
|
ticket?: string;
|
|
47
57
|
/** Offered second-factor methods. */
|
|
48
58
|
methods?: string[];
|
|
59
|
+
/** Ordered post-login nudges. */
|
|
60
|
+
recommendations?: RawRecommendation[];
|
|
49
61
|
}
|
|
50
62
|
|
|
51
63
|
interface IdentityPasskeyCompletionResponse {
|
|
@@ -55,6 +67,25 @@ interface IdentityPasskeyCompletionResponse {
|
|
|
55
67
|
identity_type: VerifiedIdentityType;
|
|
56
68
|
method: string;
|
|
57
69
|
redirect?: string;
|
|
70
|
+
/** Ordered post-login nudges. */
|
|
71
|
+
recommendations?: RawRecommendation[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Map the API's snake_case recommendation list to the SDK's typed shape,
|
|
76
|
+
* dropping entries the SDK does not understand. Returns undefined when absent.
|
|
77
|
+
*/
|
|
78
|
+
function mapRecommendations(raw: RawRecommendation[] | undefined): Recommendation[] | undefined {
|
|
79
|
+
if (!Array.isArray(raw)) return undefined;
|
|
80
|
+
const result: Recommendation[] = [];
|
|
81
|
+
for (const rec of raw) {
|
|
82
|
+
if (rec?.type === 'passkey') {
|
|
83
|
+
result.push({ type: 'passkey' });
|
|
84
|
+
} else if (rec?.type === 'backup_identifier' && (rec.missing_type === 'email' || rec.missing_type === 'phone')) {
|
|
85
|
+
result.push({ type: 'backup_identifier', missingType: rec.missing_type });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
58
89
|
}
|
|
59
90
|
|
|
60
91
|
interface JwtHeader {
|
|
@@ -269,6 +300,7 @@ export class MobileAuthClient {
|
|
|
269
300
|
identityType: verifyResult.identity_type,
|
|
270
301
|
method: verifyResult.method,
|
|
271
302
|
redirect: verifyResult.redirect,
|
|
303
|
+
recommendations: mapRecommendations(verifyResult.recommendations),
|
|
272
304
|
});
|
|
273
305
|
}
|
|
274
306
|
|
|
@@ -338,6 +370,7 @@ export class MobileAuthClient {
|
|
|
338
370
|
identityType: result.identity_type,
|
|
339
371
|
method: result.method,
|
|
340
372
|
redirect: result.redirect,
|
|
373
|
+
recommendations: mapRecommendations(result.recommendations),
|
|
341
374
|
});
|
|
342
375
|
}
|
|
343
376
|
|
|
@@ -427,6 +460,7 @@ export class MobileAuthClient {
|
|
|
427
460
|
identityType: result.identity_type,
|
|
428
461
|
method: result.method,
|
|
429
462
|
redirect: result.redirect,
|
|
463
|
+
recommendations: mapRecommendations(result.recommendations),
|
|
430
464
|
});
|
|
431
465
|
}
|
|
432
466
|
|
|
@@ -639,6 +673,7 @@ export class MobileAuthClient {
|
|
|
639
673
|
identityType?: VerifiedIdentityType;
|
|
640
674
|
method?: string;
|
|
641
675
|
redirect?: string;
|
|
676
|
+
recommendations?: Recommendation[];
|
|
642
677
|
}
|
|
643
678
|
): IdentityVerifyResult {
|
|
644
679
|
const claims = this.decodeIdentityTokenClaims(token);
|
|
@@ -649,9 +684,55 @@ export class MobileAuthClient {
|
|
|
649
684
|
method: details.method ?? claims.method,
|
|
650
685
|
redirect: details.redirect,
|
|
651
686
|
jwksUri: this.getJwksUri(),
|
|
687
|
+
recommendations: details.recommendations,
|
|
652
688
|
};
|
|
653
689
|
}
|
|
654
690
|
|
|
691
|
+
/**
|
|
692
|
+
* Skip a post-login recommendation, suppressing it server-side for 30 days.
|
|
693
|
+
* Authorized by the login's verification token. Best-effort.
|
|
694
|
+
*/
|
|
695
|
+
async dismissRecommendation(params: { verificationToken: string; key: RecommendationKey }): Promise<void> {
|
|
696
|
+
await this.postIdentity('/recommendations/dismiss', {
|
|
697
|
+
verification_token: params.verificationToken,
|
|
698
|
+
key: params.key
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Post-login: send a one-time code to a new backup identifier (the inverse of
|
|
704
|
+
* the one just logged in with), authorized by the login's verification token.
|
|
705
|
+
* Returns a pending-attach `session_id`, or `already_verified` when the
|
|
706
|
+
* identifier is already on the identity.
|
|
707
|
+
*/
|
|
708
|
+
async sendBackupVerification(params: {
|
|
709
|
+
verificationToken: string;
|
|
710
|
+
type: IdentityType;
|
|
711
|
+
value: string;
|
|
712
|
+
method?: 'email' | 'sms' | 'voice';
|
|
713
|
+
}): Promise<BackupSendResponse> {
|
|
714
|
+
return this.postIdentity<BackupSendResponse>('/backup-verification/send', {
|
|
715
|
+
verification_token: params.verificationToken,
|
|
716
|
+
type: params.type,
|
|
717
|
+
value: params.value,
|
|
718
|
+
...(params.method ? { method: params.method } : {}),
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Confirm the backup-identifier code and attach it to the identity. An
|
|
724
|
+
* identifier already owned by another identity throws (409 `backup_conflict`).
|
|
725
|
+
*/
|
|
726
|
+
async verifyBackupVerification(params: {
|
|
727
|
+
sessionId: string;
|
|
728
|
+
code: string;
|
|
729
|
+
}): Promise<BackupVerifyResponse> {
|
|
730
|
+
return this.postIdentity<BackupVerifyResponse>('/backup-verification/verify', {
|
|
731
|
+
session_id: params.sessionId,
|
|
732
|
+
code: params.code,
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
|
|
655
736
|
private decodeIdentityTokenClaims(token: string): IdentityTokenClaims {
|
|
656
737
|
const parts = token.split('.');
|
|
657
738
|
if (parts.length !== 3) {
|
package/src/billing.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import type { MobileHttpClient } from './http.js';
|
|
2
|
+
import type { IapPlatform, SparkVaultSubscription } from './types.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
currency?: string;
|
|
7
|
-
monthly_spend?: string;
|
|
8
|
-
monthly_spend_usd?: number;
|
|
9
|
-
transaction_count?: number;
|
|
10
|
-
recent_transactions?: Array<{
|
|
11
|
-
type: string;
|
|
12
|
-
amount: string;
|
|
13
|
-
balance_after?: string;
|
|
14
|
-
reference_id?: string;
|
|
15
|
-
created_at: number;
|
|
16
|
-
}>;
|
|
4
|
+
/** Short-lived Stripe Customer Portal URL for managing the subscription on web. */
|
|
5
|
+
export interface PortalSession {
|
|
6
|
+
portal_url: string;
|
|
17
7
|
}
|
|
18
8
|
|
|
19
9
|
export class MobileBillingClient {
|
|
@@ -23,8 +13,40 @@ export class MobileBillingClient {
|
|
|
23
13
|
this.http = http;
|
|
24
14
|
}
|
|
25
15
|
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Current subscription: plan, licensed vs. used seats, capacity blocks, live
|
|
18
|
+
* pool usage, and Identity attempts. Drives the subscription / usage view.
|
|
19
|
+
*/
|
|
20
|
+
async getSubscription(): Promise<SparkVaultSubscription> {
|
|
21
|
+
const response = await this.http.get<SparkVaultSubscription>('/billing/subscription');
|
|
22
|
+
return response.data;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Open the Stripe Customer Portal to manage the subscription on web (seat /
|
|
27
|
+
* block changes that fixed native SKUs cannot carry route here). The caller
|
|
28
|
+
* loads the returned URL in the WebView.
|
|
29
|
+
*/
|
|
30
|
+
async createPortalSession(): Promise<PortalSession> {
|
|
31
|
+
const response = await this.http.post<PortalSession>('/billing/portal');
|
|
32
|
+
return response.data;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validate a native in-app purchase receipt server-side and apply the
|
|
37
|
+
* resulting entitlements. Returns the refreshed subscription so the client
|
|
38
|
+
* can update its plan / usage view immediately after purchase.
|
|
39
|
+
*/
|
|
40
|
+
async iapValidate(
|
|
41
|
+
platform: IapPlatform,
|
|
42
|
+
productId: string,
|
|
43
|
+
receipt: string
|
|
44
|
+
): Promise<SparkVaultSubscription> {
|
|
45
|
+
const response = await this.http.post<SparkVaultSubscription>('/billing/iap/validate', {
|
|
46
|
+
platform,
|
|
47
|
+
product_id: productId,
|
|
48
|
+
receipt,
|
|
49
|
+
});
|
|
28
50
|
return response.data;
|
|
29
51
|
}
|
|
30
52
|
}
|
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type { ApiMeta } from './types.js';
|
|
1
|
+
import type { ApiErrorBody, ApiMeta } from './types.js';
|
|
2
|
+
|
|
3
|
+
type QuotaResource = 'storage' | 'bandwidth' | 'seats' | 'identity';
|
|
4
|
+
|
|
5
|
+
function isQuotaResource(value: unknown): value is QuotaResource {
|
|
6
|
+
return value === 'storage' || value === 'bandwidth' || value === 'seats' || value === 'identity';
|
|
7
|
+
}
|
|
2
8
|
|
|
3
9
|
export class SparkVaultMobileError extends Error {
|
|
4
10
|
readonly code: string | number;
|
|
@@ -49,6 +55,48 @@ export class SparkVaultAuthorizationError extends SparkVaultMobileError {
|
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Thrown on a 402 PLAN_REQUIRED gate: the account has no active subscription
|
|
60
|
+
* and attempted a billable action. Callers route the user into the in-app
|
|
61
|
+
* subscribe flow (native IAP: fixed bundle / Identity tier).
|
|
62
|
+
*/
|
|
63
|
+
export class PlanRequiredError extends SparkVaultMobileError {
|
|
64
|
+
constructor(message = 'An active plan is required for this action', options: {
|
|
65
|
+
details?: Record<string, unknown>;
|
|
66
|
+
meta?: ApiMeta;
|
|
67
|
+
} = {}) {
|
|
68
|
+
super(message, { code: 'PLAN_REQUIRED', statusCode: 402, details: options.details, meta: options.meta });
|
|
69
|
+
this.name = 'PlanRequiredError';
|
|
70
|
+
Object.setPrototypeOf(this, PlanRequiredError.prototype);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Thrown on a 402 QUOTA_EXCEEDED gate: a pooled-capacity or seat limit was
|
|
76
|
+
* reached. `resource` identifies what to extend, routed through the in-app
|
|
77
|
+
* subscribe flow (native IAP): storage/bandwidth to a capacity add-on,
|
|
78
|
+
* seats/identity to a seat or tier change.
|
|
79
|
+
*/
|
|
80
|
+
export class QuotaExceededError extends SparkVaultMobileError {
|
|
81
|
+
readonly resource: 'storage' | 'bandwidth' | 'seats' | 'identity';
|
|
82
|
+
|
|
83
|
+
constructor(
|
|
84
|
+
resource: QuotaExceededError['resource'],
|
|
85
|
+
message?: string,
|
|
86
|
+
options: { details?: Record<string, unknown>; meta?: ApiMeta } = {}
|
|
87
|
+
) {
|
|
88
|
+
super(message ?? `${resource} limit reached for this account`, {
|
|
89
|
+
code: 'QUOTA_EXCEEDED',
|
|
90
|
+
statusCode: 402,
|
|
91
|
+
details: { resource, ...(options.details ?? {}) },
|
|
92
|
+
meta: options.meta,
|
|
93
|
+
});
|
|
94
|
+
this.name = 'QuotaExceededError';
|
|
95
|
+
this.resource = resource;
|
|
96
|
+
Object.setPrototypeOf(this, QuotaExceededError.prototype);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
52
100
|
export class SparkVaultNetworkError extends SparkVaultMobileError {
|
|
53
101
|
constructor(message = 'Network request failed', details?: Record<string, unknown>) {
|
|
54
102
|
super(message, { code: 'network_error', details });
|
|
@@ -108,3 +156,37 @@ export class TusUploadError extends SparkVaultMobileError {
|
|
|
108
156
|
});
|
|
109
157
|
}
|
|
110
158
|
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Single source of truth for turning a 402 response into a typed gate error.
|
|
162
|
+
* Both the JSON HTTP path (http.ts) and the TUS upload path (tus.ts) route 402s
|
|
163
|
+
* through here so the subscribe / add-on UX keys off one set of error types.
|
|
164
|
+
*
|
|
165
|
+
* Returns a typed gate error for recognized server codes (`PLAN_REQUIRED`,
|
|
166
|
+
* `QUOTA_EXCEEDED`) and `null` for any other 402 body, letting the caller fall
|
|
167
|
+
* back to its generic error so unknown gates are never silently swallowed.
|
|
168
|
+
*/
|
|
169
|
+
export function gateErrorFromBody(
|
|
170
|
+
statusCode: number,
|
|
171
|
+
errorBody: ApiErrorBody
|
|
172
|
+
): PlanRequiredError | QuotaExceededError | null {
|
|
173
|
+
if (statusCode !== 402) return null;
|
|
174
|
+
|
|
175
|
+
const code = errorBody.error?.code;
|
|
176
|
+
const message = errorBody.error?.message ?? errorBody.message ?? undefined;
|
|
177
|
+
const details = errorBody.error?.details;
|
|
178
|
+
const meta = errorBody.meta;
|
|
179
|
+
|
|
180
|
+
if (code === 'PLAN_REQUIRED') {
|
|
181
|
+
return new PlanRequiredError(message, { details, meta });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (code === 'QUOTA_EXCEEDED') {
|
|
185
|
+
const resource = details?.resource;
|
|
186
|
+
if (isQuotaResource(resource)) {
|
|
187
|
+
return new QuotaExceededError(resource, message, { details, meta });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
192
|
+
}
|
package/src/http.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ResolvedMobileConfig } from './config.js';
|
|
2
2
|
import {
|
|
3
|
+
gateErrorFromBody,
|
|
3
4
|
SparkVaultAuthenticationError,
|
|
4
5
|
SparkVaultMobileError,
|
|
5
6
|
SparkVaultNetworkError,
|
|
@@ -149,6 +150,33 @@ export class MobileHttpClient {
|
|
|
149
150
|
throw new SparkVaultMobileError(err instanceof Error ? err.message : 'Unknown request error');
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Single exit for non-OK responses: 402s become typed gate errors
|
|
155
|
+
* (PlanRequiredError / QuotaExceededError) so the subscribe / add-on UX keys
|
|
156
|
+
* off one set of types; everything else becomes a SparkVaultMobileError
|
|
157
|
+
* carrying the server code, status, details, and meta.
|
|
158
|
+
*/
|
|
159
|
+
private throwHttpError(status: number, errorBody: ApiErrorBody): never {
|
|
160
|
+
if (errorBody.meta) {
|
|
161
|
+
this.lastMeta = errorBody.meta;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const gateError = gateErrorFromBody(status, errorBody);
|
|
165
|
+
if (gateError) {
|
|
166
|
+
throw gateError;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
throw new SparkVaultMobileError(
|
|
170
|
+
errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(status),
|
|
171
|
+
{
|
|
172
|
+
code: errorBody.error?.code ?? status,
|
|
173
|
+
statusCode: status,
|
|
174
|
+
details: errorBody.error?.details,
|
|
175
|
+
meta: errorBody.meta,
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
152
180
|
private makeUrl(endpoint: string): string {
|
|
153
181
|
if (/^https?:\/\//i.test(endpoint)) {
|
|
154
182
|
return endpoint;
|
|
@@ -296,19 +324,7 @@ export class MobileHttpClient {
|
|
|
296
324
|
this.config.logger.debug('Failed to parse error response body', { status: response.status });
|
|
297
325
|
}
|
|
298
326
|
|
|
299
|
-
|
|
300
|
-
this.lastMeta = errorBody.meta;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
throw new SparkVaultMobileError(
|
|
304
|
-
errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(response.status),
|
|
305
|
-
{
|
|
306
|
-
code: errorBody.error?.code ?? response.status,
|
|
307
|
-
statusCode: response.status,
|
|
308
|
-
details: errorBody.error?.details,
|
|
309
|
-
meta: errorBody.meta,
|
|
310
|
-
}
|
|
311
|
-
);
|
|
327
|
+
this.throwHttpError(response.status, errorBody);
|
|
312
328
|
}
|
|
313
329
|
|
|
314
330
|
const result = await response.json();
|
|
@@ -365,15 +381,7 @@ export class MobileHttpClient {
|
|
|
365
381
|
} catch {
|
|
366
382
|
this.config.logger.debug('Failed to parse raw error response body', { status: response.status });
|
|
367
383
|
}
|
|
368
|
-
|
|
369
|
-
errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(response.status),
|
|
370
|
-
{
|
|
371
|
-
code: errorBody.error?.code ?? response.status,
|
|
372
|
-
statusCode: response.status,
|
|
373
|
-
details: errorBody.error?.details,
|
|
374
|
-
meta: errorBody.meta,
|
|
375
|
-
}
|
|
376
|
-
);
|
|
384
|
+
this.throwHttpError(response.status, errorBody);
|
|
377
385
|
}
|
|
378
386
|
|
|
379
387
|
return response;
|
|
@@ -414,7 +422,7 @@ export class MobileHttpClient {
|
|
|
414
422
|
case 401:
|
|
415
423
|
return 'Authentication required.';
|
|
416
424
|
case 402:
|
|
417
|
-
return '
|
|
425
|
+
return 'An active plan is required to continue.';
|
|
418
426
|
case 403:
|
|
419
427
|
return 'You do not have permission to perform this action.';
|
|
420
428
|
case 404:
|