@secrecy/lib 1.73.7 → 1.74.0-feat-groups-identity.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.
Files changed (41) hide show
  1. package/dist/lib/base-client.js +4 -2
  2. package/dist/lib/client/SecrecyAppClient.js +13 -17
  3. package/dist/lib/client/SecrecyCloudClient.js +129 -137
  4. package/dist/lib/client/SecrecyDbClient.js +3 -7
  5. package/dist/lib/client/SecrecyMailClient.js +38 -48
  6. package/dist/lib/client/SecrecyOrganizationClient.js +10 -12
  7. package/dist/lib/client/SecrecyPayClient.js +1 -5
  8. package/dist/lib/client/SecrecyPseudonymClient.js +4 -8
  9. package/dist/lib/client/SecrecyUserClient.js +11 -11
  10. package/dist/lib/client/SecrecyWalletClient.js +0 -2
  11. package/dist/lib/client/convert/data.js +4 -4
  12. package/dist/lib/client/convert/mail.js +5 -6
  13. package/dist/lib/client/convert/node.js +46 -34
  14. package/dist/lib/client/helpers.js +16 -7
  15. package/dist/lib/client/index.js +45 -12
  16. package/dist/lib/client/storage.js +3 -2
  17. package/dist/lib/client/types/identity.js +18 -0
  18. package/dist/lib/client/types/index.js +3 -7
  19. package/dist/lib/index.js +1 -0
  20. package/dist/types/client/SecrecyAppClient.d.ts +2 -3
  21. package/dist/types/client/SecrecyCloudClient.d.ts +18 -18
  22. package/dist/types/client/SecrecyDbClient.d.ts +1 -3
  23. package/dist/types/client/SecrecyMailClient.d.ts +2 -3
  24. package/dist/types/client/SecrecyOrganizationClient.d.ts +2 -3
  25. package/dist/types/client/SecrecyPayClient.d.ts +1 -3
  26. package/dist/types/client/SecrecyPseudonymClient.d.ts +2 -3
  27. package/dist/types/client/SecrecyUserClient.d.ts +2 -3
  28. package/dist/types/client/convert/data.d.ts +3 -3
  29. package/dist/types/client/convert/mail.d.ts +3 -5
  30. package/dist/types/client/convert/node.d.ts +5 -5
  31. package/dist/types/client/index.d.ts +9 -2
  32. package/dist/types/client/storage.d.ts +3 -2
  33. package/dist/types/client/types/identity.d.ts +29 -0
  34. package/dist/types/client/types/index.d.ts +13 -9
  35. package/dist/types/client/types/mail.d.ts +2 -1
  36. package/dist/types/client/types/node.d.ts +12 -9
  37. package/dist/types/client/types/user.d.ts +15 -0
  38. package/dist/types/client.d.ts +679 -513
  39. package/dist/types/crypto/index.d.ts +3 -3
  40. package/dist/types/index.d.ts +2 -1
  41. package/package.json +2 -2
@@ -1,10 +1,6 @@
1
1
  export class SecrecyDbClient {
2
- // #client: SecrecyClient;
3
- // #keys: KeyPair;
4
- #apiClient;
5
- constructor(_client, _keys, apiClient) {
6
- // this.#client = client;
7
- // this.#keys = keys;
8
- this.#apiClient = apiClient;
2
+ #client;
3
+ constructor(client) {
4
+ this.#client = client;
9
5
  }
10
6
  }
@@ -3,35 +3,29 @@ import { encryptCryptoBox, sodium } from '../index.js';
3
3
  import { convertInternalMailToExternal } from './convert/mail.js';
4
4
  export class SecrecyMailClient {
5
5
  #client;
6
- #keys;
7
- #apiClient;
8
- constructor(client, keys, apiClient) {
6
+ constructor(client) {
9
7
  this.#client = client;
10
- this.#keys = keys;
11
- this.#apiClient = apiClient;
12
8
  }
13
9
  async get({ id }) {
14
- const mail = await this.#apiClient.mail.byId.query({ id });
10
+ const mail = await this.#client.apiClient.mail.byId.query({ id });
15
11
  return await convertInternalMailToExternal({
16
12
  mail,
17
- client: this.#client,
18
- keyPair: this.#keys,
13
+ keyPairs: this.#client.keyPairs,
19
14
  });
20
15
  }
21
16
  async recover({ mailId }) {
22
- const { isRecovered } = await this.#apiClient.mail.recover.mutate({
17
+ const { isRecovered } = await this.#client.apiClient.mail.recover.mutate({
23
18
  id: mailId,
24
19
  });
25
20
  return isRecovered;
26
21
  }
27
22
  async deletedMails({ mailType, }) {
28
- const deletedMails = await this.#apiClient.mail.deleted.query({
23
+ const deletedMails = await this.#client.apiClient.mail.deleted.query({
29
24
  type: mailType,
30
25
  });
