@arbidocs/client 0.4.85 → 0.4.86

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.js CHANGED
@@ -365,70 +365,98 @@ async function generateUserKeypairs(username, password, deploymentDomain) {
365
365
  encryptionKeyPair
366
366
  };
367
367
  }
368
+ var IDENTITY_WRAP_CONTEXT = "arbi-identity-wrap-v1";
369
+ function identityWrappingKey(passwordSecretKey) {
370
+ return sodium.crypto_generichash(
371
+ 32,
372
+ sodium.from_string(IDENTITY_WRAP_CONTEXT),
373
+ passwordSecretKey.slice(0, 32)
374
+ );
375
+ }
376
+ function generateIdentityKeypair() {
377
+ return generateRandomSigningKeypair();
378
+ }
379
+ function wrapIdentityKey(identitySecretKey, passwordSecretKey) {
380
+ const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
381
+ const key = identityWrappingKey(passwordSecretKey);
382
+ try {
383
+ const boxed = sodium.crypto_secretbox_easy(identitySecretKey, nonce, key);
384
+ const out = new Uint8Array(nonce.length + boxed.length);
385
+ out.set(nonce);
386
+ out.set(boxed, nonce.length);
387
+ return base64Encode(out);
388
+ } finally {
389
+ key.fill(0);
390
+ }
391
+ }
392
+ function unwrapIdentityKey(wrapped, passwordSecretKey) {
393
+ if (!wrapped) return passwordSecretKey;
394
+ const bytes = base64Decode(wrapped);
395
+ const nonce = bytes.slice(0, sodium.crypto_secretbox_NONCEBYTES);
396
+ const key = identityWrappingKey(passwordSecretKey);
397
+ try {
398
+ return sodium.crypto_secretbox_open_easy(
399
+ bytes.slice(sodium.crypto_secretbox_NONCEBYTES),
400
+ nonce,
401
+ key
402
+ );
403
+ } catch {
404
+ throw new Error("Incorrect password");
405
+ } finally {
406
+ key.fill(0);
407
+ }
408
+ }
368
409
 
369
410
  // src/crypto/credentials.ts
411
+ function signedNow(email, key) {
412
+ const timestamp = Math.floor(Date.now() / 1e3);
413
+ return { signature: signMessage(`${email}|${timestamp}`, key), timestamp };
414
+ }
370
415
  async function generateRegistrationCredentials(registrationData, password, deploymentDomain) {
371
- const { signingKeyPair } = await generateUserKeypairs(
416
+ const { signingKeyPair: passwordKey } = await generateUserKeypairs(
372
417
  registrationData.email,
373
418
  password,
374
419
  deploymentDomain
375
420
  );
421
+ const identity = generateIdentityKeypair();
376
422
  const request = {
377
423
  ...registrationData,
378
- signing_key: base64Encode(signingKeyPair.publicKey)
424
+ signing_key: base64Encode(identity.publicKey),
425
+ login_key: base64Encode(passwordKey.publicKey),
426
+ wrapped_identity_key: wrapIdentityKey(identity.secretKey, passwordKey.secretKey)
379
427
  };
380
- return { request, signingPrivateKey: signingKeyPair.secretKey };
428
+ return { request, signingPrivateKey: identity.secretKey };
381
429
  }
382
430
  async function generateLoginCredentials(loginData, password, deploymentDomain) {
383
431
  const { signingKeyPair } = await generateUserKeypairs(loginData.email, password, deploymentDomain);
384
- const timestamp = Math.floor(Date.now() / 1e3);
385
- const message = `${loginData.email}|${timestamp}`;
386
- const signature = signMessage(message, signingKeyPair.secretKey);
387
- const request = {
388
- ...loginData,
389
- signature,
390
- timestamp
432
+ return {
433
+ request: { ...loginData, ...signedNow(loginData.email, signingKeyPair.secretKey) },
434
+ passwordPrivateKey: signingKeyPair.secretKey
391
435
  };
392
- return { request, signingPrivateKey: signingKeyPair.secretKey };
393
436
  }
394
437
  function generateLoginCredentialsFromKey(loginData, signingPrivateKey) {
395
438
  if (signingPrivateKey.length !== 64) {
396
439
  throw new Error("Invalid signing key: must be exactly 64 bytes");
397
440
  }
398
- const timestamp = Math.floor(Date.now() / 1e3);
399
- const message = `${loginData.email}|${timestamp}`;
400
- const signature = signMessage(message, signingPrivateKey);
401
- const request = {
402
- ...loginData,
403
- signature,
404
- timestamp
405
- };
406
- return { request, signingPrivateKey };
407
- }
408
- async function generatePasswordChangeCredentials(email, currentPassword, newPassword, deploymentDomain) {
409
- const currentKeypairs = await generateUserKeypairs(email, currentPassword, deploymentDomain);
410
- const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain);
411
- const timestamp = Math.floor(Date.now() / 1e3);
412
- const message = `${email}|${timestamp}`;
413
- const signature = signMessage(message, currentKeypairs.signingKeyPair.secretKey);
414
- const request = {
415
- signature,
416
- timestamp,
417
- new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey)
441
+ return {
442
+ request: { ...loginData, ...signedNow(loginData.email, signingPrivateKey) },
443
+ signingPrivateKey
418
444
  };
419
- return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey };
420
445
  }
