@secrecy/lib 1.86.1-feat-improve-sdk.2 → 1.86.2-fix-metrics.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.
@@ -1,4 +1,4 @@
1
- import { usersCache, clearAllCaches } from './cache.js';
1
+ import { usersCache } from './cache.js';
2
2
  import { getStorage } from './client/storage.js';
3
3
  import { createTRPCClient, } from './client.js';
4
4
  import { getPreferedEmail } from './utils.js';
@@ -46,16 +46,15 @@ export class BaseClient {
46
46
  BaseClient.getBaseClient({
47
47
  session: opts.session,
48
48
  apiUrl: this.secrecyUrls.api,
49
- timeoutMs: opts.timeoutMs,
50
49
  onAccessDenied: async () => {
50
+ console.log('[BASE_CLIENT - BEFORE] - Access denied');
51
51
  await opts.onAccessDenied?.();
52
+ console.log('[BASE_CLIENT - AFTER] - Access denied');
52
53
  try {
53
54
  await this.logout();
54
55
  }
55
56
  finally {
56
- if (opts.reloadOnAccessDenied ?? true) {
57
- location.reload();
58
- }
57
+ location.reload();
59
58
  }
60
59
  },
61
60
  });
@@ -142,6 +141,6 @@ export class BaseClient {
142
141
  session.identities.clear();
143
142
  session.keyPairs.clear();
144
143
  session.userAppSession.clear();
145
- clearAllCaches();
144
+ usersCache.clear();
146
145
  };
147
146
  }
package/dist/lib/cache.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { LRUCache } from 'lru-cache';
2
2
  import { gigaToBytes } from './utils.js';