31
26
  return await Promise.all(deletedMails.map(async (mail) => await convertInternalMailToExternal({
32
27
  mail,
33
- client: this.#client,
34
- keyPair: this.#keys,
28
+ keyPairs: this.#client.keyPairs,
35
29
  })));
36
30
  }
37
31
  async create(data, customMessage) {
@@ -43,7 +37,7 @@ export class SecrecyMailClient {
43
37
  return { ...mail, type: 'sent' };
44
38
  }
45
39
  async waitingReceivedMails() {
46
- const waitingReceivedMails = await this.#apiClient.mail.waitingReceived.query({});
40
+ const waitingReceivedMails = await this.#client.apiClient.mail.waitingReceived.query({});
47
41
  const waitingReceivedMailsWithIds = waitingReceivedMails.map((mail) => ({
48
42
  id: Math.random().toString(36).substring(2, 9),
49
43
  sender: mail.sender,
@@ -79,18 +73,18 @@ export class SecrecyMailClient {
79
73
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
80
74
  }
81
75
  }
82
- f.name = sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#keys.publicKey, this.#keys.privateKey));
76
+ f.name = sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey));
83
77
  }
84
78
  }
85
- const updateDraftMail = await this.#apiClient.mail.updateDraft.mutate({
79
+ const updateDraftMail = await this.#client.apiClient.mail.updateDraft.mutate({
86
80
  id: draftId,
87
81
  recipients: recipients ?? null,
88
82
  replyToId: replyToId ?? null,
89
83
  body: body !== undefined
90
- ? sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#keys.publicKey, this.#keys.privateKey))
84
+ ? sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey))
91
85
  : null,
92
86
  subject: subject !== undefined
93
- ? sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#keys.publicKey, this.#keys.privateKey))
87
+ ? sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey))
94
88
  : null,
95
89
  senderFiles: senderFiles ?? null,
96
90
  hash,
@@ -98,28 +92,27 @@ export class SecrecyMailClient {
98
92
  });
99
93
  return (await convertInternalMailToExternal({
100
94
  mail: updateDraftMail,
101
- client: this.#client,
102
- keyPair: this.#keys,
95
+ keyPairs: this.#client.keyPairs,
103
96
  }));
104
97
  }
105
98
  async deleteDraft(draftId) {
106
- const { isDeleted } = await this.#apiClient.mail.deleteDraft.mutate({
99
+ const { isDeleted } = await this.#client.apiClient.mail.deleteDraft.mutate({
107
100
  id: draftId,
108
101
  });
109
102
  return isDeleted;
110
103
  }
111
104
  async deleteTrash({ ids }) {
112
- const { isDeleted } = await this.#apiClient.mail.deleteTrash.mutate({
105
+ const { isDeleted } = await this.#client.apiClient.mail.deleteTrash.mutate({
113
106
  ids,
114
107
  });
115
108
  return isDeleted;
116
109
  }
117
110
  async emptyTrash() {
118
- const { isDeleted } = await this.#apiClient.mail.emptyTrash.mutate({});
111
+ const { isDeleted } = await this.#client.apiClient.mail.emptyTrash.mutate({});
119
112
  return isDeleted;
120
113
  }
121
114
  async delete({ mailId }) {
122
- const { isDeleted } = await this.#apiClient.mail.delete.mutate({
115
+ const { isDeleted } = await this.#client.apiClient.mail.delete.mutate({
123
116
  id: mailId,
124
117
  });
125
118
  return isDeleted;
@@ -153,7 +146,7 @@ export class SecrecyMailClient {
153
146
  recipients.push(input);
154
147
  }
155
148
  }
156
- const { isSent } = await this.#apiClient.mail.sendDraft.mutate({
149
+ const { isSent } = await this.#client.apiClient.mail.sendDraft.mutate({
157
150
  temporaryRecipients,
