@ai-matrx/vault 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react from 'react';
2
+ import { ReactNode } from 'react';
2
3
  import { Look } from '@ai-matrx/design-system';
3
4
  import { KnobClient } from '@ai-matrx/data/knobs';
4
5
  import * as account from '@ai-matrx/api/account';
@@ -122,8 +123,26 @@ declare function locationFromParams(params: URLSearchParams, itemId?: string | n
122
123
  declare function locationToParams(loc: VaultLocation): URLSearchParams;
123
124
  /** The one search every list shares: name, type, tags, URLs, then plaintext custom fields. */
124
125
  declare function matchesQuery(item: VaultItem, query: string): boolean;
126
+ /**
127
+ * The authenticator's own storage on an item (the seed, digits, period, issuer…): shown only as the
128
+ * one "One-time password" row, never as loose fields — and always kept when the item is saved.
129
+ */
130
+ /**
131
+ * A vault item a host keeps for itself, never shown in any list (the desktop app's Touch ID key:
132
+ * its one-time-password factor's secret, so each of the person's computers can read it). Marked by
133
+ * this tag; the person's own vault holds it like any other item, encrypted by the server.
134
+ */
135
+ declare const HIDDEN_ITEM_TAG = "matrx:hidden";
136
+ declare const isHiddenItem: (item: {
137
+ tags?: readonly string[] | null;
138
+ }) => boolean;
125
139
  /** An item's website as people read it: `github.com` (no scheme, no `www.`), or "" when it has none. */
126
140
  declare function loginSiteOf(item: Pick<VaultItem, "loginUrls">): string;
141
+ /**
142
+ * The site a host belongs to, its registrable domain: `accounts.google.com` → `google.com`,
143
+ * `shop.example.co.uk` → `example.co.uk`. An address or a one-label host is returned as it is.
144
+ */
145
+ declare function siteDomainOf(host: string): string;
127
146
  declare function sortItems(items: readonly VaultItem[], sort: VaultSort): VaultItem[];
128
147
  interface NewSecretField {
129
148
  key: string;
@@ -240,6 +259,12 @@ interface VaultIdentity {
240
259
  withEmailCode(code: string): Promise<void>;
241
260
  /** A host-only path with no human step (the playground's dev server). */
242
261
  dev?: () => Promise<void>;
262
+ /**
263
+ * Run once when the page loads. After a provider confirmation left the page and came back, it
264
+ * checks the SAME person is signed in. A different account is signed out of this device and the
265
+ * sentence to show is returned; otherwise null.
266
+ */
267
+ checkReturn?: () => Promise<string | null>;
243
268
  }
244
269
  /** The slice of supabase-js `auth` this needs, so the package never depends on supabase-js itself. */
245
270
  interface SupabaseAuthLike {
@@ -305,12 +330,38 @@ interface SupabaseAuthLike {
305
330
  message: string;
306
331
  } | null;
307
332
  }>;
333
+ /** Used only when the host gives no `onDifferentPerson`: ends THIS device's session, never others. */
334
+ signOut?(o: {
335
+ scope: "local";
336
+ }): Promise<{
337
+ error: unknown;
338
+ }>;
308
339
  }
309
- /** THE identity confirmation for every host: give it the host's `supabase.auth`. */
310
- declare function createSupabaseIdentity(auth: SupabaseAuthLike, options?: {
340
+ /** Where the person confirming is remembered while the page is away at the provider. */
341
+ interface ReturnStore {
342
+ getItem(key: string): string | null;
343
+ setItem(key: string, value: string): void;
344
+ removeItem(key: string): void;
345
+ }
346
+ interface SupabaseIdentityOptions {
347
+ /** The host's accepted OAuth return address carrying this page. */
311
348
  redirectTo?: () => string;
312
349
  dev?: () => Promise<void>;
313
- }): VaultIdentity;
350
+ /**
351
+ * A provider confirmation came back signed in as someone else. The host ends that session on THIS
352
+ * device only (its own device-scoped sign-out) and tells the person; `message` says what happened.
353
+ * Without it the package signs out locally through `auth.signOut({ scope: "local" })`.
354
+ */
355
+ onDifferentPerson?: (message: string) => Promise<void> | void;
356
+ /** Default: the tab's `sessionStorage`. */
357
+ store?: ReturnStore;
358
+ /** Default `Date.now`. */
359
+ now?: () => number;
360
+ }
361
+ /** The key the expected person is kept under across the provider's redirect. */
362
+ declare const CONFIRM_RETURN_KEY = "matrx-vault:confirming-as";
363
+ /** THE identity confirmation for every host: give it the host's `supabase.auth`. */
364
+ declare function createSupabaseIdentity(auth: SupabaseAuthLike, options?: SupabaseIdentityOptions): VaultIdentity;
314
365
  /** True when the server refused because the sign-in is not recent enough. */
315
366
  declare function needsRecentSignIn(e: unknown): boolean;
316
367
 
@@ -1118,6 +1169,8 @@ interface VaultHostCapabilities {
1118
1169
  /** Desktop: the native passkey importer (file chooser, parsing and keys stay native). */
1119
1170
  nativeImport?: NativeImportBridge;
1120
1171
  openUrl?: (url: string) => void;
1172
+ /** The host's own sign-in, offered when the session has ended (the web app: its login page, back here after). */
1173
+ signIn?: () => void;
1121
1174
  /** A lock the host holds (`lock.ts`): while locked the vault shows Unlock and refuses every port call. */
1122
1175
  lock?: VaultLock;
1123
1176
  /** The host's clipboard: every copy goes through it; a secret is the host's to clear (`lock.ts`). */
@@ -1236,6 +1289,20 @@ interface ApiVaultPortOptions {
1236
1289
  }
1237
1290
  declare function createApiVaultPort(api: Api, options?: ApiVaultPortOptions): VaultPort;
1238
1291
 
1292
+ /**
1293
+ * Wrap any call that shows, copies or exports a secret. When the server answers "sign in again",
1294
+ * the person confirms it is them (Google, password, or an emailed code) and the call runs again —
1295
+ * they never see a dead "Authentication required" in the row.
1296
+ */
1297
+ type Confirmed = <T>(run: () => Promise<T>) => Promise<T>;
1298
+ declare function useConfirmed(): Confirmed;
1299
+ declare function IdentityGate({ identity, children }: {
1300
+ identity: VaultIdentity | undefined;
1301
+ children: ReactNode;
1302
+ }): react.JSX.Element;
1303
+ /** True for the rejection a cancelled confirmation produces (callers stay quiet about it). */
1304
+ declare const wasCancelled: (e: unknown) => boolean;
1305
+
1239
1306
  /** Reads the organization's ceilings. Raw knob values are fine: they are validated here. */
1240
1307
  type GeneratorLimitsSource = () => Promise<{
1241
1308
  maxPasswordLength?: unknown;
@@ -1252,4 +1319,4 @@ declare function GenerateButton({ onUse, label, limits, disabled }: {
1252
1319
  disabled?: boolean;
1253
1320
  }): react.JSX.Element | null;
1254
1321
 
1255
- export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, sortItems };
1322
+ export { type ApiVaultPortOptions, CATEGORIES, CONFIRM_RETURN_KEY, type CategoryId, type Confirmed, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, HIDDEN_ITEM_TAG, type IdentityAccount, IdentityGate, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type ReturnStore, type SaveResult, type SupabaseAuthLike, type SupabaseIdentityOptions, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, isHiddenItem, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, siteDomainOf, sortItems, useConfirmed, wasCancelled };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react from 'react';
2
+ import { ReactNode } from 'react';
2
3
  import { Look } from '@ai-matrx/design-system';
3
4
  import { KnobClient } from '@ai-matrx/data/knobs';
4
5
  import * as account from '@ai-matrx/api/account';
@@ -122,8 +123,26 @@ declare function locationFromParams(params: URLSearchParams, itemId?: string | n
122
123
  declare function locationToParams(loc: VaultLocation): URLSearchParams;
123
124
  /** The one search every list shares: name, type, tags, URLs, then plaintext custom fields. */
124
125
  declare function matchesQuery(item: VaultItem, query: string): boolean;
126
+ /**
127
+ * The authenticator's own storage on an item (the seed, digits, period, issuer…): shown only as the
128
+ * one "One-time password" row, never as loose fields — and always kept when the item is saved.
129
+ */
130
+ /**
131
+ * A vault item a host keeps for itself, never shown in any list (the desktop app's Touch ID key:
132
+ * its one-time-password factor's secret, so each of the person's computers can read it). Marked by
133
+ * this tag; the person's own vault holds it like any other item, encrypted by the server.
134
+ */
135
+ declare const HIDDEN_ITEM_TAG = "matrx:hidden";
136
+ declare const isHiddenItem: (item: {
137
+ tags?: readonly string[] | null;
138
+ }) => boolean;
125
139
  /** An item's website as people read it: `github.com` (no scheme, no `www.`), or "" when it has none. */
126
140
  declare function loginSiteOf(item: Pick<VaultItem, "loginUrls">): string;
141
+ /**
142
+ * The site a host belongs to, its registrable domain: `accounts.google.com` → `google.com`,
143
+ * `shop.example.co.uk` → `example.co.uk`. An address or a one-label host is returned as it is.
144
+ */
145
+ declare function siteDomainOf(host: string): string;
127
146
  declare function sortItems(items: readonly VaultItem[], sort: VaultSort): VaultItem[];
128
147
  interface NewSecretField {
129
148
  key: string;
@@ -240,6 +259,12 @@ interface VaultIdentity {
240
259
  withEmailCode(code: string): Promise<void>;
241
260
  /** A host-only path with no human step (the playground's dev server). */
242
261
  dev?: () => Promise<void>;
262
+ /**
263
+ * Run once when the page loads. After a provider confirmation left the page and came back, it
264
+ * checks the SAME person is signed in. A different account is signed out of this device and the
265
+ * sentence to show is returned; otherwise null.
266
+ */
267
+ checkReturn?: () => Promise<string | null>;
243
268
  }
244
269
  /** The slice of supabase-js `auth` this needs, so the package never depends on supabase-js itself. */
245
270
  interface SupabaseAuthLike {
@@ -305,12 +330,38 @@ interface SupabaseAuthLike {
305
330
  message: string;
306
331
  } | null;
307
332
  }>;
333
+ /** Used only when the host gives no `onDifferentPerson`: ends THIS device's session, never others. */
334
+ signOut?(o: {
335
+ scope: "local";
336
+ }): Promise<{
337
+ error: unknown;
338
+ }>;
308
339
  }
309
- /** THE identity confirmation for every host: give it the host's `supabase.auth`. */
310
- declare function createSupabaseIdentity(auth: SupabaseAuthLike, options?: {
340
+ /** Where the person confirming is remembered while the page is away at the provider. */
341
+ interface ReturnStore {
342
+ getItem(key: string): string | null;
343
+ setItem(key: string, value: string): void;
344
+ removeItem(key: string): void;
345
+ }
346
+ interface SupabaseIdentityOptions {
347
+ /** The host's accepted OAuth return address carrying this page. */
311
348
  redirectTo?: () => string;
312
349
  dev?: () => Promise<void>;
313
- }): VaultIdentity;
350
+ /**
351
+ * A provider confirmation came back signed in as someone else. The host ends that session on THIS
352
+ * device only (its own device-scoped sign-out) and tells the person; `message` says what happened.
353
+ * Without it the package signs out locally through `auth.signOut({ scope: "local" })`.
354
+ */
355
+ onDifferentPerson?: (message: string) => Promise<void> | void;
356
+ /** Default: the tab's `sessionStorage`. */
357
+ store?: ReturnStore;
358
+ /** Default `Date.now`. */
359
+ now?: () => number;
360
+ }
361
+ /** The key the expected person is kept under across the provider's redirect. */
362
+ declare const CONFIRM_RETURN_KEY = "matrx-vault:confirming-as";
363
+ /** THE identity confirmation for every host: give it the host's `supabase.auth`. */
364
+ declare function createSupabaseIdentity(auth: SupabaseAuthLike, options?: SupabaseIdentityOptions): VaultIdentity;
314
365
  /** True when the server refused because the sign-in is not recent enough. */
315
366
  declare function needsRecentSignIn(e: unknown): boolean;
316
367
 
@@ -1118,6 +1169,8 @@ interface VaultHostCapabilities {
1118
1169
  /** Desktop: the native passkey importer (file chooser, parsing and keys stay native). */
1119
1170
  nativeImport?: NativeImportBridge;
1120
1171
  openUrl?: (url: string) => void;
1172
+ /** The host's own sign-in, offered when the session has ended (the web app: its login page, back here after). */
1173
+ signIn?: () => void;
1121
1174
  /** A lock the host holds (`lock.ts`): while locked the vault shows Unlock and refuses every port call. */
1122
1175
  lock?: VaultLock;
1123
1176
  /** The host's clipboard: every copy goes through it; a secret is the host's to clear (`lock.ts`). */
@@ -1236,6 +1289,20 @@ interface ApiVaultPortOptions {
1236
1289
  }
1237
1290
  declare function createApiVaultPort(api: Api, options?: ApiVaultPortOptions): VaultPort;
1238
1291
 
1292
+ /**
1293
+ * Wrap any call that shows, copies or exports a secret. When the server answers "sign in again",
1294
+ * the person confirms it is them (Google, password, or an emailed code) and the call runs again —
1295
+ * they never see a dead "Authentication required" in the row.
1296
+ */
1297
+ type Confirmed = <T>(run: () => Promise<T>) => Promise<T>;
1298
+ declare function useConfirmed(): Confirmed;
1299
+ declare function IdentityGate({ identity, children }: {
1300
+ identity: VaultIdentity | undefined;
1301
+ children: ReactNode;
1302
+ }): react.JSX.Element;
1303
+ /** True for the rejection a cancelled confirmation produces (callers stay quiet about it). */
1304
+ declare const wasCancelled: (e: unknown) => boolean;
1305
+
1239
1306
  /** Reads the organization's ceilings. Raw knob values are fine: they are validated here. */
1240
1307
  type GeneratorLimitsSource = () => Promise<{
1241
1308
  maxPasswordLength?: unknown;
@@ -1252,4 +1319,4 @@ declare function GenerateButton({ onUse, label, limits, disabled }: {
1252
1319
  disabled?: boolean;
1253
1320
  }): react.JSX.Element | null;
1254
1321
 
1255
- export { type ApiVaultPortOptions, CATEGORIES, type CategoryId, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, type IdentityAccount, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type SaveResult, type SupabaseAuthLike, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, sortItems };
1322
+ export { type ApiVaultPortOptions, CATEGORIES, CONFIRM_RETURN_KEY, type CategoryId, type Confirmed, type CopyOptions, DEFAULT_LOCATION, type DefinitionField, type FieldHandling, type FieldKind, GenerateButton, HIDDEN_ITEM_TAG, type IdentityAccount, IdentityGate, type IdentityMethod, type ItemDraft, LOCKED_MESSAGE, type NoticeKind, type Notify, type ReturnStore, type SaveResult, type SupabaseAuthLike, type SupabaseIdentityOptions, type TotpReading, type UriMatchMode, type UrlGuess, VaultApp, type VaultAppProps, type VaultAttachment, type VaultAuthenticator, type VaultClipboard, type VaultCustomField, type VaultDefinition, type VaultField, type VaultHostCapabilities, type VaultIdentity, type VaultItem, type VaultItemCapabilities, type VaultKnobs, type VaultLayout, type VaultLocation, type VaultLock, VaultLockedError, type VaultOrganizationRef, type VaultOwner, type VaultPort, type VaultSelection, type VaultSnapshot, type VaultSort, type VaultUserStateDoor, categoryOf, copyValue, createApiVaultPort, createSupabaseIdentity, createVaultKnobs, guardPort, inferFromUrl, isHiddenItem, locationFromParams, locationToParams, loginSiteOf, matchesQuery, needsRecentSignIn, parseDefinitions, siteDomainOf, sortItems, useConfirmed, wasCancelled };