@secrecy/lib 1.74.2 → 1.75.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 (46) hide show
  1. package/dist/lib/base-client.js +26 -2
  2. package/dist/lib/client/SecrecyAppClient.js +13 -17
  3. package/dist/lib/client/SecrecyCloudClient.js +131 -135
  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 +17 -7
  15. package/dist/lib/client/index.js +48 -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/client/upload.js +29 -17
  20. package/dist/lib/crypto/domain.js +7 -3
  21. package/dist/lib/index.js +2 -0
  22. package/dist/types/base-client.d.ts +2 -0
  23. package/dist/types/client/SecrecyAppClient.d.ts +2 -3
  24. package/dist/types/client/SecrecyCloudClient.d.ts +18 -18
  25. package/dist/types/client/SecrecyDbClient.d.ts +1 -3
  26. package/dist/types/client/SecrecyMailClient.d.ts +2 -3
  27. package/dist/types/client/SecrecyOrganizationClient.d.ts +2 -3
  28. package/dist/types/client/SecrecyPayClient.d.ts +1 -3
  29. package/dist/types/client/SecrecyPseudonymClient.d.ts +2 -3
  30. package/dist/types/client/SecrecyUserClient.d.ts +2 -3
  31. package/dist/types/client/convert/data.d.ts +3 -3
  32. package/dist/types/client/convert/mail.d.ts +3 -5
  33. package/dist/types/client/convert/node.d.ts +5 -5
  34. package/dist/types/client/index.d.ts +11 -3
  35. package/dist/types/client/storage.d.ts +3 -2
  36. package/dist/types/client/types/identity.d.ts +29 -0
  37. package/dist/types/client/types/index.d.ts +13 -9
  38. package/dist/types/client/types/mail.d.ts +2 -1
  39. package/dist/types/client/types/node.d.ts +12 -9
  40. package/dist/types/client/types/user.d.ts +15 -0
  41. package/dist/types/client/upload.d.ts +4 -3
  42. package/dist/types/client.d.ts +1438 -1050
  43. package/dist/types/crypto/domain.d.ts +5 -3
  44. package/dist/types/crypto/index.d.ts +3 -3
  45. package/dist/types/index.d.ts +3 -1
  46. package/package.json +21 -21
@@ -11,7 +11,9 @@ import { SecrecyPseudonymClient } from './SecrecyPseudonymClient.js';
11
11
  import { decryptAnonymous } from '../crypto/index.js';
12
12
  import { SecrecyOrganizationClient } from './SecrecyOrganizationClient.js';
13
13
  export class SecrecyClient extends BaseClient {
14
- #keys;
14
+ #groupIdentities;
15
+ #uaIdentity;
16
+ #keyPairs;
15
17
  cloud;
16
18
  mail;
17
19
  app;
@@ -36,22 +38,53 @@ export class SecrecyClient extends BaseClient {
36
38
  }
37
39
  },
38
40
  });