421
- async function generateRecoveryPasswordChangeCredentials(email, currentSigningKey, newPassword, deploymentDomain) {
422
- const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain);
423
- const timestamp = Math.floor(Date.now() / 1e3);
424
- const message = `${email}|${timestamp}`;
425
- const signature = signMessage(message, currentSigningKey);
426
- const request = {
427
- signature,
428
- timestamp,
429
- new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey)
446
+ async function generatePasswordChangeCredentials(params, deploymentDomain) {
447
+ const signer = params.currentPassword ? (await generateUserKeypairs(params.email, params.currentPassword, deploymentDomain)).signingKeyPair.secretKey : params.identitySecretKey;
448
+ const { signingKeyPair: newPasswordKey } = await generateUserKeypairs(
449
+ params.email,
450
+ params.newPassword,
451
+ deploymentDomain
452
+ );
453
+ return {
454
+ request: {
455
+ ...signedNow(params.email, signer),
456
+ new_login_key: base64Encode(newPasswordKey.publicKey),
457
+ wrapped_identity_key: wrapIdentityKey(params.identitySecretKey, newPasswordKey.secretKey)
458
+ }
430
459
  };
431
- return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey };
432
460
  }
433
461
 
434
462
  // src/middleware/bearer-auth.ts
@@ -594,7 +622,8 @@ function createReloginHandler(deps) {
594
622
  await deps.sessionStorage.saveSession({
595
623
  signingPrivateKey: session.signingPrivateKey,
596
624
  serverSessionKey: loginResult.sessionKey,
597
- userExtId: loginResult.userExtId
625
+ userExtId: loginResult.userExtId,
626
+ wrappedIdentityKey: loginResult.wrappedIdentityKey ?? null
598
627
  });
599
628
  await deps.onReloginSuccess?.({
600
629
  email: userEmail,
@@ -845,6 +874,7 @@ async function saveSession(sessionData) {
845
874
  encryptedServerSessionKey: encryptedServerSessionKey?.ciphertext,
846
875
  serverSessionKeyIV: encryptedServerSessionKey?.iv,
847
876
  userExtId: sessionData.userExtId,
877
+ wrappedIdentityKey: sessionData.wrappedIdentityKey ?? null,
848
878
  timestamp: Date.now()
849
879
  };
850
880
  const request = store.put(data);
@@ -895,7 +925,8 @@ async function getSession() {
895
925
  resolve({
896
926
  signingPrivateKey,
897
927
  serverSessionKey,
898
- userExtId: result.userExtId
928
+ userExtId: result.userExtId,
929
+ wrappedIdentityKey: result.wrappedIdentityKey ?? null
899
930
  });
900
931
  } catch (error) {
901
932
  console.error("[STORAGE] Failed to decrypt session data:", error);
@@ -911,22 +942,12 @@ async function getSession() {
911
942
  };
912
943
  });
913
944
  }
914
- async function updateSigningPrivateKey(newSigningPrivateKey) {
915
- await ensureDatabase();
916
- try {
917
- const existingSession = await getSession();
918
- if (!existingSession) {
919
- throw new Error("No existing session to update");
920
- }
921
- await saveSession({
922
- signingPrivateKey: newSigningPrivateKey,
923
- serverSessionKey: existingSession.serverSessionKey,
924
- userExtId: existingSession.userExtId
925
- });
926
- } catch (error) {
927
- console.error("[STORAGE] Failed to update signing private key:", error);
928
- throw error;
945
+ async function updateWrappedIdentityKey(wrappedIdentityKey) {
946
+ const existingSession = await getSession();
947
+ if (!existingSession) {
948
+ throw new Error("No existing session to update");
929
949
  }
950
+ await saveSession({ ...existingSession, wrappedIdentityKey });
930
951
  }
931
952
  async function clearSession() {
932
953
  memorySession = null;
@@ -1025,6 +1046,34 @@ async function register(params, deps) {
1025
1046
  return { signingPrivateKey: credentials.signingPrivateKey };
1026
1047
  }
1027
1048
 
1049
+ // src/auth/identity.ts
1050
+ function bytesEqual(a, b) {
1051
+ return a.length === b.length && a.every((byte, i) => byte === b[i]);
1052
+ }
1053
+ function encryptionPublicKeyOf(identitySecretKey) {
1054
+ return base64Encode(
1055
+ deriveEncryptionKeypairFromSigning({
1056
+ publicKey: identitySecretKey.slice(32, 64),
1057
+ secretKey: identitySecretKey
1058
+ }).publicKey
1059
+ );
1060
+ }
1061
+ function identityFromLoginResponse(passwordPrivateKey, response) {
1062
+ const identity = unwrapIdentityKey(response.wrapped_identity_key, passwordPrivateKey);
1063
+ if (encryptionPublicKeyOf(identity) !== response.user.encryption_public_key) {
1064
+ throw new Error("The account key does not match this account");
1065
+ }
1066
+ return identity;
1067
+ }
1068
+ async function unlockIdentityWithPassword(email, password, deploymentDomain) {
1069
+ const session = await getSession();
1070
+ if (!session?.signingPrivateKey) throw new Error("No active session found");
1071
+ const { signingKeyPair } = await generateUserKeypairs(email, password, deploymentDomain);
1072
+ const identity = unwrapIdentityKey(session.wrappedIdentityKey, signingKeyPair.secretKey);
1073
+ if (!bytesEqual(identity, session.signingPrivateKey)) throw new Error("Incorrect password");
1074
+ return session.signingPrivateKey;
1075
+ }
1076
+
1028
1077
  // src/auth/login.ts
1029
1078
  async function login(params, deps) {
1030
1079
  const credentials = await generateLoginCredentials(
@@ -1035,7 +1084,7 @@ async function login(params, deps) {
1035
1084
  params.password,
1036
1085
  deps.deploymentDomain
1037
1086
  );
1038
- return performLogin(credentials.request, credentials.signingPrivateKey, deps);
1087
+ return performLogin(credentials.request, { password: credentials.passwordPrivateKey }, deps);
1039
1088
  }
1040
1089
  async function loginWithKey(params, deps) {
1041
1090
  const credentials = generateLoginCredentialsFromKey(
@@ -1045,9 +1094,9 @@ async function loginWithKey(params, deps) {
1045
1094
  },
1046
1095
  params.signingPrivateKey
1047
1096
  );
1048
- return performLogin(credentials.request, credentials.signingPrivateKey, deps);
1097
+ return performLogin(credentials.request, { identity: credentials.signingPrivateKey }, deps);
1049
1098
  }
1050
- async function performLogin(request, signingPrivateKey, deps) {
1099
+ async function performLogin(request, signer, deps) {
1051
1100
  const response = await deps.fetchClient.POST("/v1/user/login", {
1052
1101
  body: request
1053
1102
  });
@@ -1058,10 +1107,12 @@ async function performLogin(request, signingPrivateKey, deps) {
1058
1107
  }
1059
1108
  const data = response.data;
1060
1109
  const serverSessionKey = base64ToBytes(data.session_key);
1110
+ const signingPrivateKey = "password" in signer ? identityFromLoginResponse(signer.password, data) : signer.identity;
1061
1111
  await saveSession({
1062
1112
  signingPrivateKey,
1063
1113
  serverSessionKey,
1064
- userExtId: data.user.external_id ?? void 0
1114
+ userExtId: data.user.external_id ?? void 0,
1115
+ wrappedIdentityKey: data.wrapped_identity_key ?? null
1065
1116
  });
1066
1117
  deps.session.setAccessToken(data.access_token);
1067
1118
  deps.session.setUser(request.email, data.user.external_id ?? void 0);
@@ -1089,40 +1140,6 @@ async function logout(session) {
1089
1140
  }
1090
1141
 
1091
1142
  // src/auth/change-password.ts
1092
- var passwordCalls = (client) => client;
1093
- async function changePassword(params, deps) {
1094
- const credentials = await generatePasswordChangeCredentials(
1095
- params.email,
1096
- params.currentPassword,
1097
- params.newPassword,
1098
- deps.deploymentDomain
1099
- );
1100
- const stored = await getSession();
1101
- if (!stored) throw new Error("Sign in to change your password");
1102
- const current = deriveEncryptionKeypairFromSigning({
1103
- publicKey: stored.signingPrivateKey.slice(32, 64),
1104
- secretKey: stored.signingPrivateKey
1105
- });
1106
- const next = deriveEncryptionKeypairFromSigning({
1107
- publicKey: credentials.newSigningPrivateKey.slice(32, 64),
1108
- secretKey: credentials.newSigningPrivateKey
1109
- });
1110
- const mailKeys = await rewrapMailKeys(deps.fetchClient, current.secretKey, next.publicKey);
1111
- const response = await passwordCalls(deps.fetchClient).POST("/v1/user/change_password", {
1112
- body: {
1113
- ...credentials.request,
1114
- ...mailKeys,
1115
- rewrapped_workspace_keys: params.rewrappedWorkspaceKeys ?? {}
1116
- }
1117
- });
1118
- if (response.error) {
1119
- throw new Error(
1120
- `Password change failed: ${typeof response.error === "object" && response.error !== null && "detail" in response.error ? response.error.detail : "Unknown error"}`
1121
- );
1122
- }
1123
- await updateSigningPrivateKey(credentials.newSigningPrivateKey);
1124
- return { newSigningPrivateKey: credentials.newSigningPrivateKey };
1125
- }
1126
1143
  function passwordChangeErrorMessage(err) {
1127
1144
  if (err instanceof Error) return err.message;
1128
1145
  if (err && typeof err === "object") {
@@ -1138,140 +1155,24 @@ function passwordChangeErrorMessage(err) {
1138
1155
  }
1139
1156
  return "Failed to change password";
1140
1157
  }
1141
- async function reEncryptDirectMessages(fetchClient, userExtId, oldSecretKey, newSecretKey) {
1142
- const { data } = await fetchClient.GET("/v1/notifications/");
1143
- const messages = (data ?? []).filter(
1144
- (n) => n.type === "user_message" && (n.content || n.attachments)
1145
- );
1146
- const oldSecrets = {};
1147
- const newSecrets = {};
1148
- const updates = [];
1149
- for (const n of messages) {
1150
- try {
1151
- const other = n.sender.external_id === userExtId ? n.recipient : n.sender;
1152
- const id = other.external_id;
1153
- oldSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, oldSecretKey);
1154
- newSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, newSecretKey);
1155
- const reEncrypt = async (ciphertext) => encryptMessageWithSharedSecret(
1156
- await decryptMessageWithSharedSecret(ciphertext, oldSecrets[id]),
1157
- newSecrets[id]
1158
- );
1159
- const content = n.content ? await reEncrypt(n.content) : void 0;
1160
- const attachments = n.attachments ? await reEncrypt(n.attachments) : void 0;
1161
- updates.push({
1162
- external_id: n.external_id,
1163
- ...content !== void 0 ? { content } : {},
1164
- ...attachments !== void 0 ? { attachments } : {}
1165
- });
1166
- } catch {
1167
- }
1168
- }
1169
- if (updates.length === 0) return 0;
1170
- const patched = await fetchClient.PATCH("/v1/notifications/", { body: { updates } });
1171
- if (!patched.data) throw new Error("Failed to save re-encrypted messages");
1172
- return updates.length;
1173
- }
1174
- async function rewrapMailKeys(fetchClient, oldPrivateKey, newPublicKey) {
1175
- const rewrappedMailKeys = {};
1176
- let mailCursor = 0;
1177
- while (mailCursor !== null) {
1178
- const result = await fetchClient.GET(
1179
- "/v1/mail/native/keys",
1180
- {
1181
- params: { query: { cursor: mailCursor } }
1182
- }
1183
- );
1184
- if (!result.data) throw new Error("Could not load mailbox keys for password change");
1185
- for (const [id, wrapped] of Object.entries(result.data.keys)) {
1186
- const key = sealedBoxDecrypt(wrapped, oldPrivateKey);
1187
- try {
1188
- rewrappedMailKeys[id] = sealedBoxEncrypt(key, newPublicKey);
1189
- } finally {
1190
- key.fill(0);
1191
- }
1192
- }
1193
- mailCursor = result.data.next_cursor ?? null;
1194
- }
1195
- const connected = await passwordCalls(fetchClient).GET("/v1/mail/native/rotation-credentials");
1196
- if (!connected.data) throw new Error("Could not load mail connections for password change");
1197
- const rewrappedMailCredentials = {};
1198
- for (const [id, wrapped] of Object.entries(connected.data)) {
1199
- const plain = sealedBoxDecrypt(wrapped, oldPrivateKey);
1200
- try {
1201
- rewrappedMailCredentials[id] = sealedBoxEncrypt(plain, newPublicKey);
1202
- } finally {
1203
- plain.fill(0);
1204
- }
1205
- }
1206
- return {
1207
- rewrapped_mail_keys: rewrappedMailKeys,
1208
- rewrapped_mail_credentials: rewrappedMailCredentials
1209
- };
1210
- }
1211
- async function changePasswordWithRekey(params, deps) {
1212
- const session = await getSession();
1213
- if (!session) throw new Error("No active session found");
1214
- const { request, newSigningPrivateKey } = params.currentPassword ? await generatePasswordChangeCredentials(
1215
- params.email,
1216
- params.currentPassword,
1217
- params.newPassword,
1218
- deps.deploymentDomain
1219
- ) : await generateRecoveryPasswordChangeCredentials(
1220
- params.email,
1221
- session.signingPrivateKey,
1222
- params.newPassword,
1158
+ async function changePassword(params, deps) {
1159
+ const fromStore = !params.identitySecretKey;
1160
+ const identitySecretKey = params.identitySecretKey ?? (await getSession())?.signingPrivateKey;
1161
+ if (!identitySecretKey) throw new Error("Sign in to change your password");
1162
+ const { request } = await generatePasswordChangeCredentials(
1163
+ {
1164
+ email: params.email,
1165
+ identitySecretKey,
1166
+ newPassword: params.newPassword,
1167
+ currentPassword: params.currentPassword
1168
+ },
1223
1169
  deps.deploymentDomain
1224
1170
  );
1225
- const current = deriveEncryptionKeypairFromSigning({
1226
- publicKey: session.signingPrivateKey.slice(32, 64),
1227
- secretKey: session.signingPrivateKey
1228
- });
1229
- const next = deriveEncryptionKeypairFromSigning({
1230
- publicKey: newSigningPrivateKey.slice(32, 64),
1231
- secretKey: newSigningPrivateKey
1232
- });
1233
- const listed = await deps.fetchClient.GET("/v1/user/workspaces");
1234
- if (!listed.data) throw new Error("Could not list your workspaces");
1235
- const rewrapped = {};
1236
- for (const ws of listed.data.filter((w) => w.is_member)) {
1237
- if (!ws.wrapped_key) continue;
1238
- try {
1239
- rewrapped[ws.external_id] = sealedBoxEncrypt(
1240
- sealedBoxDecrypt(ws.wrapped_key, current.secretKey),
1241
- next.publicKey
1242
- );
1243
- } catch {
1244
- throw new Error(`Failed to re-wrap workspace key for ${ws.name || ws.external_id}`);
1245
- }
1246
- }
1247
- let messagesReEncrypted = 0;
1248
- if (params.userExtId) {
1249
- try {
1250
- messagesReEncrypted = await reEncryptDirectMessages(
1251
- deps.fetchClient,
1252
- params.userExtId,
1253
- current.secretKey,
1254
- next.secretKey
1255
- );
1256
- } catch {
1257
- }
1258
- }
1259
- const mailKeys = await rewrapMailKeys(deps.fetchClient, current.secretKey, next.publicKey);
1260
- const response = await passwordCalls(deps.fetchClient).POST("/v1/user/change_password", {
1261
- body: {
1262
- ...request,
1263
- rewrapped_workspace_keys: rewrapped,
1264
- ...mailKeys
1265
- }
1266
- });
1171
+ const response = await deps.fetchClient.POST("/v1/user/change_password", { body: request });
1267
1172
  if (response.error || !response.data)
1268
1173
  throw response.error ?? new Error("Failed to change password");
1269
- await updateSigningPrivateKey(newSigningPrivateKey);
1270
- return {
1271
- newSigningPrivateKey,
1272
- workspacesUpdated: response.data.workspaces_updated ?? 0,
1273
- messagesReEncrypted
1274
- };
1174
+ if (fromStore) await updateWrappedIdentityKey(request.wrapped_identity_key);
1175
+ return { wrappedIdentityKey: request.wrapped_identity_key };
1275
1176
  }
1276
1177
 
1277
1178
  // src/client.ts
@@ -1370,7 +1271,8 @@ function createArbiClient(options) {
1370
1271
  return {
1371
1272
  accessToken: data.access_token,
1372
1273
  sessionKey: base64ToBytes(data.session_key),
1373
- userExtId: data.user.external_id ?? void 0
1274
+ userExtId: data.user.external_id ?? void 0,
1275
+ wrappedIdentityKey: data.wrapped_identity_key ?? null
1374
1276
  };
1375
1277
  }
1376
1278
  };
@@ -1517,6 +1419,6 @@ function isMessageType(msg, type) {
1517
1419
  return msg.type === type;
1518
1420
  }
1519
1421
 
1520
- export { API_PREFIX, CALL_KEY_BYTES, base64Decode, base64Encode, base64ToBytes, buildCallFragment, buildWebSocketUrl, bytesToBase64, canPersistSession, changePasswordWithRekey, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decodeCallKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateCallKey, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, openSealedCallKey, parseCallFragment, parseServerMessage, passwordChangeErrorMessage, prewarmKeyPairs, saveSession, sealCallKey, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey };
1422
+ export { API_PREFIX, CALL_KEY_BYTES, base64Decode, base64Encode, base64ToBytes, buildCallFragment, buildWebSocketUrl, bytesToBase64, canPersistSession, changePassword, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decodeCallKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateCallKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isMessageType, openSealedCallKey, parseCallFragment, parseServerMessage, passwordChangeErrorMessage, prewarmKeyPairs, saveSession, sealCallKey, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, updateWrappedIdentityKey, wrapIdentityKey };
1521
1423
  //# sourceMappingURL=index.js.map
1522
1424
  //# sourceMappingURL=index.js.map