@arbidocs/client 0.4.4 → 0.4.6

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/index.d.cts CHANGED
@@ -17762,11 +17762,23 @@ interface LoginWithKeyParams {
17762
17762
  signingPrivateKey: Uint8Array;
17763
17763
  ssoToken?: string;
17764
17764
  }
17765
+ /** The signed-in user's profile as the login response carries it. */
17766
+ interface LoginProfile {
17767
+ givenName: string;
17768
+ familyName: string | null;
17769
+ /** Avatar image (data URL or URL), when set. */
17770
+ picture: string | null;
17771
+ email: string;
17772
+ /** True when the account signs in through an SSO provider (the email is managed there). */
17773
+ isSso: boolean;
17774
+ }
17765
17775
  interface LoginResult {
17766
17776
  accessToken: string;
17767
17777
  userExtId?: string;
17768
17778
  /** Owner's ext_id for agent accounts; null/undefined for human users */
17769
17779
  parentExtId?: string | null;
17780
+ /** The profile from the login response, so hosts need no second request for the name. */
17781
+ profile?: LoginProfile;
17770
17782
  signingPrivateKey: Uint8Array;
17771
17783
  serverSessionKey: Uint8Array;
17772
17784
  }
@@ -17786,6 +17798,34 @@ interface ChangePasswordParams {
17786
17798
  interface ChangePasswordResult {
17787
17799
  newSigningPrivateKey: Uint8Array;
17788
17800
  }
17801
+ interface RekeyedPasswordChangeParams {
17802
+ email: string;
17803
+ newPassword: string;
17804
+ /** The current password. Omit in recovery mode: the session's own signing key proves identity. */
17805
+ currentPassword?: string;
17806
+ /** The caller's `usr-` id; needed to tell sent from received direct messages. */
17807
+ userExtId?: string;
17808
+ }
17809
+ interface RekeyedPasswordChangeResult {
17810
+ newSigningPrivateKey: Uint8Array;
17811
+ /** Workspaces the server re-keyed. */
17812
+ workspacesUpdated: number;
17813
+ /** Direct messages re-encrypted for the new key. */
17814
+ messagesReEncrypted: number;
17815
+ }
17816
+ type FetchClient = ReturnType<typeof createFetchClient<paths>>;
17817
+ /** Pull a readable message out of whatever shape a failed call carried (`{ detail }`, `Error`). */
17818
+ declare function passwordChangeErrorMessage(err: unknown): string;
17819
+ /**
17820
+ * Change (or, in recovery mode, set) the master password: derive the new keys, re-wrap the key of
17821
+ * every workspace the user is a member of for them, re-encrypt direct messages, post it all to
17822
+ * `/v1/user/change_password`, then store the new signing key. The caller shows the recovery key
17823
+ * for `newSigningPrivateKey` afterwards.
17824
+ */
17825
+ declare function changePasswordWithRekey(params: RekeyedPasswordChangeParams, deps: {
17826
+ fetchClient: FetchClient;
17827
+ deploymentDomain: string;
17828
+ }): Promise<RekeyedPasswordChangeResult>;
17789
17829
 
17790
17830
  /**
17791
17831
  * createArbiClient() — SDK entry point
@@ -18008,4 +18048,4 @@ interface ReopenDeps {
18008
18048
  */
18009
18049
  declare function createWorkspaceReopener(deps: ReopenDeps): () => Promise<boolean>;
18010
18050
 
18011
- export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
18051
+ export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type RekeyedPasswordChangeParams, type RekeyedPasswordChangeResult, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, changePasswordWithRekey, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
package/dist/index.d.ts CHANGED
@@ -17762,11 +17762,23 @@ interface LoginWithKeyParams {
17762
17762
  signingPrivateKey: Uint8Array;
17763
17763
  ssoToken?: string;
17764
17764
  }
17765
+ /** The signed-in user's profile as the login response carries it. */
17766
+ interface LoginProfile {
17767
+ givenName: string;
17768
+ familyName: string | null;
17769
+ /** Avatar image (data URL or URL), when set. */
17770
+ picture: string | null;
17771
+ email: string;
17772
+ /** True when the account signs in through an SSO provider (the email is managed there). */
17773
+ isSso: boolean;
17774
+ }
17765
17775
  interface LoginResult {
17766
17776
  accessToken: string;
17767
17777
  userExtId?: string;
17768
17778
  /** Owner's ext_id for agent accounts; null/undefined for human users */
17769
17779
  parentExtId?: string | null;
17780
+ /** The profile from the login response, so hosts need no second request for the name. */
17781
+ profile?: LoginProfile;
17770
17782
  signingPrivateKey: Uint8Array;
17771
17783
  serverSessionKey: Uint8Array;
17772
17784
  }
@@ -17786,6 +17798,34 @@ interface ChangePasswordParams {
17786
17798
  interface ChangePasswordResult {
17787
17799
  newSigningPrivateKey: Uint8Array;
17788
17800
  }
17801
+ interface RekeyedPasswordChangeParams {
17802
+ email: string;
17803
+ newPassword: string;
17804
+ /** The current password. Omit in recovery mode: the session's own signing key proves identity. */
17805
+ currentPassword?: string;
17806
+ /** The caller's `usr-` id; needed to tell sent from received direct messages. */
17807
+ userExtId?: string;
17808
+ }
17809
+ interface RekeyedPasswordChangeResult {
17810
+ newSigningPrivateKey: Uint8Array;
17811
+ /** Workspaces the server re-keyed. */
17812
+ workspacesUpdated: number;
17813
+ /** Direct messages re-encrypted for the new key. */
17814
+ messagesReEncrypted: number;
17815
+ }
17816
+ type FetchClient = ReturnType<typeof createFetchClient<paths>>;
17817
+ /** Pull a readable message out of whatever shape a failed call carried (`{ detail }`, `Error`). */
17818
+ declare function passwordChangeErrorMessage(err: unknown): string;
17819
+ /**
17820
+ * Change (or, in recovery mode, set) the master password: derive the new keys, re-wrap the key of
17821
+ * every workspace the user is a member of for them, re-encrypt direct messages, post it all to
17822
+ * `/v1/user/change_password`, then store the new signing key. The caller shows the recovery key
17823
+ * for `newSigningPrivateKey` afterwards.
17824
+ */
17825
+ declare function changePasswordWithRekey(params: RekeyedPasswordChangeParams, deps: {
17826
+ fetchClient: FetchClient;
17827
+ deploymentDomain: string;
17828
+ }): Promise<RekeyedPasswordChangeResult>;
17789
17829
 
17790
17830
  /**
17791
17831
  * createArbiClient() — SDK entry point
@@ -18008,4 +18048,4 @@ interface ReopenDeps {
18008
18048
  */
18009
18049
  declare function createWorkspaceReopener(deps: ReopenDeps): () => Promise<boolean>;
18010
18050
 
18011
- export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
18051
+ export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type RekeyedPasswordChangeParams, type RekeyedPasswordChangeResult, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, changePasswordWithRekey, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
package/dist/index.js CHANGED
@@ -999,6 +999,13 @@ async function performLogin(request, signingPrivateKey, deps) {
999
999
  accessToken: data.access_token,
1000
1000
  userExtId: data.user.external_id ?? void 0,
1001
1001
  parentExtId: data.user.parent_ext_id ?? null,
1002
+ profile: {
1003
+ givenName: data.user.given_name,
1004
+ familyName: data.user.family_name ?? null,
1005
+ picture: data.user.picture ?? null,
1006
+ email: data.user.email ?? request.email,
1007
+ isSso: data.user.is_sso === true
1008
+ },
1002
1009
  signingPrivateKey,
1003
1010
  serverSessionKey
1004
1011
  };
@@ -1032,6 +1039,106 @@ async function changePassword(params, deps) {
1032
1039
  await updateSigningPrivateKey(credentials.newSigningPrivateKey);
1033
1040
  return { newSigningPrivateKey: credentials.newSigningPrivateKey };
1034
1041
  }
1042
+ function passwordChangeErrorMessage(err) {
1043
+ if (err instanceof Error) return err.message;
1044
+ if (err && typeof err === "object") {
1045
+ const obj = err;
1046
+ if (typeof obj.detail === "string") return obj.detail;
1047
+ if (typeof obj.message === "string") return obj.message;
1048
+ if (Array.isArray(obj.detail)) {
1049
+ const msgs = obj.detail.map(
1050
+ (d) => d && typeof d.msg === "string" ? d.msg : null
1051
+ ).filter((m) => m !== null);
1052
+ if (msgs.length) return msgs.join("; ");
1053
+ }
1054
+ }
1055
+ return "Failed to change password";
1056
+ }
1057
+ async function reEncryptDirectMessages(fetchClient, userExtId, oldSecretKey, newSecretKey) {
1058
+ const { data } = await fetchClient.GET("/v1/notifications/");
1059
+ const messages = (data ?? []).filter((n) => n.type === "user_message" && n.content);
1060
+ const oldSecrets = {};
1061
+ const newSecrets = {};
1062
+ const updates = [];
1063
+ for (const n of messages) {
1064
+ try {
1065
+ const other = n.sender.external_id === userExtId ? n.recipient : n.sender;
1066
+ const id = other.external_id;
1067
+ oldSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, oldSecretKey);
1068
+ newSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, newSecretKey);
1069
+ const plain = await decryptMessageWithSharedSecret(n.content, oldSecrets[id]);
1070
+ updates.push({
1071
+ external_id: n.external_id,
1072
+ content: await encryptMessageWithSharedSecret(plain, newSecrets[id])
1073
+ });
1074
+ } catch {
1075
+ }
1076
+ }
1077
+ if (updates.length === 0) return 0;
1078
+ const patched = await fetchClient.PATCH("/v1/notifications/", { body: { updates } });
1079
+ if (!patched.data) throw new Error("Failed to save re-encrypted messages");
1080
+ return updates.length;
1081
+ }
1082
+ async function changePasswordWithRekey(params, deps) {
1083
+ const session = await getSession();
1084
+ if (!session) throw new Error("No active session found");
1085
+ const { request, newSigningPrivateKey } = params.currentPassword ? await generatePasswordChangeCredentials(
1086
+ params.email,
1087
+ params.currentPassword,
1088
+ params.newPassword,
1089
+ deps.deploymentDomain
1090
+ ) : await generateRecoveryPasswordChangeCredentials(
1091
+ params.email,
1092
+ session.signingPrivateKey,
1093
+ params.newPassword,
1094
+ deps.deploymentDomain
1095
+ );
1096
+ const current = deriveEncryptionKeypairFromSigning({
1097
+ publicKey: session.signingPrivateKey.slice(32, 64),
1098
+ secretKey: session.signingPrivateKey
1099
+ });
1100
+ const next = deriveEncryptionKeypairFromSigning({
1101
+ publicKey: newSigningPrivateKey.slice(32, 64),
1102
+ secretKey: newSigningPrivateKey
1103
+ });
1104
+ const listed = await deps.fetchClient.GET("/v1/user/workspaces");
1105
+ if (!listed.data) throw new Error("Could not list your workspaces");
1106
+ const rewrapped = {};
1107
+ for (const ws of listed.data.filter((w) => w.is_member)) {
1108
+ if (!ws.wrapped_key) continue;
1109
+ try {
1110
+ rewrapped[ws.external_id] = sealedBoxEncrypt(
1111
+ sealedBoxDecrypt(ws.wrapped_key, current.secretKey),
1112
+ next.publicKey
1113
+ );
1114
+ } catch {
1115
+ throw new Error(`Failed to re-wrap workspace key for ${ws.name || ws.external_id}`);
1116
+ }
1117
+ }
1118
+ let messagesReEncrypted = 0;
1119
+ if (params.userExtId) {
1120
+ try {
1121
+ messagesReEncrypted = await reEncryptDirectMessages(
1122
+ deps.fetchClient,
1123
+ params.userExtId,
1124
+ current.secretKey,
1125
+ next.secretKey
1126
+ );
1127
+ } catch {
1128
+ }
1129
+ }
1130
+ const response = await deps.fetchClient.POST("/v1/user/change_password", {
1131
+ body: { ...request, rewrapped_workspace_keys: rewrapped }
1132
+ });
1133
+ if (response.error || !response.data)
1134
+ throw response.error ?? new Error("Failed to change password");
1135
+ await updateSigningPrivateKey(newSigningPrivateKey);
1136
+ return {
1137
+ newSigningPrivateKey,
1138
+ workspacesUpdated: response.data.workspaces_updated ?? 0,
1139
+ messagesReEncrypted
1140
+ };
1141
+ }
1035
1142
 
1036
1143
  // src/client.ts
1037
1144
  var API_PREFIX = "/v1";
@@ -1276,6 +1383,6 @@ function isMessageType(msg, type) {
1276
1383
  return msg.type === type;
1277
1384
  }
1278
1385
 
1279
- export { API_PREFIX, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, parseServerMessage, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey };
1386
+ export { API_PREFIX, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, changePasswordWithRekey, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, parseServerMessage, passwordChangeErrorMessage, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey };
1280
1387
  //# sourceMappingURL=index.js.map
1281
1388
  //# sourceMappingURL=index.js.map