39
- this.#keys = opts.uaKeys;
40
- this.cloud = new SecrecyCloudClient(this, this.#keys, this.client);
41
- this.mail = new SecrecyMailClient(this, this.#keys, this.client);
42
- this.app = new SecrecyAppClient(opts.uaJwt, this, this.#keys, this.client);
43
- this.db = new SecrecyDbClient(this, this.#keys, this.client);
44
- this.organization = new SecrecyOrganizationClient(this, this.#keys, this.client);
41
+ this.#keyPairs = opts.keyPairs;
42
+ this.#groupIdentities = opts.identities.filter((i) => i.kind === 'GROUP');
43
+ const uaIdentities = opts.identities.filter((i) => i.kind === 'USER_APP');
44
+ if (uaIdentities.length !== 1) {
45
+ throw new Error('One USER_APP identity is required');
46
+ }
47
+ this.#uaIdentity = uaIdentities[0];
48
+ this.cloud = new SecrecyCloudClient(this);
49
+ this.mail = new SecrecyMailClient(this);
50
+ this.app = new SecrecyAppClient(opts.uaJwt, this);
51
+ this.db = new SecrecyDbClient(this);
52
+ this.organization = new SecrecyOrganizationClient(this);
45
53
  this.wallet = new SecrecyWalletClient(this);
46
- this.pay = new SecrecyPayClient(this, this.#keys, this.client);
47
- this.user = new SecrecyUserClient(this, this.#keys, this.client);
48
- this.pseudonym = new SecrecyPseudonymClient(this, this.#keys, this.client);
54
+ this.pay = new SecrecyPayClient(this);
55
+ this.user = new SecrecyUserClient(this);
56
+ this.pseudonym = new SecrecyPseudonymClient(this);
49
57
  }
50
58
  get publicKey() {
51
- return this.#keys.publicKey;
59
+ return this.#uaIdentity.identityPubKey;
60
+ }
61
+ get apiClient() {
62
+ return this.client;
63
+ }
64
+ get keyPairs() {
65
+ return this.#keyPairs;
66
+ }
67
+ getPrivateKey(pubKey) {
68
+ const privateKey = this.#keyPairs[pubKey];
69
+ if (privateKey === undefined) {
70
+ throw new Error(`Missing private key for public key ${pubKey}`);
71
+ }
72
+ return privateKey;
73
+ }
74
+ get uaPrivateKey() {
75
+ return this.getPrivateKey(this.#uaIdentity.identityPubKey);
76
+ }
77
+ get groupIdentities() {
78
+ return this.#groupIdentities;
79
+ }
80
+ get uaIdentity() {
81
+ return this.#uaIdentity;
52
82
  }
53
83
  decryptAnonymous(data) {
54
- return decryptAnonymous(data, this.#keys);
84
+ return decryptAnonymous(data, {
85
+ publicKey: this.#uaIdentity.identityPubKey,
86
+ privateKey: this.uaPrivateKey,
87
+ });
55
88
  }
56
89
  async logout(sessionId) {
57
90
  nodesCache.clear();
@@ -59,4 +92,7 @@ export class SecrecyClient extends BaseClient {
59
92
  publicKeysCache.clear();
60
93
  await super.logout(sessionId);
61
94
  }
95
+ async getIdentities(input) {
96
+ return await this.client.identity.getMany.query(input);
97
+ }
62
98
  }
@@ -1,7 +1,8 @@
1
1
  import { storeBuddy } from '../utils/store-buddy.js';
2
2
  export function getStorage(session) {
3
3
  const userAppSession = storeBuddy(`secrecy.user_app_session`, session).init(null);
4
- const userAppKeys = storeBuddy(`secrecy.user_app_keys`, session).init(null);
4
+ const identities = storeBuddy(`secrecy.identities`, session).init(null);
5
+ const keyPairs = storeBuddy(`secrecy.key_pairs`, session).init(null);
5
6
  const jwt = storeBuddy(`secrecy.jwt`, session).init(null);
6
- return { userAppKeys, userAppSession, jwt };
7
+ return { identities, keyPairs, userAppSession, jwt };
7
8
  }
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod/v4';
2
+ export const userAppSchema = z.object({
3
+ kind: z.literal('USER_APP'),
4
+ identityPubKey: z.string(),
5
+ userId: z.string(),
6
+ appId: z.string(),
7
+ });
8
+ export const groupSchema = z.object({
9
+ kind: z.literal('GROUP'),
10
+ identityPubKey: z.string(),
11
+ groupId: z.string(),
12
+ sharedByPubKey: z.string(),
13
+ groupOwnerPubKey: z.string(),
14
+ });
15
+ export const accessIdentitySchema = z.discriminatedUnion('kind', [
16
+ userAppSchema,
17
+ groupSchema,
18
+ ]);
@@ -1,13 +1,9 @@
1
1
  import { z } from 'zod';
2
- const keyPair = z
3
- .object({
4
- publicKey: z.string(),
5
- privateKey: z.string(),
6
- })
7
- .strict();
2
+ import { accessIdentitySchema } from './identity.js';
8
3
  export const secrecyUserApp = z
9
4
  .object({
10
- keys: keyPair,
5
+ identities: accessIdentitySchema.array(),
6
+ keyPairs: z.record(z.string(), z.string()),
11
7
  jwt: z.string(),
12
8
  uaSession: z.string(),
13
9
  })
@@ -11,11 +11,11 @@ import { promiseAllLimit } from '../utils/promise.js';
11
11
  import { encryptDataAndKey } from '../crypto/domain.js';
12
12
  import { derivePassword, generatePassword } from '../crypto/helpers.js';
13
13
  import { decryptCryptoBox, encryptSecretBox } from '../crypto/index.js';
14
- export async function uploadData({ storageType, data, password, forcePassword = false, encrypted = true, encryptProgress, uploadProgress, signal, meta, keyPair, apiClient, }) {
14
+ export async function uploadData({ storageType, data, password, forcePassword = false, encrypted = true, encryptProgress, uploadProgress, signal, meta, uaIdentity, keyPairs, apiClient, }) {
15
15
  if (!encrypted && (password || forcePassword)) {
16
16
  throw new Error('Cannot share unencrypted data with a password!');
17
17
  }
18
- if (encrypted && !password && !forcePassword && !keyPair) {
18
+ if (encrypted && !password && !forcePassword && !uaIdentity) {
19
19
  throw new Error('Cannot share encrypted data without a password!');
20
20
  }
21
21
  apiClient ??= getTrpcGuestClient();
@@ -37,7 +37,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
37
37
  if (storageType === 'lite' && dataBuffer.byteLength > kiloToBytes(1024)) {
38
38
  throw new Error('The data is too big for lite upload!');
39
39
  }
40
- if (!keyPair && storageType === 'cold') {
40
+ if (!uaIdentity && storageType === 'cold') {
41
41
  throw new Error('Cold storage is only for logged users!');
42
42
  }
43
43
  const compressed = encrypted ? compress(dataBuffer) : dataBuffer;
@@ -45,7 +45,8 @@ export async function uploadData({ storageType, data, password, forcePassword =
45
45
  ? await encryptDataAndKey({
46
46
  data: compressed,
47
47
  progress: encryptProgress,
48
- keyPair,
48
+ uaIdentity,
49
+ keyPairs,
49
50
  signal,
50
51
  })
51
52
  : {
@@ -73,13 +74,17 @@ export async function uploadData({ storageType, data, password, forcePassword =
73
74
  key = dataKey;
74
75
  }
75
76
  else {
76
- if (!keyPair) {
77
+ if (!uaIdentity) {
77
78
  throw new Error('Unable to encrypt data without keyPair!');
78
79
  }
79
80
  if (!data.key) {
80
81
  throw new Error('Unable to encrypt data without key!');
81
82
  }
82
- key = decryptCryptoBox(sodium.from_hex(data.key), data.keyPair.pub, keyPair.privateKey);
83
+ const priv = keyPairs?.[data.keyPair.pub];
84
+ if (typeof priv !== 'string') {
85
+ throw new Error('Unable to encrypt data without keyPair!');
86
+ }
87
+ key = decryptCryptoBox(sodium.from_hex(data.key), data.keyPair.pub, priv);
83
88
  }
84
89
  // NOTE: Process to create a sharing for a auth client (todo: endpoint)
85
90
  return {
@@ -105,7 +110,6 @@ export async function uploadData({ storageType, data, password, forcePassword =
105
110
  type: 'unencrypted',
106
111
  content: Buffer.from(encryptedData),
107
112
  md5: md5Data,
108
- sizeEncrypted: undefined,
109
113
  size: BigInt(dataBuffer.byteLength),
110
114
  ...filetype,
111
115
  };
@@ -120,7 +124,9 @@ export async function uploadData({ storageType, data, password, forcePassword =
120
124
  id: uploadData.id,
121
125
  storageType: 'lite',
122
126
  size: uploadDataArgs.size,
123
- sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
127
+ sizeEncrypted: uploadDataArgs.type === 'encrypted'
128
+ ? uploadDataArgs.sizeEncrypted
129
+ : null,
124
130
  data: dataBuffer,
125
131
  ...filetype,
126
132
  };
@@ -145,7 +151,6 @@ export async function uploadData({ storageType, data, password, forcePassword =
145
151
  type: 'unencrypted',
146
152
  md5: md5Data,
147
153
  size: BigInt(dataBuffer.byteLength),
148
- sizeEncrypted: undefined,
149
154
  ...filetype,
150
155
  };
151
156
  const uploadDataCaller = storageType === 's3'
@@ -155,12 +160,15 @@ export async function uploadData({ storageType, data, password, forcePassword =
155
160
  signal,
156
161
  });
157
162
  if (uploadData.parts.length === 0) {
158
- if (uploadData.type === 'authed' &&
159
- (typeof keyPair === 'undefined' ||
160
- typeof keyPair === 'string' ||
161
- uploadData.keyPair.pub !== keyPair.publicKey)) {
162
- throw new Error('The public key does not match with cached key!');
163
- }
163
+ // TODO why?
164
+ // if (
165
+ // uploadData.type === 'authed' &&
166
+ // (typeof uaIdentity === 'undefined' ||
167
+ // typeof uaIdentity === 'string' ||
168
+ // uploadData.keyPair.pub !== keyPair.publicKey)
169
+ // ) {
170
+ // throw new Error('The public key does not match with cached key!')
171
+ // }
164
172
  await uploadProgress?.({
165
173
  total: encryptedData.byteLength,
166
174
  current: encryptedData.byteLength,
@@ -171,7 +179,9 @@ export async function uploadData({ storageType, data, password, forcePassword =
171
179
  id: uploadData.id,
172
180
  storageType: storageType,
173
181
  size: uploadDataArgs.size,
174
- sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
182
+ sizeEncrypted: uploadDataArgs.type === 'encrypted'
183
+ ? uploadDataArgs.sizeEncrypted
184
+ : null,
175
185
  data: dataBuffer,
176
186
  ...filetype,
177
187
  };
@@ -231,7 +241,9 @@ export async function uploadData({ storageType, data, password, forcePassword =
231
241
  id: uploadData.id,
232
242
  storageType: storageType,
233
243
  size: uploadDataArgs.size,
234
- sizeEncrypted: uploadDataArgs.sizeEncrypted ?? null,
244
+ sizeEncrypted: uploadDataArgs.type === 'encrypted'
245
+ ? uploadDataArgs.sizeEncrypted
246
+ : null,
235
247
  data: dataBuffer,
236
248
  ...filetype,
237
249
  };
@@ -10,10 +10,10 @@ import { concatenate } from '../utils/array.js';
10
10
  * If a string is provided as keypair, it should be considered as guest with password case.
11
11
  * If keypair is not provided, then we generate a key to be used as password for guest too.
12
12
  */
13
- export async function encryptDataAndKey({ data, keyPair, progress, signal, }) {
13
+ export async function encryptDataAndKey({ data, uaIdentity, keyPairs, progress, signal, }) {
14
14
  const dataKey = secretStreamKeygen();
15
15
  const { data: encryptedData, md5: md5Data, md5Encrypted, } = await encrypt(dataKey, data, progress, signal);
16
- if (!keyPair) {
16
+ if (!uaIdentity || !keyPairs) {
17
17
  return {
18
18
  encryptedData,
19
19
  dataKey,
@@ -21,7 +21,11 @@ export async function encryptDataAndKey({ data, keyPair, progress, signal, }) {
21
21
  md5Encrypted,
22
22
  };
23
23
  }
24
- const encDataKey = encryptCryptoBox(dataKey, keyPair.publicKey, keyPair.privateKey);
24
+ const priv = keyPairs[uaIdentity.identityPubKey];
25
+ if (!priv) {
26
+ throw new Error('No private key found for user app identity');
27
+ }
28
+ const encDataKey = encryptCryptoBox(dataKey, uaIdentity.identityPubKey, priv);
25
29
  return {
26
30
  encryptedDataKey: encDataKey,
27
31
  encryptedData,
package/dist/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './client/index.js';
2
2
  export * from './crypto/index.js';
3
3
  export { BaseClient } from './base-client.js';
4
+ export * from './client/types/identity.js';
4
5
  export * from './client/helpers.js';
5
6
  export * from './sodium.js';
6
7
  export * from './utils/store-buddy.js';
@@ -8,3 +9,4 @@ export * from './error/index.js';
8
9
  export * from './client/download.js';
9
10
  export * from './client/upload.js';
10
11
  export { generatePassword } from './crypto/helpers.js';
12
+ export * from './client/data-link.js';
@@ -24,6 +24,8 @@ export declare class BaseClient {
24
24
  me(): Promise<SelfUser>;
25
25
  static getUser(userId: string, opts?: CreateTrpcClientOptions): Promise<PublicUser>;
26
26
  getUser(userId: string): Promise<PublicUser>;
27
+ static getUsers(userIds: string[], opts?: CreateTrpcClientOptions): Promise<PublicUser[]>;
28
+ getUsers(userIds: string[]): Promise<PublicUser[]>;
27
29
  searchUsers(search: string): Promise<PublicUser[]>;
28
30
  updateProfile(data: RouterInputs['user']['updateProfile']): Promise<RouterOutputs['user']['updateProfile']>;
29
31
  static isCryptoTransactionDone({ idOrHash, network, opts, }: {
@@ -1,12 +1,11 @@
1
1
  import type { SecrecyClient, UserAppNotifications, UserAppSettings } from '../index.js';
2
2
  import type { JwtPayload } from 'jsonwebtoken';
3
- import { type RouterOutputs, type ApiClient, type RouterInputs } from '../client.js';
4
- import { type KeyPair } from './types/index.js';
3
+ import { type RouterOutputs, type RouterInputs } from '../client.js';
5
4
  export declare class SecrecyAppClient {
6
5
  #private;
7
6
  jwt: string;
8
7
  jwtDecoded: JwtPayload;
9
- constructor(uaJwt: string, _client: SecrecyClient, _keys: KeyPair, apiClient: ApiClient);
8
+ constructor(uaJwt: string, client: SecrecyClient);
10
9
  get userId(): string;
11
10
  get appId(): string;
12
11
  getJwt(): Promise<string>;
@@ -1,11 +1,11 @@
1
1
  import type { ProgressCallback, SecrecyClient, UploadDataOptions } from '../index.js';
2
- import type { DataMetadata, DataStorageType, KeyPair, LocalData, Node, NodeFull, NodeType } from './types/index.js';
3
- import { type RouterInputs, type ApiClient, type RouterOutputs } from '../client.js';
2
+ import type { DataMetadata, DataStorageType, LocalData, Node, NodeFull, NodeType } from './types/index.js';
4
3
  import { type Progress } from '../types.js';
4
+ import { type RouterInputs, type RouterOutputs } from '../client.js';
5
5
  import { DownloadDataFromLinkOptions } from './data-link.js';
6
6
  export declare class SecrecyCloudClient {
7
7
  #private;
8
- constructor(client: SecrecyClient, keys: KeyPair, apiClient: ApiClient);
8
+ constructor(client: SecrecyClient);
9
9
  addDataToHistory({ dataId, nodeId, }: {
10
10
  dataId: string;
11
11
  nodeId: string;
@@ -28,9 +28,9 @@ export declare class SecrecyCloudClient {
28
28
  deletedNodes(): Promise<Node[]>;
29
29
  sharedNodes(): Promise<Node[]>;
30
30
  nodesSharedWithMe(type?: NodeType): Promise<Node[]>;
31
- deleteNodeSharing({ nodeId, userId, }: {
31
+ deleteNodeSharing({ nodeId, destPubKey, }: {
32
32
  nodeId: string;
33
- userId: string;
33
+ destPubKey: string;
34
34
  }): Promise<boolean>;
35
35
  duplicateNode({ nodeId, folderId, name, }: {
36
36
  nodeId: string;
@@ -51,7 +51,7 @@ export declare class SecrecyCloudClient {
51
51
  dataMetadata({ id }: {
52
52
  id: string;
53
53
  }): Promise<DataMetadata>;
54
- shareNode(input: RouterInputs['cloud']['shareNode'], progress?: ProgressCallback): Promise<RouterOutputs['cloud']['shareNodeFinish']>;
54
+ shareNode(accesses: RouterInputs['cloud']['shareNode']['accesses'], progress?: ProgressCallback): Promise<RouterOutputs['cloud']['shareNodeFinish']>;
55
55
  updateNode({ nodeId, name, isFavorite, deletedAt, }: {
56
56
  nodeId: string;
57
57
  name?: string | null | undefined;
@@ -93,7 +93,7 @@ export declare class SecrecyCloudClient {
93
93
  name: string;
94
94
  nodeId?: string;
95
95
  }): Promise<NodeFull>;
96
- private readonly encryptNodesForUsers;
96
+ private readonly encryptNodesForIdentities;
97
97
  reportData({ id, reasons, }: Omit<RouterInputs['cloud']['reportData'], 'encryptedDataKey'>): Promise<RouterOutputs['cloud']['reportData']>;
98
98
  updateDataStorageType(input: RouterInputs['cloud']['moveToStorageType']): Promise<{
99
99
  isMoved: boolean;
@@ -126,32 +126,32 @@ export declare class SecrecyCloudClient {
126
126
  isMatching: false;
127
127
  details: {
128
128
  missingNodeAccesses: {
129
- userId: string;
129
+ pubKey: string;
130
130
  nodeId: string;
131
131
  }[];
132
132
  missingDataAccesses: {
133
- userId: string;
133
+ pubKey: string;
134
134
  nodeId: string;
135
135
  dataId: string;
136
136
  }[];
137
137
  invalidRightsAccesses: {
138
- userId: string;
138
+ pubKey: string;
139
139
  nodeId: string;
140
140
  expect: {
141
141
  rights: "delete" | "read" | "write";
142
142
  } & {
143
- addAccess?: "delete" | "read" | "write" | null | undefined;
144
- sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
145
- delAccess?: "delete" | "read" | "write" | null | undefined;
146
- sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
143
+ addAccess: "delete" | "read" | "write" | null;
144
+ sharingAddAccess: "delete" | "read" | "write" | null;
145
+ delAccess: "delete" | "read" | "write" | null;
146
+ sharingDelAccess: "delete" | "read" | "write" | null;
147
147
  };
148
148
  current: {
149
149
  rights: "delete" | "read" | "write";
150
150
  } & {
151
- addAccess?: "delete" | "read" | "write" | null | undefined;
152
- sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
153
- delAccess?: "delete" | "read" | "write" | null | undefined;
154
- sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
151
+ addAccess: "delete" | "read" | "write" | null;
152
+ sharingAddAccess: "delete" | "read" | "write" | null;
153
+ delAccess: "delete" | "read" | "write" | null;
154
+ sharingDelAccess: "delete" | "read" | "write" | null;
155
155
  };
156
156
  }[];
157
157
  };
@@ -1,7 +1,5 @@
1
- import { type ApiClient } from '../client.js';
2
1
  import type { SecrecyClient } from '../index.js';
3
- import { type KeyPair } from './types/index.js';
4
2
  export declare class SecrecyDbClient {
5
3
  #private;
6
- constructor(_client: SecrecyClient, _keys: KeyPair, apiClient: ApiClient);
4
+ constructor(client: SecrecyClient);
7
5
  }
@@ -1,10 +1,9 @@
1
- import { type ApiClient, type RouterInputs } from '../client.js';
1
+ import { type RouterInputs } from '../client.js';
2
2
  import type { DraftMail, Mail, NewMail, ReceivedMail, SecrecyClient, SentMail, WaitingReceivedMail } from '../index.js';
3
- import { type KeyPair } from './types/index.js';
4
3
  import { type ApiMail } from './types/mail.js';
5
4
  export declare class SecrecyMailClient {
6
5
  #private;
7
- constructor(client: SecrecyClient, keys: KeyPair, apiClient: ApiClient);
6
+ constructor(client: SecrecyClient);
8
7
  get({ id }: {
9
8
  id: string;
10
9
  }): Promise<Mail>;
@@ -1,9 +1,8 @@
1
- import { RouterInputs, RouterOutputs, type ApiClient } from '../client.js';
1
+ import { RouterInputs, RouterOutputs } from '../client.js';
2
2
  import type { SecrecyClient } from '../index.js';
3
- import { type KeyPair } from './types/index.js';
4
3
  export declare class SecrecyOrganizationClient {
5
4
  #private;
6
- constructor(_client: SecrecyClient, _keys: KeyPair, apiClient: ApiClient);
5
+ constructor(client: SecrecyClient);
7
6
  create(input: RouterInputs['org']['create']): Promise<RouterOutputs['org']['create']>;
8
7
  update(input: Omit<RouterInputs['org']['update'], 'billingProfileStripeCustomerId'>): Promise<RouterOutputs['org']['update']>;
9
8
  addMember(input: RouterInputs['org']['addMember']): Promise<RouterOutputs['org']['addMember']>;
@@ -1,6 +1,4 @@
1
1
  import type { SecrecyClient } from '../index.js';
2
- import { type ApiClient } from '../client.js';
3
- import { type KeyPair } from './types/index.js';
4
2
  interface SuccessPayResponse<T> {
5
3
  success: true;
6
4
  data: T;
@@ -12,7 +10,7 @@ interface ErrorPayResponse {
12
10
  export type SecrecyPayResponse<T> = SuccessPayResponse<T> | ErrorPayResponse;
13
11
  export declare class SecrecyPayClient {
14
12
  #private;
15
- constructor(client: SecrecyClient, _keys: KeyPair, _apiClient: ApiClient);
13
+ constructor(client: SecrecyClient);
16
14
  confirmPaymentIntent({ paymentIntentId, secrecyIdWhoCreatedPaymentIntent, secrecyIdWhoNeedToConfirmPaymentIntent, amount, currency, }: {
17
15
  paymentIntentId: string;
18
16
  secrecyIdWhoCreatedPaymentIntent: string;
@@ -1,9 +1,8 @@
1
- import { type RouterInputs, type RouterOutputs, type ApiClient } from '../client.js';
1
+ import { type RouterInputs, type RouterOutputs } from '../client.js';
2
2
  import type { SecrecyClient } from '../index.js';
3
- import { type KeyPair } from './types/index.js';
4
3
  export declare class SecrecyPseudonymClient {
5
4
  #private;
6
- constructor(client: SecrecyClient, keys: KeyPair, apiClient: ApiClient);
5
+ constructor(client: SecrecyClient);
7
6
  askForLabel(input: RouterInputs['pseudonym']['askForLabel']): Promise<RouterOutputs['pseudonym']['askForLabel']>;
8
7
  askForUser(input: RouterInputs['pseudonym']['askForUser']): Promise<RouterOutputs['pseudonym']['askForUser']>;
9
8
  cross(input: RouterInputs['pseudonym']['cross']): Promise<RouterOutputs['pseudonym']['cross']>;
@@ -1,9 +1,8 @@
1
- import type { RouterInputs, ApiClient, RouterOutputs } from '../client.js';
1
+ import type { RouterInputs, RouterOutputs } from '../client.js';
2
2
  import type { SecrecyClient } from '../index.js';
3
- import type { KeyPair } from './types/index.js';
4
3
  export declare class SecrecyUserClient {
5
4
  #private;
6
- constructor(_client: SecrecyClient, _keys: KeyPair, apiClient: ApiClient);
5
+ constructor(client: SecrecyClient);
7
6
  answerInvitation(input: RouterInputs['contacts']['answerInvitation']): Promise<RouterOutputs['contacts']['answerInvitation']>;
8
7
  cancelInvitation(input: RouterInputs['contacts']['cancelInvitation']): Promise<RouterOutputs['contacts']['cancelInvitation']>;
9
8
  createInvitation(input: RouterInputs['contacts']['createInvitation']): Promise<RouterOutputs['contacts']['createInvitation']>;
@@ -1,4 +1,4 @@
1
- import type { ApiData, InternalData, DataMetadata, KeyPair } from '../types/index.js';
2
- export declare function apiDataToInternal(apiData: ApiData, keyPair: KeyPair): InternalData;
1
+ import type { ApiData, InternalData, DataMetadata } from '../types/index.js';
2
+ export declare function apiDataToInternal(apiData: ApiData, keyPairs: Record<string, string>): InternalData;
3
3
  export declare function internalDataToExternalData(internal: InternalData): DataMetadata;
4
- export declare function apiDataToExternal(apiData: ApiData, keyPair: KeyPair): DataMetadata;
4
+ export declare function apiDataToExternal(apiData: ApiData, keyPairs: Record<string, string>): DataMetadata;
@@ -1,8 +1,6 @@
1
- import { type Mail, type SecrecyClient } from '../../index.js';
2
- import { type KeyPair } from '../types/index.js';
1
+ import { type Mail } from '../../index.js';
3
2
  import { type ApiMail } from '../types/mail.js';
4
- export declare function convertInternalMailToExternal({ client, mail, keyPair, }: {
3
+ export declare function convertInternalMailToExternal({ mail, keyPairs, }: {
5
4
  mail: ApiMail;
6
- client: SecrecyClient;
7
- keyPair: KeyPair;
5
+ keyPairs: Record<string, string>;
8
6
  }): Promise<Mail>;
@@ -1,6 +1,6 @@
1
- import type { Node, ApiNode, ApiNodeFull, InternalNodeFull, NodeFull, KeyPair, ApiNodeParent, ApiNodeForEncryption, InternalMinimalNodeForEncryption } from '../types/index.js';
2
- export declare function apiNodeFullToInternalFull(apiNodeFull: ApiNodeFull, keyPair: KeyPair): Promise<InternalNodeFull>;
1
+ import type { Node, ApiNode, ApiNodeFull, InternalNodeFull, NodeFull, ApiNodeParent, ApiNodeForEncryption, InternalMinimalNodeForEncryption } from '../types/index.js';
2
+ export declare function apiNodeFullToInternalFull(apiNodeFull: ApiNodeFull, keyPairs: Record<string, string>): Promise<InternalNodeFull>;
3
3
  export declare function internalNodeFullToNodeFull(internal: InternalNodeFull): NodeFull;
4
- export declare function apiNodeToExternalNodeFull(apiNodeFull: ApiNodeFull, keyPair: KeyPair): Promise<NodeFull>;
5
- export declare function apiNodeToExternal(apiNode: ApiNode | ApiNodeParent, keyPair: KeyPair): Promise<Node>;
6
- export declare function apiNodeForEncryptionToInternal(apiNode: ApiNodeForEncryption, keyPair: KeyPair): Promise<InternalMinimalNodeForEncryption>;
4
+ export declare function apiNodeToExternalNodeFull(apiNodeFull: ApiNodeFull, keyPairs: Record<string, string>): Promise<NodeFull>;
5
+ export declare function apiNodeToExternal(apiNode: ApiNode | ApiNodeParent, keyPairs: Record<string, string>): Promise<Node>;
6
+ export declare function apiNodeForEncryptionToInternal(apiNode: ApiNodeForEncryption, keyPairs: Record<string, string>): Promise<InternalMinimalNodeForEncryption>;
@@ -6,16 +6,17 @@ import { SecrecyAppClient } from './SecrecyAppClient.js';
6
6
  import { SecrecyDbClient } from './SecrecyDbClient.js';
7
7
  import { SecrecyWalletClient } from './SecrecyWalletClient.js';
8
8
  import { SecrecyPayClient } from './SecrecyPayClient.js';
9
- import { ApiClient, type RouterInputs } from '../client.js';
10
- import { type KeyPair } from './types/index.js';
9
+ import { ApiClient, type RouterInputs, type RouterOutputs } from '../client.js';
11
10
  import { SecrecyUserClient } from './SecrecyUserClient.js';
12
11
  import { SecrecyPseudonymClient } from './SecrecyPseudonymClient.js';
13
12
  import { SecrecyOrganizationClient } from './SecrecyOrganizationClient.js';
13
+ import type { AccessIdentity, GroupIdentity, UserAppIdentity } from './types/identity.js';
14
14
  export type NewMail = Pick<RouterInputs['mail']['createDraft'], 'body' | 'subject' | 'senderFiles' | 'recipients' | 'replyToId'>;
15
15
  export type ProgressCallback = (progress: SecretStreamProgress) => Promise<void>;
16
16
  export interface SecrecyClientOptions {
17
17
  uaSession: string;
18
- uaKeys: KeyPair;
18
+ identities: AccessIdentity[];
19
+ keyPairs: Record<string, string>;
19
20
  uaJwt: string;
20
21
  apiClient?: ApiClient;
21
22
  secrecyUrls?: Partial<SecrecyUrls>;
@@ -33,6 +34,13 @@ export declare class SecrecyClient extends BaseClient {
33
34
  pseudonym: SecrecyPseudonymClient;
34
35
  constructor(opts: SecrecyClientOptions);
35
36
  get publicKey(): string;
37
+ get apiClient(): Readonly<ApiClient>;
38
+ get keyPairs(): Readonly<Record<string, string>>;
39
+ getPrivateKey(pubKey: string): string;
40
+ get uaPrivateKey(): string;
41
+ get groupIdentities(): ReadonlyArray<Readonly<GroupIdentity>>;
42
+ get uaIdentity(): Readonly<UserAppIdentity>;
36
43
  decryptAnonymous(data: Uint8Array): Uint8Array;
37
44
  logout(sessionId?: string | null | undefined): Promise<void>;
45
+ getIdentities(input: RouterInputs['identity']['getMany']): Promise<RouterOutputs['identity']['getMany']>;
38
46
  }
@@ -1,7 +1,8 @@
1
1
  import type { StoreBuddy } from '../utils/store-buddy.js';
2
- import { type KeyPair } from './types/index.js';
2
+ import type { AccessIdentity } from './types/identity.js';
3
3
  export declare function getStorage(session?: boolean | undefined): {
4
- userAppKeys: StoreBuddy<KeyPair | null>;
4
+ identities: StoreBuddy<AccessIdentity[] | null>;
5
+ keyPairs: StoreBuddy<Record<string, string> | null>;
5
6
  userAppSession: StoreBuddy<string | null>;
6
7
  jwt: StoreBuddy<string | null>;
7
8
  };
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod/v4';
2
+ export declare const userAppSchema: z.ZodObject<{
3
+ kind: z.ZodLiteral<"USER_APP">;
4
+ identityPubKey: z.ZodString;
5
+ userId: z.ZodString;
6
+ appId: z.ZodString;
7
+ }, z.core.$strip>;
8
+ export declare const groupSchema: z.ZodObject<{
9
+ kind: z.ZodLiteral<"GROUP">;
10
+ identityPubKey: z.ZodString;
11
+ groupId: z.ZodString;
12
+ sharedByPubKey: z.ZodString;
13
+ groupOwnerPubKey: z.ZodString;
14
+ }, z.core.$strip>;
15
+ export declare const accessIdentitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
16
+ kind: z.ZodLiteral<"USER_APP">;
17
+ identityPubKey: z.ZodString;
18
+ userId: z.ZodString;
19
+ appId: z.ZodString;
20
+ }, z.core.$strip>, z.ZodObject<{
21
+ kind: z.ZodLiteral<"GROUP">;
22
+ identityPubKey: z.ZodString;
23
+ groupId: z.ZodString;
24
+ sharedByPubKey: z.ZodString;
25
+ groupOwnerPubKey: z.ZodString;
26
+ }, z.core.$strip>], "kind">;
27
+ export type AccessIdentity = z.infer<typeof accessIdentitySchema>;
28
+ export type UserAppIdentity = z.infer<typeof userAppSchema>;
29
+ export type GroupIdentity = z.infer<typeof groupSchema>;
@@ -4,16 +4,20 @@ export type * from './data.js';
4
4
  export type * from './node.js';
5
5
  export type * from './mail.js';
6
6
  export type * from './user.js';
7
- declare const keyPair: z.ZodObject<{
8
- publicKey: z.ZodString;
9
- privateKey: z.ZodString;
10
- }, z.core.$strict>;
11
- export type KeyPair = z.infer<typeof keyPair>;
12
7
  export declare const secrecyUserApp: z.ZodReadonly<z.ZodObject<{
13
- keys: z.ZodObject<{
14
- publicKey: z.ZodString;
15
- privateKey: z.ZodString;
16
- }, z.core.$strict>;
8
+ identities: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
9
+ kind: z.ZodLiteral<"USER_APP">;
10
+ identityPubKey: z.ZodString;
11
+ userId: z.ZodString;
12
+ appId: z.ZodString;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ kind: z.ZodLiteral<"GROUP">;
15
+ identityPubKey: z.ZodString;
16
+ groupId: z.ZodString;
17
+ sharedByPubKey: z.ZodString;
18
+ groupOwnerPubKey: z.ZodString;
19
+ }, z.core.$strip>], "kind">>;
20
+ keyPairs: z.ZodRecord<z.ZodString, z.ZodString>;
17
21
  jwt: z.ZodString;
18
22
  uaSession: z.ZodString;
19
23
  }, z.core.$strict>>;