3
- const boundedCacheOpts = { max: 5_000, ttl: 5 * 60 * 1000 };
4
- export const dataCache = new LRUCache(boundedCacheOpts);
5
- export const nodesCache = new LRUCache(boundedCacheOpts);
6
- export const nodesEncryptionCache = new LRUCache(boundedCacheOpts);
3
+ export const dataCache = new Map();
4
+ export const nodesCache = new Map();
5
+ export const nodesEncryptionCache = new Map();
7
6
  export const getNodeForEncryptionFromCache = (id) => {
8
7
  if (nodesEncryptionCache.has(id)) {
9
8
  return nodesEncryptionCache.get(id);
@@ -13,8 +12,8 @@ export const getNodeForEncryptionFromCache = (id) => {
13
12
  }
14
13
  return undefined;
15
14
  };
16
- export const usersCache = new LRUCache(boundedCacheOpts);
17
- export const publicKeysCache = new LRUCache({ max: 10_000 });
15
+ export const usersCache = new Map();
16
+ export const publicKeysCache = new Map();
18
17
  export const dataContentCache = new LRUCache({
19
18
  max: 500,
20
19
  maxSize: gigaToBytes(0.5),
@@ -22,11 +21,3 @@ export const dataContentCache = new LRUCache({
22
21
  return value.data.byteLength;
23
22
  },
24
23
  });
25
- export function clearAllCaches() {
26
- dataCache.clear();
27
- nodesCache.clear();
28
- nodesEncryptionCache.clear();
29
- usersCache.clear();
30
- publicKeysCache.clear();
31
- dataContentCache.clear();
32
- }
@@ -18,15 +18,18 @@ export class SecrecyCloudClient {
18
18
  this.#client = client;
19
19
  }
20
20
  async addDataToHistory({ dataId, nodeId, }) {
21
- const currentNode = await apiNodeFullToInternalFull(await this.#client.apiClient.cloud.nodeFullById.query({ id: nodeId }), this.#client.keyPairs);
22
- const currentData = currentNode.history.find((d) => d.id === dataId);
23
- if (currentData === undefined) {
24
- throw new Error(`Data ${dataId} is not in node ${nodeId}`);
25
- }
21
+ const [rawData, currentNode] = await Promise.all([
22
+ this.#client.apiClient.cloud.dataById.query({
23
+ id: dataId,
24
+ fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
25
+ }),
26
+ this.node({ id: nodeId }),
27
+ ]);
28
+ const data = apiDataToInternal(rawData, this.#client.keyPairs);
26
29
  const encryptedAccesses = Object.keys(currentNode.identities).map((pubKey) => ({
27
30
  pubKey,
28
- key: currentData.key
29
- ? sodium.to_hex(encryptCryptoBox(sodium.from_hex(currentData.key), pubKey, this.#client.currentIdentityPrivateKey))
31
+ key: data.key
32
+ ? sodium.to_hex(encryptCryptoBox(sodium.from_hex(data.key), pubKey, this.#client.currentIdentityPrivateKey))
30
33
  : null,
31
34
  }));
32
35
  const addDataToHistory = await this.#client.apiClient.cloud.addDataToHistory.mutate({
@@ -0,0 +1,3 @@
1
+ export class SecrecyDbClient {
2
+ constructor(_client) { }
3
+ }
@@ -31,13 +31,8 @@ export class SecrecyMailClient {
31
31
  })));
32
32
  }
33
33
  async create(data, customMessage) {
34
- const { customMessage: embeddedCustomMessage, ...mailData } = data;
35
- const resolvedCustomMessage = customMessage ?? embeddedCustomMessage;
36
- const mail = await this.createDraft(mailData);
37
- const isSent = await this.sendDraft({
38
- draftId: mail.mailIntegrityId,
39
- customMessage: resolvedCustomMessage,
40
- });
34
+ const mail = await this.createDraft(data);
35
+ const isSent = await this.sendDraft(mail.mailIntegrityId, customMessage);
41
36
  if (!isSent) {
42
37
  throw new Error('The mail does not sent!');
43
38
  }
@@ -58,8 +53,7 @@ export class SecrecyMailClient {
58
53
  }));
59
54
  return waitingReceivedMailsWithIds;
60
55
  }
61
- async updateDraft(arg, args) {
62
- const { draftId, body, subject, senderFiles, recipients, replyToId, } = typeof arg === 'string' ? { draftId: arg, ...args } : arg;
56
+ async updateDraft(draftId, { body, subject, senderFiles, recipients, replyToId }) {
63
57
  const drafts = await this.draftMails({});
64
58
  const draft = drafts.find((d) => d.mailIntegrityId === draftId);
65
59
  if (draft === undefined) {
@@ -130,8 +124,7 @@ export class SecrecyMailClient {
130
124
  });
131
125
  return isDeleted;
132
126
  }
133
- async sendDraft(arg, customMessage) {
134
- const { draftId, customMessage: resolvedCustomMessage } = typeof arg === 'string' ? { draftId: arg, customMessage } : arg;
127
+ async sendDraft(draftId, customMessage) {
135
128
  const drafts = await this.draftMails({});
136
129
  const draft = drafts.find((d) => d.mailIntegrityId === draftId);
137
130
  if (draft === undefined) {
@@ -164,7 +157,7 @@ export class SecrecyMailClient {
164
157
  temporaryRecipients,
165
158
  recipients,
166
159
  id: draft.mailIntegrityId,
167
- customMessage: resolvedCustomMessage ?? null,
160
+ customMessage: customMessage ?? null,
168
161
  });
169
162
  return isSent;
170
163
  }
@@ -2,26 +2,14 @@ import { SecrecyClient } from './index.js';
2
2
  import { popup } from '../utils/popup-tools.js';
3
3
  import { secrecyUserApp } from './types/index.js';
4
4
  import { getStorage } from './storage.js';
5
- import { setup } from '../sodium.js';
6
- export function assertBrowser(fn) {
7
- if (typeof window === 'undefined') {
8
- const err = {
9
- name: 'ClientError',
10
- code: 'SERVER_ENVIRONMENT',
11
- message: `${fn}() can only run in a browser. On Next.js, call it from a "use client" component, or via dynamic(..., { ssr: false }).`,
12
- };
13
- throw err;
14
- }
15
- }
16
5
  export function parseInfos() {
17
- assertBrowser('parseInfos');
18
6
  if (window.location.hash === '') {
19
7
  return null;
20
8
  }
21
- const hash = window.location.hash.slice(1);
9
+ const hash = window.location.hash.substr(1);
22
10
  try {
23
11
  const res = JSON.parse(atob(hash));
24
- history.replaceState(null, '', window.location.pathname + window.location.search);
12
+ window.location.hash = '';
25
13
  const data = secrecyUserApp.safeParse(res);
26
14
  return data.success ? data.data : null;
27
15
  }
@@ -30,7 +18,6 @@ export function parseInfos() {
30
18
  }
31
19
  }
32
20
  export function getSecrecyClient(opts = {}) {
33
- assertBrowser('getSecrecyClient');
34
21
  const storage = getStorage(opts.session);
35
22
  const infos = parseInfos();
36
23
  if (infos !== null) {
@@ -62,7 +49,6 @@ export function getSecrecyClient(opts = {}) {
62
49
  return null;
63
50
  }
64
51
  export async function login({ appId, context, path, redirect, scopes, backPath, session, secrecyUrls, forceLogin, }) {
65
- assertBrowser('login');
66
52
  return await new Promise(async (resolve, reject) => {
67
53
  const appUrl = window.location.origin;
68
54
  const client = getSecrecyClient({ session, secrecyUrls });
@@ -143,21 +129,3 @@ export async function login({ appId, context, path, redirect, scopes, backPath,
143
129
  }
144
130
  });
145
131
  }
146
- /**
147
- * Single async entry point: runs `setup()`, reuses an existing session if
148
- * one is found, and falls back to `login()` otherwise. Equivalent to
149
- * `await setup()` + `getSecrecyClient()` + `login()`, without having to
150
- * juggle the sync/async mismatch between them.
151
- */
152
- export async function initSecrecy(opts) {
153
- assertBrowser('initSecrecy');
154
- await setup();
155
- const existing = getSecrecyClient({
156
- session: opts.session,
157
- secrecyUrls: opts.secrecyUrls,
158
- });
159
- if (existing !== null) {
160
- return existing;
161
- }
162
- return await login(opts);
163
- }
@@ -2,7 +2,8 @@ import { BaseClient } from '../base-client.js';
2
2
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
3
3
  import { SecrecyMailClient } from './SecrecyMailClient.js';
4
4
  import { SecrecyAppClient } from './SecrecyAppClient.js';
5
- import { clearAllCaches } from '../cache.js';
5
+ import { nodesCache, dataCache, publicKeysCache } from '../cache.js';
6
+ import { SecrecyDbClient } from './SecrecyDbClient.js';
6
7
  import { SecrecyWalletClient } from './SecrecyWalletClient.js';
7
8
  import { SecrecyPayClient } from './SecrecyPayClient.js';
8
9
  import { SecrecyUserClient } from './SecrecyUserClient.js';
@@ -19,10 +20,9 @@ export class SecrecyClient extends BaseClient {
19
20
  cloud;
20
21
  mail;
21
22
  app;
23
+ db;
22
24
  organization;
23
- /** @experimental Susceptible de changer sans version majeure. */
24
25
  wallet;
25
- /** @experimental Susceptible de changer sans version majeure. */
26
26
  pay;
27
27
  user;
28
28
  pseudonym;
@@ -33,9 +33,8 @@ export class SecrecyClient extends BaseClient {
33
33
  session: opts.uaSession,
34
34
  secrecyUrls: opts.secrecyUrls,
35
35
  apiClient: opts.apiClient,
36
- timeoutMs: opts.timeoutMs,
37
- reloadOnAccessDenied: opts.reloadOnAccessDenied,
38
36
  onAccessDenied: async () => {
37
+ console.log('[CLIENT] - Access denied');
39
38
  try {
40
39
  await this.logout();
41
40
  }
@@ -54,6 +53,7 @@ export class SecrecyClient extends BaseClient {
54
53
  this.cloud = new SecrecyCloudClient(this);
55
54
  this.mail = new SecrecyMailClient(this);
56
55
  this.app = new SecrecyAppClient(opts.uaJwt, this);
56
+ this.db = new SecrecyDbClient(this);
57
57
  this.organization = new SecrecyOrganizationClient(this);
58
58
  this.wallet = new SecrecyWalletClient(this);
59
59
  this.pay = new SecrecyPayClient(this);
@@ -104,7 +104,9 @@ export class SecrecyClient extends BaseClient {
104
104
  });
105
105
  }
106
106
  async logout(sessionId) {
107
- clearAllCaches();
107
+ nodesCache.clear();
108
+ dataCache.clear();
109
+ publicKeysCache.clear();
108
110
  await super.logout(sessionId);
109
111
  }
110
112
  }
@@ -24,22 +24,26 @@ export const createTRPCClient = (opts) => innerCreateTRPCClient({
24
24
  : 'https://api.secrecy.tech/trpc',
25
25
  maxURLLength: 2083,
26
26
  fetch: async (input, init) => {
27
- const timeout = AbortSignal.timeout(opts.timeoutMs ?? 20_000);
28
- const signal = init?.signal
29
- ? AbortSignal.any([init.signal, timeout])
30
- : timeout;
27
+ const controller = new AbortController();
28
+ const id = setTimeout(() => {
29
+ controller.abort();
30
+ }, 20000);
31
31
  const headers = new Headers(init?.headers);
32
32
  headers.set('secrecy-lib-version', SECRECY_LIB_VERSION);
33
33
  if (typeof opts.session === 'string') {
34
34
  headers.set('secrecy-session', opts.session);
35
35
  }
36
- return await fetch(input, {
36
+ const call = fetch(input, {
37
37
  ...init,
38
38
  headers,
39
- signal,
39
+ signal: controller.signal,
40
40
  mode: 'cors',
41
41
  credentials: opts.session ? 'include' : 'omit',
42
42
  });
43
+ void call.finally(() => {
44
+ clearTimeout(id);
45
+ });
46
+ return await call;
43
47
  },
44
48
  }),
45
49
  ],
@@ -1,12 +1,5 @@
1
1
  import { concatenate } from '../utils/array.js';
2
2
  import { sodium } from '../sodium.js';
3
- function dataTooShortError() {
4
- return {
5
- name: 'ClientError',
6
- code: 'DATA_TOO_SHORT',
7
- message: 'Encrypted payload is shorter than nonce + MAC',
8
- };
9
- }
10
3
  export function encryptCryptoBox(data, publicKeyBob, privateKeyAlice) {
11
4
  const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
12
5
  const crypt = sodium.crypto_box_easy(data, nonce, sodium.from_hex(publicKeyBob), sodium.from_hex(privateKeyAlice));
@@ -17,7 +10,7 @@ export function generateCryptoBoxKeyPair() {
17
10
  }
18
11
  export function decryptCryptoBox(data, publicKeyAlice, privateKeyBob) {
19
12
  if (data.length < sodium.crypto_box_NONCEBYTES + sodium.crypto_box_MACBYTES) {
20
- throw dataTooShortError();
13
+ throw 'data too short';
21
14
  }
22
15
  const nonce = data.slice(0, sodium.crypto_box_NONCEBYTES);
23
16
  const cipher = data.slice(sodium.crypto_box_NONCEBYTES);
@@ -34,7 +27,7 @@ export function encryptSecretBox(data, key) {
34
27
  export function decryptSecretBox(data, key) {
35
28
  if (data.length <
36
29
  sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES) {
37
- throw dataTooShortError();
30
+ throw 'data too short';
38
31
  }
39
32
  const nonce = data.slice(0, sodium.crypto_secretbox_NONCEBYTES);
40
33
  const cipher = data.slice(sodium.crypto_secretbox_NONCEBYTES);
@@ -1,11 +1,5 @@
1
1
  import { z } from 'zod';
2
- export const clientErrorCodeKey = z.enum([
3
- 'NOT_FOUND',
4
- 'DATA_TOO_SHORT',
5
- 'POPUP_BLOCKED',
6
- 'POPUP_CLOSED',
7
- 'SERVER_ENVIRONMENT',
8
- ]);
2
+ export const clientErrorCodeKey = z.enum(['NOT_FOUND']);
9
3
  export const clientError = z.object({
10
4
  name: z.literal('ClientError'),
11
5
  code: clientErrorCodeKey,
@@ -10,6 +10,7 @@ const defaultOptions = {
10
10
  scrollbars: 'no',
11
11
  centered: true,
12
12
  };
13
+ let popupCount = 1;
13
14
  /**
14
15
  * Return options converted to a string
15
16
  *
@@ -22,11 +23,12 @@ function optionsToString(options) {
22
23
  .join(',');
23
24
  }
24
25
  /**
25
- * Get an unpredictable, unique name on each call
26
+ * Get a unique name on each call
26
27
  * @return {String}
27
28
  */
28
29
  function defaultPopupName() {
29
- return `secrecy-${crypto.randomUUID()}`;
30
+ popupCount += 1;
31
+ return `Popup ${popupCount}`;
30
32
  }
31
33
  /**
32
34
  * Convert "centered: true" key into concrete left and top arguments
@@ -99,7 +101,6 @@ function popupExecute(execute, url, name, options, callback) {
99
101
  };
100
102
  const optionsString = optionsToString(popupOptions);
101
103
  const win = execute(url, popupName, optionsString);
102
- const expectedOrigin = new URL(url, window.location.href).origin;
103
104
  let isMessageSent = false;
104
105
  let interval;
105
106
  function popupCallbackOnce(err, data) {
@@ -109,11 +110,7 @@ function popupExecute(execute, url, name, options, callback) {
109
110
  }
110
111
  }
111
112
  function onMessage(message) {
112
- if (message === undefined || message.origin !== expectedOrigin) {
113
- console.error('Invalid message origin', message?.origin, expectedOrigin);
114
- return;
115
- }
116
- const data = message.data;
113
+ const data = message !== undefined ? message.data : undefined;
117
114
  if (data !== undefined && data.id === popupName) {
118
115
  popupCallbackOnce(undefined, data.data);
119
116
  window.removeEventListener('message', onMessage);
@@ -126,21 +123,13 @@ function popupExecute(execute, url, name, options, callback) {
126
123
  if (win === null || win.closed) {
127
124
  setTimeout(function delayWindowClosing() {
128
125
  clearInterval(interval);
129
- popupCallbackOnce({
130
- name: 'ClientError',
131
- code: 'POPUP_CLOSED',
132
- message: 'The popup was closed before completing',
133
- });
126
+ popupCallbackOnce(new Error('Popup closed'));
134
127
  }, 500);
135
128
  }
136
129
  }, 100);
137
130
  }
138
131
  else {
139
- popupCallbackOnce({
140
- name: 'ClientError',
141
- code: 'POPUP_BLOCKED',
142
- message: 'The popup was blocked by the browser',
143
- });
132
+ popupCallbackOnce(new Error('Popup blocked'));
144
133
  }
145
134
  return win;
146
135
  }
@@ -181,8 +170,11 @@ export function popupWithPost(url, postData, name, options, callback) {
181
170
  }
182
171
  /**
183
172
  * Return html that when executed, will trigger the popup to callback with a response
173
+ *
174
+ * @param {Object}
175
+ * @return {String}
184
176
  */
185
- export function popupResponse(id, data, targetOrigin) {
177
+ export function popupResponse(id, data) {
186
178
  const jsonData = JSON.stringify({ id, data });
187
- return `<script>window.opener.postMessage(${jsonData}, ${JSON.stringify(targetOrigin)});setTimeout(function() { window.close(); }, 50);</script>`;
179
+ return `<script>window.opener.postMessage(${jsonData}, "*");setTimeout(function() { window.close(); }, 50);</script>`;
188
180
  }
@@ -12,8 +12,6 @@ export type BaseClientOptions = {
12
12
  apiClient?: ApiClient;
13
13
  onAccessDenied?: () => void | Promise<void>;
14
14
  secrecyUrls?: Partial<SecrecyUrls>;
15
- timeoutMs?: number;
16
- reloadOnAccessDenied?: boolean;
17
15
  };
18
16
  export declare class BaseClient {
19
17
  #private;
@@ -1,18 +1,17 @@
1
1
  import type { InternalNode, InternalData, InternalNodeFull, LocalData, InternalMinimalNodeForEncryption } from './client/types/index.js';
2
2
  import { LRUCache } from 'lru-cache';
3
3
  type NodeForEncryptionCached = InternalNode | InternalNodeFull | InternalMinimalNodeForEncryption;
4
- export declare const dataCache: LRUCache<string, InternalData, unknown>;
5
- export declare const nodesCache: LRUCache<string, InternalNode | InternalNodeFull, unknown>;
6
- export declare const nodesEncryptionCache: LRUCache<string, InternalMinimalNodeForEncryption, unknown>;
4
+ export declare const dataCache: Map<string, InternalData>;
5
+ export declare const nodesCache: Map<string, InternalNode | InternalNodeFull>;
6
+ export declare const nodesEncryptionCache: Map<string, InternalMinimalNodeForEncryption>;
7
7
  export declare const getNodeForEncryptionFromCache: (id: string) => NodeForEncryptionCached | undefined;
8
- export declare const usersCache: LRUCache<string, {
8
+ export declare const usersCache: Map<string, {
9
9
  firstname: string;
10
10
  lastname: string;
11
11
  id: string;
12
12
  avatar: string | null;
13
13
  isSearchable: boolean;
14
- }, unknown>;
15
- export declare const publicKeysCache: LRUCache<string, string, unknown>;
14
+ }>;
15
+ export declare const publicKeysCache: Map<string, string>;
16
16
  export declare const dataContentCache: LRUCache<string, LocalData, unknown>;
17
- export declare function clearAllCaches(): void;
18
17
  export {};
@@ -0,0 +1,4 @@
1
+ import type { SecrecyClient } from '../index.js';
2
+ export declare class SecrecyDbClient {
3
+ constructor(_client: SecrecyClient);
4
+ }
@@ -13,23 +13,9 @@ export declare class SecrecyMailClient {
13
13
  deletedMails({ mailType, }: {
14
14
  mailType: ApiMail['type'];
15
15
  }): Promise<Mail[]>;
16
- create(data: NewMail & {
17
- customMessage?: string | null | undefined;
18
- }): Promise<SentMail>;
19
- /**
20
- * @deprecated Pass a single object instead:
21
- * `create({ ...data, customMessage })`.
22
- */
23
16
  create(data: NewMail, customMessage?: string | null | undefined): Promise<SentMail>;
24
17
  waitingReceivedMails(): Promise<WaitingReceivedMail[]>;
25
- updateDraft(input: {
26
- draftId: string;
27
- } & Partial<NewMail>): Promise<DraftMail>;
28
- /**
29
- * @deprecated Pass a single object instead:
30
- * `updateDraft({ draftId, ...args })`.
31
- */
32
- updateDraft(draftId: string, args: Partial<NewMail>): Promise<DraftMail>;
18
+ updateDraft(draftId: string, { body, subject, senderFiles, recipients, replyToId }: Partial<NewMail>): Promise<DraftMail>;
33
19
  deleteDraft(draftId: string): Promise<boolean>;
34
20
  deleteTrash({ ids }: {
35
21
  ids: string[];
@@ -38,14 +24,6 @@ export declare class SecrecyMailClient {
38
24
  delete({ mailId }: {
39
25
  mailId: string;
40
26
  }): Promise<boolean>;
41
- sendDraft(input: {
42
- draftId: string;
43
- customMessage?: string | null | undefined;
44
- }): Promise<boolean>;
45
- /**
46
- * @deprecated Pass a single object instead:
47
- * `sendDraft({ draftId, customMessage })`.
48
- */
49
27
  sendDraft(draftId: string, customMessage?: string | null | undefined): Promise<boolean>;
50
28
  sendWaitingEmails(): Promise<void>;
51
29
  createDraft({ body, subject, senderFiles, recipients, replyToId, }: NewMail): Promise<DraftMail>;
@@ -1,7 +1,6 @@
1
1
  import { SecrecyClient } from './index.js';
2
2
  import { type SecrecyUserApp } from './types/index.js';
3
3
  import type { SecrecyUrls } from '../base-client.js';
4
- export declare function assertBrowser(fn: string): void;
5
4
  export declare function parseInfos(): SecrecyUserApp | null;
6
5
  export interface HashInfos {
7
6
  appId?: string;
@@ -30,16 +29,4 @@ type LoginResponse<Params extends UseSecrecyParams> = Params extends {
30
29
  redirect: true;
31
30
  } ? SecrecyClient | null : SecrecyClient;
32
31
  export declare function login<Params extends UseSecrecyParams>({ appId, context, path, redirect, scopes, backPath, session, secrecyUrls, forceLogin, }: Params): Promise<LoginResponse<Params>>;
33
- /**
34
- * Single async entry point: runs `setup()`, reuses an existing session if
35
- * one is found, and falls back to `login()` otherwise. Equivalent to
36
- * `await setup()` + `getSecrecyClient()` + `login()`, without having to
37
- * juggle the sync/async mismatch between them.
38
- */
39
- export declare function initSecrecy(opts: {
40
- appId: string;
41
- session?: boolean | undefined;
42
- redirect?: boolean | undefined;
43
- secrecyUrls?: Partial<SecrecyUrls>;
44
- }): Promise<SecrecyClient | null>;
45
32
  export {};
@@ -3,6 +3,7 @@ import type { SecretStreamProgress } from '../crypto/data.js';
3
3
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
4
4
  import { SecrecyMailClient } from './SecrecyMailClient.js';
5
5
  import { SecrecyAppClient } from './SecrecyAppClient.js';
6
+ import { SecrecyDbClient } from './SecrecyDbClient.js';
6
7
  import { SecrecyWalletClient } from './SecrecyWalletClient.js';
7
8
  import { SecrecyPayClient } from './SecrecyPayClient.js';
8
9
  import { type ApiClient, type RouterInputs } from '../client.js';
@@ -21,18 +22,15 @@ export interface SecrecyClientOptions {
21
22
  uaJwt: string;
22
23
  apiClient?: ApiClient;
23
24
  secrecyUrls?: Partial<SecrecyUrls>;
24
- timeoutMs?: number;
25
- reloadOnAccessDenied?: boolean;
26
25
  }
27
26
  export declare class SecrecyClient extends BaseClient {
28
27
  #private;
29
28
  cloud: SecrecyCloudClient;
30
29
  mail: SecrecyMailClient;
31
30
  app: SecrecyAppClient;
31
+ db: SecrecyDbClient;
32
32
  organization: SecrecyOrganizationClient;
33
- /** @experimental Susceptible de changer sans version majeure. */
34
33
  wallet: SecrecyWalletClient;
35
- /** @experimental Susceptible de changer sans version majeure. */
36
34
  pay: SecrecyPayClient;
37
35
  user: SecrecyUserClient;
38
36
  pseudonym: SecrecyPseudonymClient;
@@ -8,7 +8,6 @@ export interface CreateTrpcClientOptions {
8
8
  session?: string | null | undefined;
9
9
  apiUrl?: string | null | undefined;
10
10
  onAccessDenied?: () => void | Promise<void> | null | undefined;
11
- timeoutMs?: number | undefined;
12
11
  }
13
12
  export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import("@trpc/client").TRPCClient<import("@trpc/server").TRPCBuiltRouter<{
14
13
  ctx: any;
@@ -3919,7 +3918,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
3919
3918
  output: {
3920
3919
  id: string;
3921
3920
  name: string;
3922
- currentState: "init" | "ready";
3921
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
3923
3922
  isPrimary: boolean;
3924
3923
  parentId?: string | undefined;
3925
3924
  };
@@ -3943,7 +3942,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
3943
3942
  output: {
3944
3943
  id: string;
3945
3944
  name: string;
3946
- currentState: "init" | "ready";
3945
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
3947
3946
  isPrimary: boolean;
3948
3947
  parentId?: string | undefined;
3949
3948
  };
@@ -3961,7 +3960,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
3961
3960
  output: {
3962
3961
  id: string;
3963
3962
  name: string;
3964
- currentState: "init" | "ready";
3963
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
3965
3964
  isPrimary: boolean;
3966
3965
  parentId?: string | undefined;
3967
3966
  }[];
@@ -3977,7 +3976,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
3977
3976
  output: {
3978
3977
  id: string;
3979
3978
  name: string;
3980
- currentState: "init" | "ready";
3979
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
3981
3980
  isPrimary: boolean;
3982
3981
  parentId?: string | undefined;
3983
3982
  };
@@ -4003,7 +4002,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
4003
4002
  output: {
4004
4003
  id: string;
4005
4004
  name: string;
4006
- currentState: "init" | "ready";
4005
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
4007
4006
  isPrimary: boolean;
4008
4007
  parentId?: string | undefined;
4009
4008
  };
@@ -4018,7 +4017,7 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => import
4018
4017
  output: {
4019
4018
  id: string;
4020
4019
  name: string;
4021
- currentState: "init" | "ready";
4020
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
4022
4021
  isPrimary: boolean;
4023
4022
  parentId?: string | undefined;
4024
4023
  };
@@ -10627,7 +10626,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10627
10626
  output: {
10628
10627
  id: string;
10629
10628
  name: string;
10630
- currentState: "init" | "ready";
10629
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10631
10630
  isPrimary: boolean;
10632
10631
  parentId?: string | undefined;
10633
10632
  };
@@ -10651,7 +10650,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10651
10650
  output: {
10652
10651
  id: string;
10653
10652
  name: string;
10654
- currentState: "init" | "ready";
10653
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10655
10654
  isPrimary: boolean;
10656
10655
  parentId?: string | undefined;
10657
10656
  };
@@ -10669,7 +10668,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10669
10668
  output: {
10670
10669
  id: string;
10671
10670
  name: string;
10672
- currentState: "init" | "ready";
10671
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10673
10672
  isPrimary: boolean;
10674
10673
  parentId?: string | undefined;
10675
10674
  }[];
@@ -10685,7 +10684,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10685
10684
  output: {
10686
10685
  id: string;
10687
10686
  name: string;
10688
- currentState: "init" | "ready";
10687
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10689
10688
  isPrimary: boolean;
10690
10689
  parentId?: string | undefined;
10691
10690
  };
@@ -10711,7 +10710,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10711
10710
  output: {
10712
10711
  id: string;
10713
10712
  name: string;
10714
- currentState: "init" | "ready";
10713
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10715
10714
  isPrimary: boolean;
10716
10715
  parentId?: string | undefined;
10717
10716
  };
@@ -10726,7 +10725,7 @@ export declare const getTrpcGuestClient: ({ url }?: {
10726
10725
  output: {
10727
10726
  id: string;
10728
10727
  name: string;
10729
- currentState: "init" | "ready";
10728
+ currentState: "init" | "resetting" | "ready" | "archived" | (string & Record<never, never>);
10730
10729
  isPrimary: boolean;
10731
10730
  parentId?: string | undefined;
10732
10731
  };
@@ -1,20 +1,12 @@
1
1
  import { z } from 'zod';
2
2
  export declare const clientErrorCodeKey: z.ZodEnum<{
3
3
  NOT_FOUND: "NOT_FOUND";
4
- DATA_TOO_SHORT: "DATA_TOO_SHORT";
5
- POPUP_BLOCKED: "POPUP_BLOCKED";
6
- POPUP_CLOSED: "POPUP_CLOSED";
7
- SERVER_ENVIRONMENT: "SERVER_ENVIRONMENT";
8
4
  }>;
9
5
  export type CLIENT_ERROR_CODE_KEY = z.infer<typeof clientErrorCodeKey>;
10
6
  export declare const clientError: z.ZodObject<{
11
7
  name: z.ZodLiteral<"ClientError">;
12
8
  code: z.ZodEnum<{
13
9
  NOT_FOUND: "NOT_FOUND";
14
- DATA_TOO_SHORT: "DATA_TOO_SHORT";
15
- POPUP_BLOCKED: "POPUP_BLOCKED";
16
- POPUP_CLOSED: "POPUP_CLOSED";
17
- SERVER_ENVIRONMENT: "SERVER_ENVIRONMENT";
18
10
  }>;
19
11
  message: z.ZodString;
20
12
  }, z.core.$strip>;
@@ -24,10 +24,6 @@ export declare const secrecyError: z.ZodDiscriminatedUnion<[z.ZodObject<{
24
24
  name: z.ZodLiteral<"ClientError">;
25
25
  code: z.ZodEnum<{
26
26
  NOT_FOUND: "NOT_FOUND";
27
- DATA_TOO_SHORT: "DATA_TOO_SHORT";
28
- POPUP_BLOCKED: "POPUP_BLOCKED";
29
- POPUP_CLOSED: "POPUP_CLOSED";
30
- SERVER_ENVIRONMENT: "SERVER_ENVIRONMENT";
31
27
  }>;
32
28
  message: z.ZodString;
33
29
  }, z.core.$strip>], "name">;
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * TS Rewrite of https://github.com/enhancv/popup-tools
3
3
  */
4
- import { type ClientError } from '../error/client.js';
5
4
  type YesNo = 'yes' | 'no';
6
5
  interface Options {
7
6
  width?: number;
@@ -14,7 +13,7 @@ interface Options {
14
13
  left?: number;
15
14
  top?: number;
16
15
  }
17
- type Callback = (err?: ClientError, data?: unknown) => void;
16
+ type Callback = (err?: Error, data?: unknown) => void;
18
17
  /**
19
18
  * Open a popup using the first argument.
20
19
  * Wait for it to close and call the callback.
@@ -45,6 +44,9 @@ export declare function popup(url: string, name: string, options: Partial<Option
45
44
  export declare function popupWithPost(url: string, postData: Record<string, string>, name: string, options: Partial<Options>, callback: Callback): Window | null;
46
45
  /**
47
46
  * Return html that when executed, will trigger the popup to callback with a response
47
+ *
48
+ * @param {Object}
49
+ * @return {String}
48
50
  */
49
- export declare function popupResponse<T>(id: string, data: T, targetOrigin: string): string;
51
+ export declare function popupResponse<T>(id: string, data: T): string;
50
52
  export {};
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "@secrecy/lib",
3
3
  "author": "Anonymize <anonymize@gmail.com>",
4
- "description": "Client-side end-to-end encryption SDK for Secrecy",
5
- "version": "1.86.1-feat-improve-sdk.2",
6
- "engines": {
7
- "node": ">=22.21.1"
8
- },
4
+ "description": "Anonymize Secrecy Library",
5
+ "version": "1.86.2-fix-metrics.1",
9
6
  "repository": {
10
7
  "type": "git",
11
8
  "url": "https://github.com/anonymize-org/lib.git"
@@ -16,12 +13,11 @@
16
13
  },
17
14
  "homepage": "https://github.com/anonymize-org/lib#readme",
18
15
  "keywords": [
16
+ "anonymize",
17
+ "lib",
19
18
  "secrecy",
20
- "e2ee",
21
- "encryption",
22
- "libsodium",
23
- "zero-knowledge",
24
- "browser"
19
+ "wallet",
20
+ "stripe"
25
21
  ],
26
22
  "type": "module",
27
23
  "exports": {
@@ -55,12 +51,9 @@
55
51
  "devDependencies": {
56
52
  "@commitlint/cli": "^20.3.0",
57
53
  "@commitlint/config-conventional": "^20.3.0",
58
- "@happy-dom/global-registrator": "^20.11.2",
59
54
  "@prisma/client": "6.17.1",
60
- "@trpc/server": "^11.6.0",
61
55
  "@types/bun": "^1.3.5",
62
56
  "@types/jsonwebtoken": "^9.0.10",
63
- "@types/react": "^19.2.18",
64
57
  "@types/spark-md5": "^3.0.5",
65
58
  "@types/streamsaver": "^2.0.5",
66
59
  "@typescript-eslint/eslint-plugin": "^8.52.0",
@@ -74,7 +67,6 @@
74
67
  "husky": "^9.1.7",
75
68
  "npm-run-all": "^4.1.5",
76
69
  "prettier": "^3.7.4",
77
- "react": "^19.2.8",
78
70
  "rimraf": "^6.1.2",
79
71
  "semantic-release": "^25.0.2",
80
72
  "typedoc": "^0.28.15",
@@ -84,8 +76,9 @@
84
76
  },
85
77
  "dependencies": {
86
78
  "@js-temporal/polyfill": "^0.5.1",
87
- "@secrecy/trpc-api-types": "1.41.0-dev.1",
79
+ "@secrecy/trpc-api-types": "1.41.0-fix-dashboard-dev-db-metrics.1",
88
80
  "@trpc/client": "11.6.0",
81
+ "@trpc/server": "^11.6.0",
89
82
  "@types/libsodium-wrappers-sumo": "^0.7.8",
90
83
  "axios": "^1.13.2",
91
84
  "bson": "^7.0.0",
@@ -99,13 +92,5 @@
99
92
  "streamsaver": "^2.0.6",
100
93
  "superjson": "2.2.6",
101
94
  "zod": "4.3.5"
102
- },
103
- "peerDependencies": {
104
- "react": "^18.0.0 || ^19.0.0"
105
- },
106
- "peerDependenciesMeta": {
107
- "react": {
108
- "optional": true
109
- }
110
95
  }
111
96
  }
@@ -1,69 +0,0 @@
1
- import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useState, } from 'react';
2
- import { initSecrecy, login as secrecyLogin } from '../client/helpers.js';
3
- const SecrecyContext = createContext(null);
4
- export function SecrecyProvider(props) {
5
- const { appId, session, redirect, secrecyUrls, children } = props;
6
- const [client, setClient] = useState(null);
7
- const [status, setStatus] = useState('idle');
8
- const [error, setError] = useState(null);
9
- const secrecyUrlsKey = JSON.stringify(secrecyUrls ?? null);
10
- useEffect(() => {
11
- let cancelled = false;
12
- setStatus('loading');
13
- initSecrecy({ appId, session, redirect, secrecyUrls })
14
- .then((result) => {
15
- if (cancelled)
16
- return;
17
- setClient(result);
18
- setStatus(result !== null ? 'authenticated' : 'idle');
19
- })
20
- .catch((err) => {
21
- if (cancelled)
22
- return;
23
- setError(err);
24
- setStatus('error');
25
- });
26
- return () => {
27
- cancelled = true;
28
- };
29
- // secrecyUrls is tracked through secrecyUrlsKey, a stable primitive.
30
- // eslint-disable-next-line react-hooks/exhaustive-deps
31
- }, [appId, session, redirect, secrecyUrlsKey]);
32
- const login = useCallback(async () => {
33
- setStatus('loading');
34
- setError(null);
35
- try {
36
- const result = await secrecyLogin({
37
- appId,
38
- session,
39
- secrecyUrls,
40
- forceLogin: true,
41
- });
42
- setClient(result);
43
- setStatus('authenticated');
44
- }
45
- catch (err) {
46
- setError(err);
47
- setStatus('error');
48
- }
49
- // secrecyUrls is tracked through secrecyUrlsKey, a stable primitive.
50
- // eslint-disable-next-line react-hooks/exhaustive-deps
51
- }, [appId, session, secrecyUrlsKey]);
52
- const logout = useCallback(async () => {
53
- if (client === null) {
54
- return;
55
- }
56
- await client.logout();
57
- setClient(null);
58
- setStatus('idle');
59
- }, [client]);
60
- const value = useMemo(() => ({ client, status, error, login, logout }), [client, status, error, login, logout]);
61
- return createElement(SecrecyContext.Provider, { value }, children);
62
- }
63
- export function useSecrecy() {
64
- const ctx = useContext(SecrecyContext);
65
- if (ctx === null) {
66
- throw new Error('useSecrecy() must be used within a <SecrecyProvider>');
67
- }
68
- return ctx;
69
- }
@@ -1,20 +0,0 @@
1
- import { type ReactNode } from 'react';
2
- import type { SecrecyClient } from '../client/index.js';
3
- import type { SecrecyUrls } from '../base-client.js';
4
- export type SecrecyStatus = 'idle' | 'loading' | 'authenticated' | 'error';
5
- export interface SecrecyContextValue {
6
- client: SecrecyClient | null;
7
- status: SecrecyStatus;
8
- error: unknown;
9
- login: () => Promise<void>;
10
- logout: () => Promise<void>;
11
- }
12
- export interface SecrecyProviderProps {
13
- appId: string;
14
- session?: boolean | undefined;
15
- redirect?: boolean | undefined;
16
- secrecyUrls?: Partial<SecrecyUrls> | undefined;
17
- children?: ReactNode;
18
- }
19
- export declare function SecrecyProvider(props: SecrecyProviderProps): ReactNode;
20
- export declare function useSecrecy(): SecrecyContextValue;