@sparkvault/sdk-mobile 3.0.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/account.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ResolvedMobileConfig } from './config.js';
2
2
  import type { MobileHttpClient } from './http.js';
3
- import type { CompleteSignupRequest, CompleteSignupResponse, PinVerifyResponse, SparkVaultAccount, SparkVaultUser } from './types.js';
3
+ import type { CompleteSignupRequest, CompleteSignupResponse, PinVerifyResponse, SparkVaultAccount, SparkVaultUser, UpdateAccountRequest } from './types.js';
4
4
  /**
5
5
  * First-party SparkVault Core session, profile, and account client. Exchanges a
6
6
  * verified Identity token for an app session and owns the authenticated
@@ -22,6 +22,13 @@ export declare class MobileAccountClient {
22
22
  name?: string;
23
23
  }): Promise<SparkVaultUser>;
24
24
  getAccount(): Promise<SparkVaultAccount>;
25
+ /**
26
+ * Update organization settings (member admins only). Sends a JSON body — the
27
+ * logo-upload variant of PUT /account is web-only. The PUT returns a partial
28
+ * settings projection, so re-read the full account to refresh the cache and
29
+ * return a complete, canonical SparkVaultAccount.
30
+ */
31
+ updateAccount(updates: UpdateAccountRequest): Promise<SparkVaultAccount>;
25
32
  revokeRefreshToken(refreshToken?: string): Promise<void>;