158
151
  recipients,
159
152
  id: draft.mailIntegrityId,
@@ -175,10 +168,11 @@ export class SecrecyMailClient {
175
168
  if (input === null) {
176
169
  continue;
177
170
  }
178
- await this.#apiClient.mail.sendOne.mutate({
171
+ await this.#client.apiClient.mail.sendOne.mutate({
179
172
  id: mail.mailIntegrityId,
180
173
  recipient: {
181
174
  ...input,
175
+ recipientPublicKey: input.recipientPubKey,
182
176
  attachments: input.attachments.map((attachment) => ({
183
177
  id: attachment.dataId,
184
178
  key: attachment.key,
@@ -207,62 +201,58 @@ export class SecrecyMailClient {
207
201
  }
208
202
  senderFiles.push({
209
203
  id: data.id,
210
- name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#keys.publicKey, this.#keys.privateKey)),
204
+ name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey)),
211
205
  });
212
206
  }
213
- const createDraftMail = await this.#apiClient.mail.createDraft.mutate({
207
+ const createDraftMail = await this.#client.apiClient.mail.createDraft.mutate({
214
208
  recipients,
215
209
  replyToId,
216
- body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#keys.publicKey, this.#keys.privateKey)),
217
- subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#keys.publicKey, this.#keys.privateKey)),
210
+ body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey)),
211
+ subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.uaIdentity.identityPubKey, this.#client.uaPrivateKey)),
218
212
  senderFiles,
219
213
  hash,
220
214
  hashKey,
221
215
  });
222
216
  return (await convertInternalMailToExternal({
223
217
  mail: createDraftMail,
224
- client: this.#client,
225
- keyPair: this.#keys,
218
+ keyPairs: this.#client.keyPairs,
226
219
  }));
227
220
  }
228
221
  async read({ mailId }) {
229
- const { isRead } = await this.#apiClient.mail.read.mutate({
222
+ const { isRead } = await this.#client.apiClient.mail.read.mutate({
230
223
  id: mailId,
231
224
  });
232
225
  return isRead;
233
226
  }
234
227
  async unread({ mailId }) {
235
- const { isUnread } = await this.#apiClient.mail.unread.mutate({
228
+ const { isUnread } = await this.#client.apiClient.mail.unread.mutate({
236
229
  id: mailId,
237
230
  });
238
231
  return isUnread;
239
232
  }
240
233
  async receivedMails(input) {
241
- const receivedMails = await this.#apiClient.mail.received.query(input);
234
+ const receivedMails = await this.#client.apiClient.mail.received.query(input);
242
235
  return await Promise.all(receivedMails.map(async (mail) => (await convertInternalMailToExternal({
243
236
  mail,
244
- client: this.#client,
245
- keyPair: this.#keys,
237
+ keyPairs: this.#client.keyPairs,
246
238
  }))));
247
239
  }
248
240
  async sentMails(input) {
249
- const sentMails = await this.#apiClient.mail.sent.query(input);
241
+ const sentMails = await this.#client.apiClient.mail.sent.query(input);
250
242
  return await Promise.all(sentMails.map(async (mail) => (await convertInternalMailToExternal({
251
243
  mail,
252
- client: this.#client,
253
- keyPair: this.#keys,
244
+ keyPairs: this.#client.keyPairs,
254
245
  }))));
255
246
  }
256
247
  async draftMails(input) {
257
- const draftMails = await this.#apiClient.mail.draft.query(input);
248
+ const draftMails = await this.#client.apiClient.mail.draft.query(input);
258
249
  return await Promise.all(draftMails.map(async (mail) => (await convertInternalMailToExternal({
259
250
  mail,
260
- client: this.#client,
261
- keyPair: this.#keys,
251
+ keyPairs: this.#client.keyPairs,
262
252
  }))));
263
253
  }
264
254
  async unreadReceivedMailsCount() {
265
- const unreadReceivedMailsCount = await this.#apiClient.mail.unreadReceivedCount.query({});
255
+ const unreadReceivedMailsCount = await this.#client.apiClient.mail.unreadReceivedCount.query({});
266
256
  return unreadReceivedMailsCount;
267
257
  }
