@arbidocs/client 0.4.5 → 0.4.7

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.cjs CHANGED
@@ -1006,6 +1006,13 @@ async function performLogin(request, signingPrivateKey, deps) {
1006
1006
  accessToken: data.access_token,
1007
1007
  userExtId: data.user.external_id ?? void 0,
1008
1008
  parentExtId: data.user.parent_ext_id ?? null,
1009
+ profile: {
1010
+ givenName: data.user.given_name,
1011
+ familyName: data.user.family_name ?? null,
1012
+ picture: data.user.picture ?? null,
1013
+ email: data.user.email ?? request.email,
1014
+ isSso: data.user.is_sso === true
1015
+ },
1009
1016
  signingPrivateKey,
1010
1017
  serverSessionKey
1011
1018
  };
@@ -1039,6 +1046,106 @@ async function changePassword(params, deps) {
1039
1046
  await updateSigningPrivateKey(credentials.newSigningPrivateKey);
1040
1047
  return { newSigningPrivateKey: credentials.newSigningPrivateKey };
1041
1048
  }
1049
+ function passwordChangeErrorMessage(err) {
1050
+ if (err instanceof Error) return err.message;
1051
+ if (err && typeof err === "object") {
1052
+ const obj = err;
1053
+ if (typeof obj.detail === "string") return obj.detail;
1054
+ if (typeof obj.message === "string") return obj.message;
1055
+ if (Array.isArray(obj.detail)) {
1056
+ const msgs = obj.detail.map(
1057
+ (d) => d && typeof d.msg === "string" ? d.msg : null
1058
+ ).filter((m) => m !== null);
1059
+ if (msgs.length) return msgs.join("; ");
1060
+ }
1061
+ }
1062
+ return "Failed to change password";
1063
+ }
1064
+ async function reEncryptDirectMessages(fetchClient, userExtId, oldSecretKey, newSecretKey) {
1065
+ const { data } = await fetchClient.GET("/v1/notifications/");
1066
+ const messages = (data ?? []).filter((n) => n.type === "user_message" && n.content);
1067
+ const oldSecrets = {};
1068
+ const newSecrets = {};
1069
+ const updates = [];
1070
+ for (const n of messages) {
1071
+ try {
1072
+ const other = n.sender.external_id === userExtId ? n.recipient : n.sender;
1073
+ const id = other.external_id;
1074
+ oldSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, oldSecretKey);
1075
+ newSecrets[id] ??= await computeSharedSecret(other.encryption_public_key, newSecretKey);
1076
+ const plain = await decryptMessageWithSharedSecret(n.content, oldSecrets[id]);
1077
+ updates.push({
1078
+ external_id: n.external_id,
1079
+ content: await encryptMessageWithSharedSecret(plain, newSecrets[id])
1080
+ });
1081
+ } catch {
1082
+ }
1083
+ }
1084
+ if (updates.length === 0) return 0;
1085
+ const patched = await fetchClient.PATCH("/v1/notifications/", { body: { updates } });
1086
+ if (!patched.data) throw new Error("Failed to save re-encrypted messages");
1087
+ return updates.length;
1088
+ }
1089
+ async function changePasswordWithRekey(params, deps) {
1090
+ const session = await getSession();
1091
+ if (!session) throw new Error("No active session found");
1092
+ const { request, newSigningPrivateKey } = params.currentPassword ? await generatePasswordChangeCredentials(
1093
+ params.email,
1094
+ params.currentPassword,
1095
+ params.newPassword,
1096
+ deps.deploymentDomain
1097
+ ) : await generateRecoveryPasswordChangeCredentials(
1098
+ params.email,
1099
+ session.signingPrivateKey,
1100
+ params.newPassword,
1101
+ deps.deploymentDomain
1102
+ );
1103
+ const current = deriveEncryptionKeypairFromSigning({
1104
+ publicKey: session.signingPrivateKey.slice(32, 64),
1105
+ secretKey: session.signingPrivateKey
1106
+ });
1107
+ const next = deriveEncryptionKeypairFromSigning({
1108
+ publicKey: newSigningPrivateKey.slice(32, 64),
1109
+ secretKey: newSigningPrivateKey
1110
+ });
1111
+ const listed = await deps.fetchClient.GET("/v1/user/workspaces");
1112
+ if (!listed.data) throw new Error("Could not list your workspaces");
1113
+ const rewrapped = {};
1114
+ for (const ws of listed.data.filter((w) => w.is_member)) {
1115
+ if (!ws.wrapped_key) continue;
1116
+ try {
1117
+ rewrapped[ws.external_id] = sealedBoxEncrypt(
1118
+ sealedBoxDecrypt(ws.wrapped_key, current.secretKey),
1119
+ next.publicKey
1120
+ );
1121
+ } catch {
1122
+ throw new Error(`Failed to re-wrap workspace key for ${ws.name || ws.external_id}`);
1123
+ }
1124
+ }
1125
+ let messagesReEncrypted = 0;
1126
+ if (params.userExtId) {
1127
+ try {
1128
+ messagesReEncrypted = await reEncryptDirectMessages(
1129
+ deps.fetchClient,
1130
+ params.userExtId,
1131
+ current.secretKey,
1132
+ next.secretKey
1133
+ );
1134
+ } catch {
1135
+ }
1136
+ }
1137
+ const response = await deps.fetchClient.POST("/v1/user/change_password", {
1138
+ body: { ...request, rewrapped_workspace_keys: rewrapped }
1139
+ });
1140
+ if (response.error || !response.data)
1141
+ throw response.error ?? new Error("Failed to change password");
1142
+ await updateSigningPrivateKey(newSigningPrivateKey);
1143
+ return {
1144
+ newSigningPrivateKey,
1145
+ workspacesUpdated: response.data.workspaces_updated ?? 0,
1146
+ messagesReEncrypted
1147
+ };
1148
+ }
1042
1149
 
1043
1150
  // src/client.ts
1044
1151
  var API_PREFIX = "/v1";
@@ -1289,6 +1396,7 @@ exports.base64Encode = base64Encode;
1289
1396
  exports.base64ToBytes = base64ToBytes;
1290
1397
  exports.buildWebSocketUrl = buildWebSocketUrl;
1291
1398
  exports.bytesToBase64 = bytesToBase64;
1399
+ exports.changePasswordWithRekey = changePasswordWithRekey;
1292
1400
  exports.clearAllData = clearAllData;
1293
1401
  exports.clearSession = clearSession;
1294
1402
  exports.computeSharedSecret = computeSharedSecret;
@@ -1323,6 +1431,7 @@ exports.initSodium = initSodium;
1323
1431
  exports.initializeDatabase = initializeDatabase;
1324
1432
  exports.isMessageType = isMessageType;
1325
1433
  exports.parseServerMessage = parseServerMessage;
1434
+ exports.passwordChangeErrorMessage = passwordChangeErrorMessage;
1326
1435
  exports.prewarmKeyPairs = prewarmKeyPairs;
1327
1436
  exports.saveSession = saveSession;
1328
1437
  exports.sealKeyForSession = sealKeyForSession;