26
33
  logout(options?: {
27
34
  revoke?: boolean;
package/dist/account.js CHANGED
@@ -64,6 +64,16 @@ export class MobileAccountClient {
64
64
  }
65
65
  return response.data;
66
66
  }
67
+ /**
68
+ * Update organization settings (member admins only). Sends a JSON body — the
69
+ * logo-upload variant of PUT /account is web-only. The PUT returns a partial
70
+ * settings projection, so re-read the full account to refresh the cache and
71
+ * return a complete, canonical SparkVaultAccount.
72
+ */
73
+ async updateAccount(updates) {
74
+ await this.http.put('/account', updates);
75
+ return this.getAccount();
76
+ }
67
77
  async revokeRefreshToken(refreshToken) {
68
78
  const token = refreshToken ?? await this.config.tokenStorage.getRefreshToken();
69
79
  if (!token)
@@ -1 +1 @@
1
- {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -9,6 +9,7 @@ import { MobileIngotsClient } from './ingots.js';
9
9
  import { MobileProductsClient } from './products/index.js';
10
10
  import { MobilePushTokensClient } from './push-tokens.js';
11
11
  import { MobileSparksClient } from './sparks.js';
12
+ import { MobileUsersClient } from './users.js';
12
13
  import { MobileVaultsClient } from './vaults.js';
13
14
  export declare class SparkVaultMobile {
14
15
  readonly config: ResolvedMobileConfig;
@@ -22,6 +23,7 @@ export declare class SparkVaultMobile {
22
23
  readonly entropy: MobileEntropyClient;
23
24
  readonly pushTokens: MobilePushTokensClient;
24
25
  readonly billing: MobileBillingClient;
26
+ readonly users: MobileUsersClient;
25
27
  private readonly http;
26
28
  constructor(config: SparkVaultMobileConfig);
27
29
  onAuthEvent(listener: AuthEventListener): () => void;
package/dist/client.js CHANGED
@@ -9,6 +9,7 @@ import { MobileIngotsClient } from './ingots.js';
9
9
  import { MobileProductsClient } from './products/index.js';
10
10
  import { MobilePushTokensClient } from './push-tokens.js';
11
11
  import { MobileSparksClient } from './sparks.js';
12
+ import { MobileUsersClient } from './users.js';
12
13
  import { MobileVaultsClient } from './vaults.js';
13
14
  export class SparkVaultMobile {
14
15
  constructor(config) {
@@ -24,6 +25,7 @@ export class SparkVaultMobile {
24
25
  this.entropy = new MobileEntropyClient(this.http);
25
26
  this.pushTokens = new MobilePushTokensClient(this.http);
26
27
  this.billing = new MobileBillingClient(this.http);
28
+ this.users = new MobileUsersClient(this.http);
27
29
  if (this.config.preloadIdentityConfig) {
28
30
  this.products.identity.preloadConfig();
29
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAA0D,MAAM,aAAa,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,OAAO,gBAAgB;IAc3B,YAAY,MAA8B;QACxC,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,QAA2B;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACF;AAED,MAAM,UAAU,4BAA4B,CAAC,MAA8B;IACzE,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAA0D,MAAM,aAAa,CAAC;AAC1G,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,OAAO,gBAAgB;IAe3B,YAAY,MAA8B;QACxC,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,QAA2B;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACF;AAED,MAAM,UAAU,4BAA4B,CAAC,MAA8B;IACzE,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -17,6 +17,7 @@ export { MobilePushTokensClient, } from './push-tokens.js';
17
17
  export type { RegisterPushTokenResponse, } from './push-tokens.js';
18
18
  export { MobileBillingClient, } from './billing.js';
19
19
  export type { PortalSession, } from './billing.js';
20
+ export { MobileUsersClient, } from './users.js';
20
21
  export { MobileTusUploader, parseForgeUrl, } from './tus.js';
21
22
  export type { TusUploadFromUriOptions, ParsedForgeUrl, } from './tus.js';
22
23
  export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export { MobileSparksClient, } from './sparks.js';
9
9
  export { MobileEntropyClient, } from './entropy.js';
10
10
  export { MobilePushTokensClient, } from './push-tokens.js';
11
11
  export { MobileBillingClient, } from './billing.js';
12
+ export { MobileUsersClient, } from './users.js';
12
13
  export { MobileTusUploader, parseForgeUrl, } from './tus.js';
13
14
  export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
14
15
  export { gateErrorFromBody, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
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,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAYrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAUrB,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"}
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,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAYrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAUrB,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,GAClB,MAAM,YAAY,CAAC;AACpB,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/types.d.ts CHANGED
@@ -48,11 +48,13 @@ export interface RateLimitInfo {
48
48
  remaining: number;
49
49
  reset: number;
50
50
  }
51
+ /** Account-scoped role. Owners and admins manage the organization and team. */
52
+ export type OrgRole = 'owner' | 'admin' | 'user';
51
53
  export interface SparkVaultUser {
52
54
  user_id: string;
53
55
  email: string;
54
56
  name?: string;
55
- role: 'admin' | 'engineer' | 'viewer';
57
+ role: OrgRole;
56
58
  has_passkey?: boolean;
57
59
  created_at: number;
58
60
  }
@@ -65,6 +67,66 @@ export interface SparkVaultAccount {
65
67
  logo_dark_url?: string;
66
68
  created_at: number;
67
69
  }
70
+ /** Fields a member admin may change on the organization. */
71
+ export interface UpdateAccountRequest {
72
+ organization_name: string;
73
+ }
74
+ /** A member's license tier. `unlicensed` consumes no paid seat. */
75
+ export type SeatType = 'full' | 'viewer' | 'unlicensed';
76
+ /** Membership lifecycle: `invited` until the invite link is accepted. */
77
+ export type OrgMemberStatus = 'active' | 'invited';
78
+ /** A member of the organization, as returned by GET /users. */
79
+ export interface OrgMember {
80
+ user_id: string;
81
+ email: string;
82
+ name: string | null;
83
+ role: OrgRole;
84
+ /** Effective license tier resolved with account context. */
85
+ seat_type: SeatType | null;
86
+ /** Period-end epoch (seconds) when a scheduled license cancellation lands, else null. */
87
+ seat_cancel_at: number | null;
88
+ status: OrgMemberStatus;
89
+ created_at: number;
90
+ last_login_at: number | null;
91
+ }
92
+ export interface ListMembersOptions {
93
+ search?: string;
94
+ status?: OrgMemberStatus;
95
+ limit?: number;
96
+ cursor?: string;
97
+ }
98
+ export interface ListMembersResponse {
99
+ users: OrgMember[];
100
+ /** Null on the last page. */
101
+ next_cursor: string | null;
102
+ }
103
+ export interface InviteMemberRequest {
104
+ email: string;
105
+ role: 'admin' | 'user';
106
+ /** Defaults to `unlicensed` server-side — licensing a seat is a billing action handled on web. */
107
+ seat_type?: SeatType;
108
+ }
109
+ export interface InviteMemberResponse {
110
+ user_id: string;
111
+ email: string;
112
+ role: 'admin' | 'user';
113
+ status: 'invited';
114
+ invited_at: number;
115
+ /** False when the invite row was created but the email failed to send. */
116
+ email_sent: boolean;
117
+ email_error?: string | null;
118
+ }
119
+ export interface RemoveMemberResponse {
120
+ user_id: string;
121
+ removed_at: number;
122
+ dvaks_revoked: number;
123
+ }
124
+ export interface ResendInviteResponse {
125
+ user_id: string;
126
+ email: string;
127
+ status: 'invited';
128
+ message: string;
129
+ }
68
130
  /** Identity attempts usage against the purchased tier cap. */
69
131
  export interface SubscriptionIdentityStatus {
70
132
  attempts_cap: number | null;
@@ -529,8 +591,8 @@ export type SparkShareStatus = {
529
591
  link_code: string;
530
592
  visibility: string;
531
593
  invites: string[];
532
- max_uses?: number | null;
533
- use_count: number;
594
+ /** Single-use lifecycle: 'active' → 'consumed' (opened once) | 'revoked'. */
595
+ status: string;
534
596
  expires_at?: number;
535
597
  created_at?: number;
536
598
  };
@@ -0,0 +1,24 @@
1
+ import type { MobileHttpClient } from './http.js';
2
+ import type { InviteMemberRequest, InviteMemberResponse, ListMembersOptions, ListMembersResponse, RemoveMemberResponse, ResendInviteResponse } from './types.js';
3
+ /**
4
+ * Organization team client (member admins only — the API gates these on the
5
+ * admin role and returns 403 otherwise).
6
+ *
7
+ * Licensing a seat is a billing action (it pushes prorated quantities onto
8
+ * Stripe), so the only seat-affecting operation exposed here is `invite`, which
9
+ * defaults new members to `unlicensed` and never charges. Assigning or changing
10
+ * a paid license is intentionally absent — clients route that to the web
11
+ * dashboard so native apps never initiate an out-of-band purchase.
12
+ */
13
+ export declare class MobileUsersClient {
14
+ private readonly http;
15
+ constructor(http: MobileHttpClient);
16
+ /** List organization members (active and invited), with optional search/filter. */
17
+ list(options?: ListMembersOptions): Promise<ListMembersResponse>;
18
+ /** Invite a coworker by email. Defaults to an unlicensed seat (no charge). */
19
+ invite(request: InviteMemberRequest): Promise<InviteMemberResponse>;
20
+ /** Remove a member, releasing their seat and revoking their DVAKs. */
21
+ remove(userId: string): Promise<RemoveMemberResponse>;
22
+ /** Resend a pending invitation email (resets the 7-day expiry). */
23
+ resendInvite(userId: string): Promise<ResendInviteResponse>;
24
+ }
package/dist/users.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Organization team client (member admins only — the API gates these on the
3
+ * admin role and returns 403 otherwise).
4
+ *
5
+ * Licensing a seat is a billing action (it pushes prorated quantities onto
6
+ * Stripe), so the only seat-affecting operation exposed here is `invite`, which
7
+ * defaults new members to `unlicensed` and never charges. Assigning or changing
8
+ * a paid license is intentionally absent — clients route that to the web
9
+ * dashboard so native apps never initiate an out-of-band purchase.
10
+ */
11
+ export class MobileUsersClient {
12
+ constructor(http) {
13
+ this.http = http;
14
+ }
15
+ /** List organization members (active and invited), with optional search/filter. */
16
+ async list(options = {}) {
17
+ const params = new URLSearchParams();
18
+ if (options.search)
19
+ params.set('search', options.search);
20
+ if (options.status)
21
+ params.set('status', options.status);
22
+ if (typeof options.limit === 'number')
23
+ params.set('limit', String(options.limit));
24
+ if (options.cursor)
25
+ params.set('cursor', options.cursor);
26
+ const query = params.toString();
27
+ const response = await this.http.get(query ? `/users?${query}` : '/users');
28
+ return response.data;
29
+ }
30
+ /** Invite a coworker by email. Defaults to an unlicensed seat (no charge). */
31
+ async invite(request) {
32
+ const response = await this.http.post('/users/invite', request);
33
+ return response.data;
34
+ }
35
+ /** Remove a member, releasing their seat and revoking their DVAKs. */
36
+ async remove(userId) {
37
+ const response = await this.http.delete(`/users/${userId}`);
38
+ return response.data;
39
+ }
40
+ /** Resend a pending invitation email (resets the 7-day expiry). */
41
+ async resendInvite(userId) {
42
+ const response = await this.http.post(`/users/${userId}/resend-invite`);
43
+ return response.data;
44
+ }
45
+ }
46
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../src/users.ts"],"names":[],"mappings":"AAUA;;;;;;;;;GASG;AACH,MAAM,OAAO,iBAAiB;IAG5B,YAAY,IAAsB;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,mFAAmF;IACnF,KAAK,CAAC,IAAI,CAAC,UAA8B,EAAE;QACzC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAClF,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAClC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CACrC,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,MAAM,CAAC,OAA4B;QACvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAuB,eAAe,EAAE,OAAO,CAAC,CAAC;QACtF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAuB,UAAU,MAAM,EAAE,CAAC,CAAC;QAClF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAuB,UAAU,MAAM,gBAAgB,CAAC,CAAC;QAC9F,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkvault/sdk-mobile",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": "Mobile SDK for SparkVault Identity, vault, folder, and ingot workflows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/account.ts CHANGED
@@ -8,6 +8,7 @@ import type {
8
8
  PinVerifyResponse,
9
9
  SparkVaultAccount,
10
10
  SparkVaultUser,
11
+ UpdateAccountRequest,
11
12
  } from './types.js';
12
13
 
13
14
  /**
@@ -103,6 +104,17 @@ export class MobileAccountClient {
103
104
  return response.data;
104
105
  }
105
106
 
107
+ /**
108
+ * Update organization settings (member admins only). Sends a JSON body — the
109
+ * logo-upload variant of PUT /account is web-only. The PUT returns a partial
110
+ * settings projection, so re-read the full account to refresh the cache and
111
+ * return a complete, canonical SparkVaultAccount.
112
+ */
113
+ async updateAccount(updates: UpdateAccountRequest): Promise<SparkVaultAccount> {
114
+ await this.http.put('/account', updates);
115
+ return this.getAccount();
116
+ }
117
+
106
118
  async revokeRefreshToken(refreshToken?: string): Promise<void> {
107
119
  const token = refreshToken ?? await this.config.tokenStorage.getRefreshToken();
108
120
  if (!token) return;
package/src/client.ts CHANGED
@@ -9,6 +9,7 @@ import { MobileIngotsClient } from './ingots.js';
9
9
  import { MobileProductsClient } from './products/index.js';
10
10
  import { MobilePushTokensClient } from './push-tokens.js';
11
11
  import { MobileSparksClient } from './sparks.js';
12
+ import { MobileUsersClient } from './users.js';
12
13
  import { MobileVaultsClient } from './vaults.js';
13
14
 
14
15
  export class SparkVaultMobile {
@@ -23,6 +24,7 @@ export class SparkVaultMobile {
23
24
  readonly entropy: MobileEntropyClient;
24
25
  readonly pushTokens: MobilePushTokensClient;
25
26
  readonly billing: MobileBillingClient;
27
+ readonly users: MobileUsersClient;
26
28
  private readonly http: MobileHttpClient;
27
29
 
28
30
  constructor(config: SparkVaultMobileConfig) {
@@ -38,6 +40,7 @@ export class SparkVaultMobile {
38
40
  this.entropy = new MobileEntropyClient(this.http);
39
41
  this.pushTokens = new MobilePushTokensClient(this.http);
40
42
  this.billing = new MobileBillingClient(this.http);
43
+ this.users = new MobileUsersClient(this.http);
41
44
 
42
45
  if (this.config.preloadIdentityConfig) {
43
46
  this.products.identity.preloadConfig();
package/src/index.ts CHANGED
@@ -76,6 +76,9 @@ export {
76
76
  export type {
77
77
  PortalSession,
78
78
  } from './billing.js';
79
+ export {
80
+ MobileUsersClient,
81
+ } from './users.js';
79
82
  export {
80
83
  MobileTusUploader,
81
84
  parseForgeUrl,
package/src/types.ts CHANGED
@@ -56,11 +56,14 @@ export interface RateLimitInfo {
56
56
  reset: number;
57
57
  }
58
58
 
59
+ /** Account-scoped role. Owners and admins manage the organization and team. */
60
+ export type OrgRole = 'owner' | 'admin' | 'user';
61
+
59
62
  export interface SparkVaultUser {
60
63
  user_id: string;
61
64
  email: string;
62
65
  name?: string;
63
- role: 'admin' | 'engineer' | 'viewer';
66
+ role: OrgRole;
64
67
  has_passkey?: boolean;
65
68
  created_at: number;
66
69
  }
@@ -75,6 +78,76 @@ export interface SparkVaultAccount {
75
78
  created_at: number;
76
79
  }
77
80
 
81
+ /** Fields a member admin may change on the organization. */
82
+ export interface UpdateAccountRequest {
83
+ organization_name: string;
84
+ }
85
+
86
+ /** A member's license tier. `unlicensed` consumes no paid seat. */
87
+ export type SeatType = 'full' | 'viewer' | 'unlicensed';
88
+
89
+ /** Membership lifecycle: `invited` until the invite link is accepted. */
90
+ export type OrgMemberStatus = 'active' | 'invited';
91
+
92
+ /** A member of the organization, as returned by GET /users. */
93
+ export interface OrgMember {
94
+ user_id: string;
95
+ email: string;
96
+ name: string | null;
97
+ role: OrgRole;
98
+ /** Effective license tier resolved with account context. */
99
+ seat_type: SeatType | null;
100
+ /** Period-end epoch (seconds) when a scheduled license cancellation lands, else null. */
101
+ seat_cancel_at: number | null;
102
+ status: OrgMemberStatus;
103
+ created_at: number;
104
+ last_login_at: number | null;
105
+ }
106
+
107
+ export interface ListMembersOptions {
108
+ search?: string;
109
+ status?: OrgMemberStatus;
110
+ limit?: number;
111
+ cursor?: string;
112
+ }
113
+
114
+ export interface ListMembersResponse {
115
+ users: OrgMember[];
116
+ /** Null on the last page. */
117
+ next_cursor: string | null;
118
+ }
119
+
120
+ export interface InviteMemberRequest {
121
+ email: string;
122
+ role: 'admin' | 'user';
123
+ /** Defaults to `unlicensed` server-side — licensing a seat is a billing action handled on web. */
124
+ seat_type?: SeatType;
125
+ }
126
+
127
+ export interface InviteMemberResponse {
128
+ user_id: string;
129
+ email: string;
130
+ role: 'admin' | 'user';
131
+ status: 'invited';
132
+ invited_at: number;
133
+ /** False when the invite row was created but the email failed to send. */
134
+ email_sent: boolean;
135
+ email_error?: string | null;
136
+ }
137
+
138
+ export interface RemoveMemberResponse {
139
+ user_id: string;
140
+ removed_at: number;
141
+ dvaks_revoked: number;
142
+ }
143
+
144
+ export interface ResendInviteResponse {
145
+ user_id: string;
146
+ email: string;
147
+ status: 'invited';
148
+ message: string;
149
+ }
150
+
78
151
  /** Identity attempts usage against the purchased tier cap. */
79
152
  export interface SubscriptionIdentityStatus {
80
153
  attempts_cap: number | null;
@@ -626,8 +699,8 @@ export type SparkShareStatus =
626
699
  link_code: string;
627
700
  visibility: string;
628
701
  invites: string[];
629
- max_uses?: number | null;
630
- use_count: number;
702
+ /** Single-use lifecycle: 'active' → 'consumed' (opened once) | 'revoked'. */
703
+ status: string;
631
704
  expires_at?: number;
632
705
  created_at?: number;
633
706
  };
package/src/users.ts ADDED
@@ -0,0 +1,59 @@
1
+ import type { MobileHttpClient } from './http.js';
2
+ import type {
3
+ InviteMemberRequest,
4
+ InviteMemberResponse,
5
+ ListMembersOptions,
6
+ ListMembersResponse,
7
+ RemoveMemberResponse,
8
+ ResendInviteResponse,
9
+ } from './types.js';
10
+
11
+ /**
12
+ * Organization team client (member admins only — the API gates these on the
13
+ * admin role and returns 403 otherwise).
14
+ *
15
+ * Licensing a seat is a billing action (it pushes prorated quantities onto
16
+ * Stripe), so the only seat-affecting operation exposed here is `invite`, which
17
+ * defaults new members to `unlicensed` and never charges. Assigning or changing
18
+ * a paid license is intentionally absent — clients route that to the web
19
+ * dashboard so native apps never initiate an out-of-band purchase.
20
+ */
21
+ export class MobileUsersClient {
22
+ private readonly http: MobileHttpClient;
23
+
24
+ constructor(http: MobileHttpClient) {
25
+ this.http = http;
26
+ }
27
+
28
+ /** List organization members (active and invited), with optional search/filter. */
29
+ async list(options: ListMembersOptions = {}): Promise<ListMembersResponse> {
30
+ const params = new URLSearchParams();
31
+ if (options.search) params.set('search', options.search);
32
+ if (options.status) params.set('status', options.status);
33
+ if (typeof options.limit === 'number') params.set('limit', String(options.limit));
34
+ if (options.cursor) params.set('cursor', options.cursor);
35
+ const query = params.toString();
36
+ const response = await this.http.get<ListMembersResponse>(
37
+ query ? `/users?${query}` : '/users'
38
+ );
39
+ return response.data;
40
+ }
41
+
42
+ /** Invite a coworker by email. Defaults to an unlicensed seat (no charge). */
43
+ async invite(request: InviteMemberRequest): Promise<InviteMemberResponse> {
44
+ const response = await this.http.post<InviteMemberResponse>('/users/invite', request);
45
+ return response.data;
46
+ }
47
+
48
+ /** Remove a member, releasing their seat and revoking their DVAKs. */
49
+ async remove(userId: string): Promise<RemoveMemberResponse> {
50
+ const response = await this.http.delete<RemoveMemberResponse>(`/users/${userId}`);
51
+ return response.data;
52
+ }
53
+
54
+ /** Resend a pending invitation email (resets the 7-day expiry). */
55
+ async resendInvite(userId: string): Promise<ResendInviteResponse> {
56
+ const response = await this.http.post<ResendInviteResponse>(`/users/${userId}/resend-invite`);
57
+ return response.data;
58
+ }
59
+ }