268
258
  _eachUser = async (data, subject, body, idOrMail) => {
@@ -282,17 +272,17 @@ export class SecrecyMailClient {
282
272
  const key = dataInHistory.key;
283
273
  attachments.push({
284
274
  dataId: f.id,
285
- name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#keys.privateKey)),
275
+ name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#client.uaPrivateKey)),
286
276
  key: key
287
- ? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#keys.privateKey))
277
+ ? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#client.uaPrivateKey))
288
278
  : null,
289
279
  });
290
280
  }
291
281
  return {
292
282
  // recipientId: userId,
293
- recipientId: idOrMail,
294
- body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#keys.privateKey)),
295
- subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#keys.privateKey)),
283
+ recipientPubKey: pubKey,
284
+ body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#client.uaPrivateKey)),
285
+ subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#client.uaPrivateKey)),
296
286
  attachments,
297
287
  };
298
288
  };
@@ -1,29 +1,27 @@
1
1
  export class SecrecyOrganizationClient {
2
- // readonly #client: SecrecyClient
3
- #apiClient;
4
- constructor(_client, _keys, apiClient) {
5
- // this.#client = client
6
- this.#apiClient = apiClient;
2
+ #client;
3
+ constructor(client) {
4
+ this.#client = client;
7
5
  }
8
6
  async create(input) {
9
- return this.#apiClient.org.create.mutate(input);
7
+ return this.#client.apiClient.org.create.mutate(input);
10
8
  }
11
9
  async update(input) {
12
- return this.#apiClient.org.update.mutate(input);
10
+ return this.#client.apiClient.org.update.mutate(input);
13
11
  }
14
12
  async addMember(input) {
15
- return this.#apiClient.org.addMember.mutate(input);
13
+ return this.#client.apiClient.org.addMember.mutate(input);
16
14
  }
17
15
  async removeMember(input) {
18
- return this.#apiClient.org.removeMember.mutate(input);
16
+ return this.#client.apiClient.org.removeMember.mutate(input);
19
17
  }
20
18
  async updateRole(input) {
21
- return this.#apiClient.org.updateRole.mutate(input);
19
+ return this.#client.apiClient.org.updateRole.mutate(input);
22
20
  }
23
21
  async list(input) {
24
- return this.#apiClient.org.list.query(input);
22
+ return this.#client.apiClient.org.list.query(input);
25
23
  }
26
24
  async plans(input) {
27
- return this.#apiClient.org.plans.query(input);
25
+ return this.#client.apiClient.org.plans.query(input);
28
26
  }
29
27
  }
@@ -1,12 +1,8 @@
1
1
  import { popup } from '../utils/popup-tools.js';
2
2
  export class SecrecyPayClient {
3
3
  #client;
4
- // #keys: KeyPair
5
- // #apiClient: ApiClient
6
- constructor(client, _keys, _apiClient) {
4
+ constructor(client) {
7
5
  this.#client = client;
8
- // this.#keys = keys
9
- // this.#apiClient = apiClient
10
6
  }
11
7
  async confirmPaymentIntent({ paymentIntentId, secrecyIdWhoCreatedPaymentIntent, secrecyIdWhoNeedToConfirmPaymentIntent, amount, currency, }) {
12
8
  const hash = Buffer.from(JSON.stringify({
@@ -1,19 +1,15 @@
1
1
  export class SecrecyPseudonymClient {
2
2
  #client;
3
- #keys;
4
- #apiClient;
5
- constructor(client, keys, apiClient) {
3
+ constructor(client) {
6
4
  this.#client = client;
7
- this.#keys = keys;
8
- this.#apiClient = apiClient;
9
5
  }
10
6
  async askForLabel(input) {
11
- return await this.#apiClient.pseudonym.askForLabel.query(input);
7
+ return await this.#client.apiClient.pseudonym.askForLabel.query(input);
12
8
  }
13
9
  async askForUser(input) {
14
- return await this.#apiClient.pseudonym.askForUser.query(input);
10
+ return await this.#client.apiClient.pseudonym.askForUser.query(input);
15
11
  }
16
12
  async cross(input) {
17
- return await this.#apiClient.pseudonym.cross.query(input);
13
+ return await this.#client.apiClient.pseudonym.cross.query(input);
18
14
  }
19
15
  }
@@ -1,30 +1,30 @@
1
1
  export class SecrecyUserClient {
2
- #apiClient;
3
- constructor(_client, _keys, apiClient) {
4
- this.#apiClient = apiClient;
2
+ #client;
3
+ constructor(client) {
4
+ this.#client = client;
5
5
  }
6
6
  async answerInvitation(input) {
7
- return await this.#apiClient.contacts.answerInvitation.mutate(input);
7
+ return await this.#client.apiClient.contacts.answerInvitation.mutate(input);
8
8
  }
9
9
  async cancelInvitation(input) {
10
- return await this.#apiClient.contacts.cancelInvitation.mutate(input);
10
+ return await this.#client.apiClient.contacts.cancelInvitation.mutate(input);
11
11
  }
12
12
  async createInvitation(input) {
13
- return await this.#apiClient.contacts.createInvitation.mutate(input);
13
+ return await this.#client.apiClient.contacts.createInvitation.mutate(input);
14
14
  }
15
15
  async getContacts(input) {
16
- return await this.#apiClient.contacts.getContacts.query(input);
16
+ return await this.#client.apiClient.contacts.getContacts.query(input);
17
17
  }
18
18
  async getReceivedInvitations(input) {
19
- return await this.#apiClient.contacts.getReceivedInvitations.query(input);
19
+ return await this.#client.apiClient.contacts.getReceivedInvitations.query(input);
20
20
  }
21
21
  async getSentInvitations(input) {
22
- return await this.#apiClient.contacts.getSentInvitations.query(input);
22
+ return await this.#client.apiClient.contacts.getSentInvitations.query(input);
23
23
  }
24
24
  async removeContact(input) {
25
- return await this.#apiClient.contacts.removeContact.mutate(input);
25
+ return await this.#client.apiClient.contacts.removeContact.mutate(input);
26
26
  }
27
27
  async getUsers(input) {
28
- return await this.#apiClient.account.getUsers.query(input);
28
+ return await this.#client.apiClient.account.getUsers.query(input);
29
29
  }
30
30
  }
@@ -1,11 +1,9 @@
1
1
  import { popup } from '../utils/popup-tools.js';
2
2
  export class SecrecyWalletClient {
3
3
  #client;
4
- // #keys: KeyPair;
5
4
  // #thunder: ReturnType<typeof Thunder>;
6
5
  constructor(client) {
7
6
  this.#client = client;
8
- // this.#keys = keys;
9
7
  // this.#thunder = thunder;
10
8
  }
11
9
  async createTransaction({ network = 'mainnet', tx, }) {
@@ -1,7 +1,7 @@
1
1
  import { dataCache } from '../../cache.js';
2
2
  import { decryptCryptoBox } from '../../crypto/index.js';
3
3
  import { sodium } from '../../sodium.js';
4
- export function apiDataToInternal(apiData, keyPair) {
4
+ export function apiDataToInternal(apiData, keyPairs) {
5
5
  const data = {
6
6
  id: apiData.id,
7
7
  md5: apiData.md5,
@@ -10,7 +10,7 @@ export function apiDataToInternal(apiData, keyPair) {
10
10
  size: apiData.size,
11
11
  sizeEncrypted: apiData.sizeEncrypted,
12
12
  key: apiData.access.key
13
- ? sodium.to_hex(decryptCryptoBox(sodium.from_hex(apiData.access.key), apiData.access.sharedByPubKey, keyPair.privateKey))
13
+ ? sodium.to_hex(decryptCryptoBox(sodium.from_hex(apiData.access.key), apiData.access.sharedByPubKey, keyPairs[apiData.access.identityPubKey]))
14
14
  : null,
15
15
  mime: apiData.mime ?? undefined,
16
16
  ext: apiData.ext ?? undefined,
@@ -30,6 +30,6 @@ export function internalDataToExternalData(internal) {
30
30
  ext: internal.ext ?? undefined,
31
31
  };
32
32
  }
33
- export function apiDataToExternal(apiData, keyPair) {
34
- return internalDataToExternalData(apiDataToInternal(apiData, keyPair));
33
+ export function apiDataToExternal(apiData, keyPairs) {
34
+ return internalDataToExternalData(apiDataToInternal(apiData, keyPairs));
35
35
  }
@@ -1,5 +1,5 @@
1
- import { sodium, decryptCryptoBox, } from '../../index.js';
2
- export async function convertInternalMailToExternal({ client, mail, keyPair, }) {
1
+ import { sodium, decryptCryptoBox } from '../../index.js';
2
+ export async function convertInternalMailToExternal({ mail, keyPairs, }) {
3
3
  let type = mail.type;
4
4
  if (mail.mailIntegrityDraft !== null) {
5
5
  type = 'draft';
@@ -8,10 +8,8 @@ export async function convertInternalMailToExternal({ client, mail, keyPair, })
8
8
  if (mI === null) {
9
9
  throw new Error('Mail integrity is null');
10
10
  }
11
- const pubKey = mail.type === 'received'
12
- ? await client.app.userPublicKey(mail.sender.id)
13
- : keyPair.publicKey;
14
- const privateKey = keyPair.privateKey;
11
+ const pubKey = mail.senderPubKey;
12
+ const privateKey = keyPairs[mail.recipientPubKey];
15
13
  const body = sodium.to_string(decryptCryptoBox(sodium.from_hex(mail.body), pubKey, privateKey));
16
14
  const subject = sodium.to_string(decryptCryptoBox(sodium.from_hex(mail.subject), pubKey, privateKey));
17
15
  const hash = sodium.crypto_generichash(sodium.crypto_generichash_BYTES, JSON.stringify({ body, subject }), mI.hashKey, 'hex');
@@ -30,6 +28,7 @@ export async function convertInternalMailToExternal({ client, mail, keyPair, })
30
28
  temporaryRecipients: [], // TODO
31
29
  recipients: mI.recipients,
32
30
  sender: mail.sender,
31
+ senderPublicKey: mail.senderPubKey,
33
32
  attachments: mail.attachments.map((f) => {
34
33
  const name = sodium.to_string(decryptCryptoBox(sodium.from_hex(f.name), pubKey, privateKey));
35
34
  return {
@@ -3,11 +3,11 @@ import { decryptCryptoBox } from '../../crypto/index.js';
3
3
  import { nodesCache, nodesEncryptionCache } from '../../cache.js';
4
4
  import { decryptSecretStream } from '../../crypto/data.js';
5
5
  import { apiDataToInternal, internalDataToExternalData } from './data.js';
6
- async function apiNodeToInternal(apiNode, keyPair) {
6
+ async function apiNodeToInternal(apiNode, keyPairs) {
7
7
  const internal = {
8
8
  id: apiNode.id,
9
9
  type: apiNode.type,
10
- access: apiNode.access,
10
+ accesses: apiNode.accesses,
11
11
  name: apiNode.name,
12
12
  isFavorite: apiNode.isFavorite,
13
13
  breadcrumb: 'breadcrumb' in apiNode ? apiNode.breadcrumb : [],
@@ -21,38 +21,48 @@ async function apiNodeToInternal(apiNode, keyPair) {
21
21
  createdAt: apiNode.createdAt,
22
22
  updatedAt: apiNode.updatedAt,
23
23
  deletedAt: apiNode.deletedAt,
24
- users: apiNode.users,
24
+ identities: apiNode.identities,
25
+ permissions: apiNode.permissions,
25
26
  parentId: apiNode.parentId ?? null,
26
27
  currentDataId: apiNode.currentDataId ?? null,
27
28
  };
28
- if (apiNode.access.nameKey !== null) {
29
- const key = decryptCryptoBox(sodium.from_hex(apiNode.access.nameKey), apiNode.access.sharedByPubKey, keyPair.privateKey);
30
- internal.name = sodium.to_string(await decryptSecretStream(key, sodium.from_hex(internal.name)));
31
- internal.access.nameKey = sodium.to_hex(key);
29
+ for (const access of internal.accesses) {
30
+ if (access.nameKey === null) {
31
+ continue;
32
+ }
33
+ const pk = keyPairs[access.identityPubKey];
34
+ const key = decryptCryptoBox(sodium.from_hex(access.nameKey), access.sharedByPubKey, pk);
35
+ access.nameKey = sodium.to_hex(key);
36
+ }
37
+ const firstAccess = internal.accesses[0];
38
+ if (!firstAccess || firstAccess.nameKey === null) {
39
+ throw new Error('No access found for node ' + internal.id);
32
40
  }
41
+ internal.name = sodium.to_string(await decryptSecretStream(sodium.from_hex(firstAccess.nameKey), sodium.from_hex(internal.name)));
33
42
  for (const b of internal.breadcrumb) {
34
43
  if (b.nameKey === null) {
35
44
  continue;
36
45
  }
37
- const key = decryptCryptoBox(sodium.from_hex(b.nameKey), b.pubKey, keyPair.privateKey);
46
+ const pk = keyPairs[b.identityPubKey];
47
+ const key = decryptCryptoBox(sodium.from_hex(b.nameKey), b.sharedByPubKey, pk);
38
48
  b.nameKey = sodium.to_hex(key);
39
49
  b.name = sodium.to_string(await decryptSecretStream(key, sodium.from_hex(b.name)));
40
50
  }
41
51
  nodesCache.set(internal.id, internal);
42
52
  return internal;
43
53
  }
44
- export async function apiNodeFullToInternalFull(apiNodeFull, keyPair) {
45
- const f = await apiNodeToInternal(apiNodeFull, keyPair);
54
+ export async function apiNodeFullToInternalFull(apiNodeFull, keyPairs) {
55
+ const f = await apiNodeToInternal(apiNodeFull, keyPairs);
46
56
  const nodeFull = {
47
57
  ...f,
48
58
  current: !!apiNodeFull.current
49
- ? apiDataToInternal(apiNodeFull.current, keyPair)
59
+ ? apiDataToInternal(apiNodeFull.current, keyPairs)
50
60
  : undefined,
51
61
  parent: apiNodeFull.parent !== null
52
- ? await apiNodeToInternal(apiNodeFull.parent, keyPair)
62
+ ? await apiNodeToInternal(apiNodeFull.parent, keyPairs)
53
63
  : null,
54
- children: await Promise.all(apiNodeFull.children.map(async (s) => await apiNodeToInternal(s, keyPair))),
55
- history: apiNodeFull.history.map((f) => apiDataToInternal(f, keyPair)),
64
+ children: await Promise.all(apiNodeFull.children.map(async (s) => await apiNodeToInternal(s, keyPairs))),
65
+ history: apiNodeFull.history.map((f) => apiDataToInternal(f, keyPairs)),
56
66
  };
57
67
  nodesCache.set(f.id, nodeFull);
58
68
  return nodeFull;
@@ -60,19 +70,19 @@ export async function apiNodeFullToInternalFull(apiNodeFull, keyPair) {
60
70
  function internalNodeToNode(internal) {
61
71
  const node = {
62
72
  ...internal,
63
- breadcrumb: internal.breadcrumb.map((b) => ({
64
- id: b.id,
65
- name: b.name,
66
- })),
67
- access: {
68
- isRoot: internal.access.isRoot,
69
- sharedByPubKey: internal.access.sharedByPubKey,
70
- rights: internal.access.rights,
71
- addAccess: internal.access.addAccess,
72
- delAccess: internal.access.delAccess,
73
- sharingAddAccess: internal.access.sharingAddAccess,
74
- sharingDelAccess: internal.access.sharingDelAccess,
75
- },
73
+ // breadcrumb: internal.breadcrumb.map((b) => ({
74
+ // id: b.id,
75
+ // name: b.name,
76
+ // })),
77
+ // access: {
78
+ // isRoot: internal.access.isRoot,
79
+ // sharedByPubKey: internal.access.sharedByPubKey,
80
+ // rights: internal.access.rights,
81
+ // addAccess: internal.access.addAccess,
82
+ // delAccess: internal.access.delAccess,
83
+ // sharingAddAccess: internal.access.sharingAddAccess,
84
+ // sharingDelAccess: internal.access.sharingDelAccess,
85
+ // },
76
86
  };
77
87
  return node;
78
88
  }
@@ -87,17 +97,18 @@ export function internalNodeFullToNodeFull(internal) {
87
97
  : undefined,
88
98
  };
89
99
  }
90
- export async function apiNodeToExternalNodeFull(apiNodeFull, keyPair) {
91
- const apiNode = await apiNodeFullToInternalFull(apiNodeFull, keyPair);
100
+ export async function apiNodeToExternalNodeFull(apiNodeFull, keyPairs) {
101
+ const apiNode = await apiNodeFullToInternalFull(apiNodeFull, keyPairs);
92
102
  return internalNodeFullToNodeFull(apiNode);
93
103
  }
94
- export async function apiNodeToExternal(apiNode, keyPair) {
95
- const internal = await apiNodeToInternal(apiNode, keyPair);
104
+ export async function apiNodeToExternal(apiNode, keyPairs) {
105
+ const internal = await apiNodeToInternal(apiNode, keyPairs);
96
106
  return internalNodeToNode(internal);
97
107
  }
98
- export async function apiNodeForEncryptionToInternal(apiNode, keyPair) {
108
+ export async function apiNodeForEncryptionToInternal(apiNode, keyPairs) {
99
109
  const history = apiNode.history.map((history) => {
100
- const key = decryptCryptoBox(sodium.from_hex(history.access.key), history.access.sharedByPublicKey, keyPair.privateKey);
110
+ const pk = keyPairs[history.access.identityPubKey];
111
+ const key = decryptCryptoBox(sodium.from_hex(history.access.key), history.access.sharedByPublicKey, pk);
101
112
  return {
102
113
  id: history.id,
103
114
  key: sodium.to_hex(key),
@@ -112,7 +123,8 @@ export async function apiNodeForEncryptionToInternal(apiNode, keyPair) {
112
123
  };
113
124
  internal.access = { ...apiNode.access };
114
125
  if (apiNode.access.nameKey !== null) {
115
- const key = decryptCryptoBox(sodium.from_hex(apiNode.access.nameKey), apiNode.access.sharedByPublicKey, keyPair.privateKey);
126
+ const pk = keyPairs[apiNode.access.identityPubKey];
127
+ const key = decryptCryptoBox(sodium.from_hex(apiNode.access.nameKey), apiNode.access.sharedByPublicKey, pk);
116
128
  internal.name = sodium.to_string(await decryptSecretStream(key, sodium.from_hex(internal.name)));
117
129
  internal.access.nameKey = sodium.to_hex(key);
118
130
  }
@@ -21,23 +21,26 @@ export function getSecrecyClient(opts = {}) {
21
21
  const storage = getStorage(opts.session);
22
22
  const infos = parseInfos();
23
23
  if (infos !== null) {
24
- storage.userAppKeys.save(infos.keys);
24
+ storage.identities.save(infos.identities);
25
25
  storage.userAppSession.save(infos.uaSession);
26
26
  storage.jwt.save(infos.jwt);
27
27
  return new SecrecyClient({
28
28
  uaSession: infos.uaSession,
29
- uaKeys: infos.keys,
29
+ identities: infos.identities,
30
+ keyPairs: infos.keyPairs,
30
31
  uaJwt: infos.jwt,
31
32
  secrecyUrls: opts.secrecyUrls,
32
33
  });
33
34
  }
34
35
  const uaSession = storage.userAppSession.load();
35
- const uaKeys = storage.userAppKeys.load();
36
+ const identities = storage.identities.load();
37
+ const keyPairs = storage.keyPairs.load();
36
38
  const uaJwt = storage.jwt.load();
37
- if (uaSession && uaKeys && uaJwt) {
39
+ if (uaSession && identities && keyPairs && uaJwt) {
38
40
  return new SecrecyClient({
39
41
  uaSession,
40
- uaKeys,
42
+ identities,
43
+ keyPairs,
41
44
  uaJwt,
42
45
  secrecyUrls: opts.secrecyUrls,
43
46
  });
@@ -64,11 +67,13 @@ export async function login({ appId, context, path, redirect, scopes, backPath,
64
67
  const validate = (infos) => {
65
68
  const storage = getStorage(session);
66
69
  storage.userAppSession.save(infos.uaSession);
67
- storage.userAppKeys.save(infos.keys);
70
+ storage.identities.save(infos.identities);
71
+ storage.keyPairs.save(infos.keyPairs);
68
72
  storage.jwt.save(infos.jwt);
69
73
  resolve(new SecrecyClient({
70
74
  uaSession: infos.uaSession,
71
- uaKeys: infos.keys,
75
+ identities: infos.identities,
76
+ keyPairs: infos.keyPairs,
72
77
  uaJwt: infos.jwt,
73
78
  secrecyUrls,
74
79
  }));
@@ -108,6 +113,10 @@ export async function login({ appId, context, path, redirect, scopes, backPath,
108
113
  }
109
114
  else {
110
115
  if (context) {
116
+ if (context.userId && client.uaIdentity.userId !== context.userId) {
117
+ innerLogin();
118
+ return;
119
+ }
111
120
  const me = await client.me();
112
121
  if ((context.userId && context.userId !== me.id) ||
113
122
  (context.orgId && context.orgId !== me.organization.id)) {