@ai-matrx/vault 0.1.9 → 0.1.11
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/CHANGELOG.md +40 -1
- package/dist/index.cjs +245 -264
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +227 -246
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -164,6 +164,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } f
|
|
|
164
164
|
import { Button, Field } from "@ai-matrx/design-system/controls";
|
|
165
165
|
|
|
166
166
|
// src/glyphs.tsx
|
|
167
|
+
import { GlobeIcon } from "@ai-matrx/design-system/icons";
|
|
167
168
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
168
169
|
function glyph(paths, air = [1, 1]) {
|
|
169
170
|
const style = { "--matrx-glyph-air-l": air[0], "--matrx-glyph-air-r": air[1] };
|
|
@@ -175,10 +176,6 @@ var KeyGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
|
175
176
|
/* @__PURE__ */ jsx2("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
|
|
176
177
|
/* @__PURE__ */ jsx2("path", { d: "m21 2-9.6 9.6M15.5 7.5l3 3" })
|
|
177
178
|
] }), [1, 2]);
|
|
178
|
-
var GlobeGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
179
|
-
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10" }),
|
|
180
|
-
/* @__PURE__ */ jsx2("path", { d: "M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
|
|
181
|
-
] }), [1, 1]);
|
|
182
179
|
var NoteGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
183
180
|
/* @__PURE__ */ jsx2("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
184
181
|
/* @__PURE__ */ jsx2("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M16 13H8M16 17H8" })
|
|
@@ -208,10 +205,6 @@ var FileGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
|
208
205
|
var CodeGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "m16 18 6-6-6-6M8 6l-6 6 6 6" }) }), [1, 1]);
|
|
209
206
|
var StarGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1z" }), [1, 1]);
|
|
210
207
|
var PlusGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 5v14M5 12h14" }), [4, 4]);
|
|
211
|
-
var CopyGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
212
|
-
/* @__PURE__ */ jsx2("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
213
|
-
/* @__PURE__ */ jsx2("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
214
|
-
] }), [1, 1]);
|
|
215
208
|
var EyeGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
216
209
|
/* @__PURE__ */ jsx2("path", { d: "M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" }),
|
|
217
210
|
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
|
|
@@ -236,11 +229,6 @@ var BuildingGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
|
236
229
|
/* @__PURE__ */ jsx2("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
237
230
|
/* @__PURE__ */ jsx2("path", { d: "M9 22v-4h6v4M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01" })
|
|
238
231
|
] }), [3, 3]);
|
|
239
|
-
var UsersGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
240
|
-
/* @__PURE__ */ jsx2("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
|
|
241
|
-
/* @__PURE__ */ jsx2("circle", { cx: "9", cy: "7", r: "4" }),
|
|
242
|
-
/* @__PURE__ */ jsx2("path", { d: "M22 21v-2a4 4 0 0 0-3-3.9M16 3.1a4 4 0 0 1 0 7.8" })
|
|
243
|
-
] }), [1, 1]);
|
|
244
232
|
var ChevronLeftGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m15 18-6-6 6-6" }), [8, 8]);
|
|
245
233
|
var GridGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
246
234
|
/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
|
|
@@ -259,7 +247,7 @@ var FAMILY_GLYPHS = {
|
|
|
259
247
|
cloud_infrastructure: ServerGlyph
|
|
260
248
|
};
|
|
261
249
|
function definitionGlyph(key, family) {
|
|
262
|
-
if (key === "username_password" || key === "website_login") return
|
|
250
|
+
if (key === "username_password" || key === "website_login") return GlobeIcon;
|
|
263
251
|
return FAMILY_GLYPHS[family] ?? KeyGlyph;
|
|
264
252
|
}
|
|
265
253
|
var XGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M18 6 6 18M6 6l12 12" }), [5, 5]);
|
|
@@ -277,15 +265,7 @@ var MoreGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
|
277
265
|
/* @__PURE__ */ jsx2("circle", { cx: "5", cy: "12", r: "1" })
|
|
278
266
|
] }), [3, 3]);
|
|
279
267
|
var ShareGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13" }) }), [3, 3]);
|
|
280
|
-
var HistoryGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
281
|
-
/* @__PURE__ */ jsx2("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
282
|
-
/* @__PURE__ */ jsx2("path", { d: "M3 3v5h5M12 7v5l4 2" })
|
|
283
|
-
] }), [2, 2]);
|
|
284
268
|
var ListGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }), [2, 2]);
|
|
285
|
-
var SettingsGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
286
|
-
/* @__PURE__ */ jsx2("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
|
|
287
|
-
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
|
|
288
|
-
] }), [2, 2]);
|
|
289
269
|
var ImportGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }), [2, 2]);
|
|
290
270
|
var ExportGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" }), [2, 2]);
|
|
291
271
|
var ChevronDownGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }), [5, 5]);
|
|
@@ -326,10 +306,6 @@ var RefreshGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
|
326
306
|
/* @__PURE__ */ jsx2("path", { d: "M21 3v5h-5M3 21v-5h5" })
|
|
327
307
|
] }), [2, 2]);
|
|
328
308
|
var SlidersGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6" }) }), [0, 0]);
|
|
329
|
-
var DownloadGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
330
|
-
/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
331
|
-
/* @__PURE__ */ jsx2("path", { d: "m7 10 5 5 5-5M12 15V3" })
|
|
332
|
-
] }), [2, 2]);
|
|
333
309
|
var UploadGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
334
310
|
/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
335
311
|
/* @__PURE__ */ jsx2("path", { d: "m17 8-5-5-5 5M12 3v12" })
|
|
@@ -411,7 +387,7 @@ var Ctx2 = createContext2((run) => run());
|
|
|
411
387
|
function useConfirmed() {
|
|
412
388
|
return useContext2(Ctx2);
|
|
413
389
|
}
|
|
414
|
-
var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack" };
|
|
390
|
+
var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack", browser: "Browser", touch_id: "Touch ID" };
|
|
415
391
|
var providerLabel = (p) => PROVIDER_LABEL[p] ?? p.charAt(0).toUpperCase() + p.slice(1);
|
|
416
392
|
function IdentityGate({ identity, children }) {
|
|
417
393
|
const [asking, setAsking] = useState2(false);
|
|
@@ -481,10 +457,21 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
|
|
|
481
457
|
] }),
|
|
482
458
|
/* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-3", children: [
|
|
483
459
|
identity.dev ? /* @__PURE__ */ jsx3(Button, { variant: "primary", disabled: busy, onClick: () => void attempt(() => identity.dev?.() ?? Promise.resolve()), children: "Sign in again (dev)" }) : null,
|
|
484
|
-
account10?.providers.map((p) => /* @__PURE__ */ jsxs3(
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
460
|
+
account10?.providers.map((p) => /* @__PURE__ */ jsxs3(
|
|
461
|
+
Button,
|
|
462
|
+
{
|
|
463
|
+
variant: identity.dev ? "outline" : "primary",
|
|
464
|
+
disabled: busy,
|
|
465
|
+
onClick: () => void attempt(async () => {
|
|
466
|
+
if (await identity.withProvider(p) === "confirmed") onDone();
|
|
467
|
+
}, false),
|
|
468
|
+
children: [
|
|
469
|
+
"Continue with ",
|
|
470
|
+
providerLabel(p)
|
|
471
|
+
]
|
|
472
|
+
},
|
|
473
|
+
p
|
|
474
|
+
)),
|
|
488
475
|
account10?.hasPassword ? /* @__PURE__ */ jsxs3("form", { className: "flex gap-2", onSubmit: (e) => {
|
|
489
476
|
e.preventDefault();
|
|
490
477
|
if (password) void attempt(() => identity.withPassword(password));
|
|
@@ -511,6 +498,7 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
|
|
|
511
498
|
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
512
499
|
import { Badge, Button as Button2, Field as Field2, Textarea } from "@ai-matrx/design-system/controls";
|
|
513
500
|
import { cn as cn3 } from "@ai-matrx/design-system";
|
|
501
|
+
import { CopyIcon } from "@ai-matrx/design-system/icons";
|
|
514
502
|
|
|
515
503
|
// src/hooks.ts
|
|
516
504
|
import { createContext as createContext3, createElement, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
|
|
@@ -579,7 +567,7 @@ function useRoomOf(ref) {
|
|
|
579
567
|
return room;
|
|
580
568
|
}
|
|
581
569
|
var RoomProvider = Room.Provider;
|
|
582
|
-
function
|
|
570
|
+
function VaultSection({ title, actions, children, className }) {
|
|
583
571
|
const flat = useContext4(InPanel);
|
|
584
572
|
const desktop = useLook() === "desktop";
|
|
585
573
|
return /* @__PURE__ */ jsxs4("section", { className: cn2("flex flex-col gap-1.5", className), children: [
|
|
@@ -595,7 +583,7 @@ var ROW_GRID = {
|
|
|
595
583
|
roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
|
|
596
584
|
viewport: "grid-cols-[5.75rem_minmax(0,1fr)_auto] gap-x-2 px-3 sm:grid-cols-[9rem_minmax(0,1fr)_auto] sm:gap-x-3 sm:px-4"
|
|
597
585
|
};
|
|
598
|
-
function
|
|
586
|
+
function VaultRow({ label, hint, children, actions, top = false, className }) {
|
|
599
587
|
const room = useContext4(Room);
|
|
600
588
|
return /* @__PURE__ */ jsxs4("div", { className: cn2("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
|
|
601
589
|
/* @__PURE__ */ jsxs4("div", { className: cn2("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
|
|
@@ -616,11 +604,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
|
|
|
616
604
|
footer ? /* @__PURE__ */ jsx4(DialogFooter, { children: footer }) : null
|
|
617
605
|
] }) });
|
|
618
606
|
}
|
|
619
|
-
function formatBytes(n) {
|
|
620
|
-
if (n < 1024) return `${n} B`;
|
|
621
|
-
if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
|
|
622
|
-
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
623
|
-
}
|
|
624
607
|
var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
|
|
625
608
|
|
|
626
609
|
// src/FieldRows.tsx
|
|
@@ -679,14 +662,14 @@ function SecretRow({ port, item, field, extra }) {
|
|
|
679
662
|
const multiline = field.kind === "multiline";
|
|
680
663
|
const shown = visible ? plain : secret.value;
|
|
681
664
|
return /* @__PURE__ */ jsx5(
|
|
682
|
-
|
|
665
|
+
VaultRow,
|
|
683
666
|
{
|
|
684
667
|
label: field.label,
|
|
685
668
|
top: multiline && shown !== null,
|
|
686
669
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
687
670
|
extra,
|
|
688
671
|
canSee && !visible ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ jsx5(EyeOffGlyph, {}) : /* @__PURE__ */ jsx5(EyeGlyph, {}), "aria-label": secret.value !== null ? `Hide ${field.label}` : `Show ${field.label}`, disabled: busy, onClick: () => void toggle2() }) : null,
|
|
689
|
-
canSee ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(
|
|
672
|
+
canSee ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyIcon, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
|
|
690
673
|
] }),
|
|
691
674
|
children: sealed ? /* @__PURE__ */ jsx5(Badge, { icon: /* @__PURE__ */ jsx5(LockGlyph, {}), children: "Sealed" }) : off ? /* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: "Turned off" }) : error ? /* @__PURE__ */ jsx5("span", { className: "truncate text-destructive", title: error, children: error }) : shown !== null ? visible ? /* @__PURE__ */ jsx5("span", { className: cn3("block", multiline ? "whitespace-pre-wrap break-words" : "truncate"), children: shown || "\u2014" }) : /* @__PURE__ */ jsx5(SecretText, { value: shown, multiline }) : /* @__PURE__ */ jsx5("span", { className: cn3("block truncate text-muted-foreground", !visible && "tracking-widest"), children: visible ? "\u2026" : MASK })
|
|
692
675
|
}
|
|
@@ -696,7 +679,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
696
679
|
const copyValue2 = useCopy();
|
|
697
680
|
const isUrl = /^https?:\/\//i.test(value);
|
|
698
681
|
return /* @__PURE__ */ jsx5(
|
|
699
|
-
|
|
682
|
+
VaultRow,
|
|
700
683
|
{
|
|
701
684
|
label,
|
|
702
685
|
hint,
|
|
@@ -704,7 +687,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
704
687
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
705
688
|
extra,
|
|
706
689
|
isUrl && openUrl ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
|
|
707
|
-
/* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(
|
|
690
|
+
/* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyIcon, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
|
|
708
691
|
] }),
|
|
709
692
|
children: isUrl && openUrl ? (
|
|
710
693
|
// A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
|
|
@@ -727,12 +710,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
727
710
|
);
|
|
728
711
|
}
|
|
729
712
|
function AddRow({ label, onAdd, children = "Add" }) {
|
|
730
|
-
return /* @__PURE__ */ jsx5(
|
|
713
|
+
return /* @__PURE__ */ jsx5(VaultRow, { label, children: onAdd ? /* @__PURE__ */ jsx5("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ jsx5("span", { className: "text-disabled-foreground", children: "\u2014" }) });
|
|
731
714
|
}
|
|
732
715
|
function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
|
|
733
716
|
const [shown, setShown] = useState5(false);
|
|
734
717
|
return /* @__PURE__ */ jsx5(
|
|
735
|
-
|
|
718
|
+
VaultRow,
|
|
736
719
|
{
|
|
737
720
|
label,
|
|
738
721
|
hint,
|
|
@@ -749,7 +732,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
|
|
|
749
732
|
function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
750
733
|
const [shown, setShown] = useState5(false);
|
|
751
734
|
return /* @__PURE__ */ jsx5(
|
|
752
|
-
|
|
735
|
+
VaultRow,
|
|
753
736
|
{
|
|
754
737
|
label: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
|
|
755
738
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
@@ -762,6 +745,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
|
762
745
|
}
|
|
763
746
|
|
|
764
747
|
// src/activity/HistoryPanel.tsx
|
|
748
|
+
import { CopyIcon as CopyIcon2 } from "@ai-matrx/design-system/icons";
|
|
765
749
|
import { formatAbsoluteDate as formatAbsoluteDate2 } from "@ai-matrx/kit/format";
|
|
766
750
|
|
|
767
751
|
// src/activity/logic.ts
|
|
@@ -814,6 +798,8 @@ function matchesQuery(item, query) {
|
|
|
814
798
|
if (!q) return true;
|
|
815
799
|
return [item.name, item.definitionLabel, ...item.tags, ...item.loginUrls, ...item.custom.map((c) => `${c.label} ${c.value}`)].some((h) => h.toLowerCase().includes(q));
|
|
816
800
|
}
|
|
801
|
+
var HIDDEN_ITEM_TAG = "matrx:hidden";
|
|
802
|
+
var isHiddenItem = (item) => (item.tags ?? []).includes(HIDDEN_ITEM_TAG);
|
|
817
803
|
var isAuthenticatorStorage = (key) => key === "totp_seed" || key.startsWith("totp_") || key === "authenticator_last_time_step";
|
|
818
804
|
function loginSiteOf(item) {
|
|
819
805
|
const raw = item.loginUrls[0];
|
|
@@ -1254,7 +1240,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1254
1240
|
footer: hasMore ? /* @__PURE__ */ jsx6(Button3, { variant: "outline", disabled: loading, onClick: () => setLimit((n) => Math.min(MAX, n * 2)), children: loading ? "Loading\u2026" : "Show more" }) : void 0,
|
|
1255
1241
|
children: [
|
|
1256
1242
|
error ? /* @__PURE__ */ jsx6("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1257
|
-
entries === null ? loading ? /* @__PURE__ */ jsx6(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ jsx6(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ jsx6(
|
|
1243
|
+
entries === null ? loading ? /* @__PURE__ */ jsx6(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ jsx6(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ jsx6(VaultSection, { title: day.label, children: collapseRuns(
|
|
1258
1244
|
day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
|
|
1259
1245
|
(r) => `${r.s.what}|${r.s.who ?? ""}`
|
|
1260
1246
|
).map(({ row: { entry, s }, times }) => {
|
|
@@ -1277,7 +1263,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1277
1263
|
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1278
1264
|
var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
1279
1265
|
var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
1280
|
-
function
|
|
1266
|
+
function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
1281
1267
|
const eligible = historyEligible(item);
|
|
1282
1268
|
const [page, setPage] = useState7(null);
|
|
1283
1269
|
const [loading, setLoading] = useState7(eligible);
|
|
@@ -1339,7 +1325,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
|
1339
1325
|
error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1340
1326
|
notice ? /* @__PURE__ */ jsx7("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
|
|
1341
1327
|
page && groups.length === 0 ? /* @__PURE__ */ jsx7(Empty, { children: "No earlier values yet." }) : null,
|
|
1342
|
-
page ? groups.map((g) => /* @__PURE__ */ jsx7(
|
|
1328
|
+
page ? groups.map((g) => /* @__PURE__ */ jsx7(VaultSection, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ jsx7(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
|
|
1343
1329
|
page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
|
|
1344
1330
|
page.captureStartedAt ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
|
|
1345
1331
|
"Kept since ",
|
|
@@ -1400,12 +1386,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1400
1386
|
}
|
|
1401
1387
|
}
|
|
1402
1388
|
return /* @__PURE__ */ jsx7(
|
|
1403
|
-
|
|
1389
|
+
VaultRow,
|
|
1404
1390
|
{
|
|
1405
1391
|
label: when,
|
|
1406
1392
|
actions: entry.available ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1407
1393
|
/* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ jsx7(EyeOffGlyph, {}) : /* @__PURE__ */ jsx7(EyeGlyph, {}), "aria-label": secret.value !== null ? "Hide" : "Show", disabled: busy, onClick: () => void toggle2() }),
|
|
1408
|
-
/* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(
|
|
1394
|
+
/* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(CopyIcon2, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
|
|
1409
1395
|
canRestore(page, entry) ? /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
|
|
1410
1396
|
] }) : null,
|
|
1411
1397
|
children: !entry.available ? /* @__PURE__ */ jsx7(Badge2, { children: "Not kept" }) : secret.value !== null ? /* @__PURE__ */ jsx7(SecretText, { value: secret.value, multiline: false }) : /* @__PURE__ */ jsx7("span", { className: "block truncate tracking-widest text-muted-foreground", children: MASK2 })
|
|
@@ -1417,6 +1403,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1417
1403
|
import { useEffect as useEffect11, useState as useState13 } from "react";
|
|
1418
1404
|
import { Button as Button9 } from "@ai-matrx/design-system/controls";
|
|
1419
1405
|
import { cn as cn6, DropdownMenu as DropdownMenu2, DropdownMenuContent as DropdownMenuContent2, DropdownMenuItem as DropdownMenuItem2, DropdownMenuSeparator as DropdownMenuSeparator2, DropdownMenuTrigger as DropdownMenuTrigger2, TextInputDialog } from "@ai-matrx/design-system";
|
|
1406
|
+
import { CopyIcon as CopyIcon4 } from "@ai-matrx/design-system/icons";
|
|
1420
1407
|
|
|
1421
1408
|
// src/authenticator/AddOtpPanel.tsx
|
|
1422
1409
|
import { useState as useState12 } from "react";
|
|
@@ -1426,8 +1413,11 @@ import { Button as Button8, Field as Field4, Select as Select2 } from "@ai-matrx
|
|
|
1426
1413
|
import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
|
|
1427
1414
|
import { Button as Button5 } from "@ai-matrx/design-system/controls";
|
|
1428
1415
|
import { cn as cn5 } from "@ai-matrx/design-system";
|
|
1416
|
+
import { CopyIcon as CopyIcon3 } from "@ai-matrx/design-system/icons";
|
|
1417
|
+
import { groupCode as groupCode2 } from "@ai-matrx/kit/format";
|
|
1429
1418
|
|
|
1430
1419
|
// src/authenticator/otpauth.ts
|
|
1420
|
+
import { groupCode } from "@ai-matrx/kit/format";
|
|
1431
1421
|
var TOTP_DEFAULT_DIGITS = 6;
|
|
1432
1422
|
var TOTP_DEFAULT_PERIOD = 30;
|
|
1433
1423
|
var TOTP_DEFAULT_ALGORITHM = "SHA1";
|
|
@@ -1495,12 +1485,6 @@ function describeEnrollment(parsed) {
|
|
|
1495
1485
|
const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
|
|
1496
1486
|
return parts.length ? parts.join(" \xB7 ") : "Setup key";
|
|
1497
1487
|
}
|
|
1498
|
-
function groupCode(code) {
|
|
1499
|
-
const c = code.replace(/\s/g, "");
|
|
1500
|
-
if (c.length < 6) return c;
|
|
1501
|
-
const head = Math.ceil(c.length / 2);
|
|
1502
|
-
return `${c.slice(0, head)} ${c.slice(head)}`;
|
|
1503
|
-
}
|
|
1504
1488
|
function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
|
|
1505
1489
|
return groupCode("\u2022".repeat(Math.max(6, digits)));
|
|
1506
1490
|
}
|
|
@@ -1578,7 +1562,7 @@ function useCopied() {
|
|
|
1578
1562
|
}
|
|
1579
1563
|
function CodeButton({ live, digits, size = "md", label }) {
|
|
1580
1564
|
const { copied, copy } = useCopied();
|
|
1581
|
-
const shown = live.code ?
|
|
1565
|
+
const shown = live.code ? groupCode2(live.code) : maskedCode(digits);
|
|
1582
1566
|
return /* @__PURE__ */ jsxs8(
|
|
1583
1567
|
"button",
|
|
1584
1568
|
{
|
|
@@ -1597,7 +1581,7 @@ function CodeButton({ live, digits, size = "md", label }) {
|
|
|
1597
1581
|
}
|
|
1598
1582
|
function CopyCodeButton({ live, label }) {
|
|
1599
1583
|
const { copied, copy } = useCopied();
|
|
1600
|
-
return /* @__PURE__ */ jsx8(Button5, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx8(CheckGlyph, {}) : /* @__PURE__ */ jsx8(
|
|
1584
|
+
return /* @__PURE__ */ jsx8(Button5, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx8(CheckGlyph, {}) : /* @__PURE__ */ jsx8(CopyIcon3, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
|
|
1601
1585
|
}
|
|
1602
1586
|
|
|
1603
1587
|
// src/authenticator/live-code.ts
|
|
@@ -1869,7 +1853,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
|
|
|
1869
1853
|
className: dragging ? "rounded-lg bg-accent" : void 0,
|
|
1870
1854
|
children: [
|
|
1871
1855
|
/* @__PURE__ */ jsxs9(
|
|
1872
|
-
|
|
1856
|
+
VaultRow,
|
|
1873
1857
|
{
|
|
1874
1858
|
label,
|
|
1875
1859
|
actions: /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
@@ -2019,7 +2003,7 @@ function TotpRow({ port, item, onChanged }) {
|
|
|
2019
2003
|
] })
|
|
2020
2004
|
] }) : null;
|
|
2021
2005
|
return /* @__PURE__ */ jsx10(
|
|
2022
|
-
|
|
2006
|
+
VaultRow,
|
|
2023
2007
|
{
|
|
2024
2008
|
label: "One-time password",
|
|
2025
2009
|
actions: /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
@@ -2078,7 +2062,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
|
|
|
2078
2062
|
const [busy, setBusy] = useState11(false);
|
|
2079
2063
|
const [error, setError] = useState11(null);
|
|
2080
2064
|
const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
|
|
2081
|
-
return /* @__PURE__ */ jsx10(
|
|
2065
|
+
return /* @__PURE__ */ jsx10(VaultRow, { label: "Two-factor", hint: error ? /* @__PURE__ */ jsx10("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ jsx10(
|
|
2082
2066
|
Select,
|
|
2083
2067
|
{
|
|
2084
2068
|
value: value ?? "none",
|
|
@@ -2193,7 +2177,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2193
2177
|
/* @__PURE__ */ jsx11(Button8, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
|
|
2194
2178
|
] }),
|
|
2195
2179
|
children: [
|
|
2196
|
-
/* @__PURE__ */ jsxs11(
|
|
2180
|
+
/* @__PURE__ */ jsxs11(VaultSection, { children: [
|
|
2197
2181
|
/* @__PURE__ */ jsx11(
|
|
2198
2182
|
OtpSetupRow,
|
|
2199
2183
|
{
|
|
@@ -2215,7 +2199,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2215
2199
|
status: image ? `QR image ready \xB7 ${image.name}` : null
|
|
2216
2200
|
}
|
|
2217
2201
|
),
|
|
2218
|
-
/* @__PURE__ */ jsx11(
|
|
2202
|
+
/* @__PURE__ */ jsx11(VaultRow, { label: "Add to", children: /* @__PURE__ */ jsx11(
|
|
2219
2203
|
Select2,
|
|
2220
2204
|
{
|
|
2221
2205
|
value: target,
|
|
@@ -2229,7 +2213,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2229
2213
|
}
|
|
2230
2214
|
) }),
|
|
2231
2215
|
isNew ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
2232
|
-
/* @__PURE__ */ jsx11(
|
|
2216
|
+
/* @__PURE__ */ jsx11(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx11(
|
|
2233
2217
|
Field4,
|
|
2234
2218
|
{
|
|
2235
2219
|
className: "w-full",
|
|
@@ -2243,7 +2227,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2243
2227
|
"aria-label": "Name"
|
|
2244
2228
|
}
|
|
2245
2229
|
) }),
|
|
2246
|
-
/* @__PURE__ */ jsx11(
|
|
2230
|
+
/* @__PURE__ */ jsx11(VaultRow, { label: "Website", hint: websiteBad ? /* @__PURE__ */ jsx11("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ jsx11(Field4, { className: "w-full", type: "url", value: website, disabled: busy || created !== null, onChange: (e) => setWebsite(e.target.value), placeholder: "example.com", "aria-label": "Website", "aria-invalid": websiteBad || void 0 }) })
|
|
2247
2231
|
] }) : null
|
|
2248
2232
|
] }),
|
|
2249
2233
|
error ? /* @__PURE__ */ jsx11("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
|
|
@@ -2311,7 +2295,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
|
|
|
2311
2295
|
/* @__PURE__ */ jsx12("span", { className: "flex size-12 items-center justify-center rounded-full bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx12(ShieldGlyph, { className: "size-6" }) }),
|
|
2312
2296
|
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
|
|
2313
2297
|
/* @__PURE__ */ jsx12(Button9, { variant: "primary", icon: /* @__PURE__ */ jsx12(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
|
|
2314
|
-
] }) : groups.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ jsx12("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ jsx12("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ jsx12(
|
|
2298
|
+
] }) : groups.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ jsx12("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ jsx12("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ jsx12(VaultSection, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ jsx12(
|
|
2315
2299
|
OtpListRow,
|
|
2316
2300
|
{
|
|
2317
2301
|
port,
|
|
@@ -2405,7 +2389,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2405
2389
|
"Open login"
|
|
2406
2390
|
] }),
|
|
2407
2391
|
live.code ? /* @__PURE__ */ jsxs12(DropdownMenuItem2, { onSelect: () => live.code && void copy(live.code), children: [
|
|
2408
|
-
/* @__PURE__ */ jsx12(
|
|
2392
|
+
/* @__PURE__ */ jsx12(CopyIcon4, { className: "size-4" }),
|
|
2409
2393
|
"Copy code"
|
|
2410
2394
|
] }) : null,
|
|
2411
2395
|
canManage ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
@@ -2432,6 +2416,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2432
2416
|
import { useRef as useRef9, useState as useState14 } from "react";
|
|
2433
2417
|
import { Badge as Badge3, Button as Button10, DisclosureHeader, Field as Field5, SegmentedControl, Select as Select3, Switch } from "@ai-matrx/design-system/controls";
|
|
2434
2418
|
import { confirm as confirm3 } from "@ai-matrx/kit/confirm-opener";
|
|
2419
|
+
import { GlobeIcon as GlobeIcon2 } from "@ai-matrx/design-system/icons";
|
|
2435
2420
|
|
|
2436
2421
|
// src/fields/rules.ts
|
|
2437
2422
|
var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -2581,7 +2566,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2581
2566
|
const locked = !canEdit || busy !== null;
|
|
2582
2567
|
return /* @__PURE__ */ jsxs13(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2583
2568
|
!canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2584
|
-
/* @__PURE__ */ jsx13(
|
|
2569
|
+
/* @__PURE__ */ jsx13(VaultSection, { title: "Who can see it", children: /* @__PURE__ */ jsx13(VaultRow, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ jsx13(Badge3, { icon: /* @__PURE__ */ jsx13(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ jsx13(
|
|
2585
2570
|
SegmentedControl,
|
|
2586
2571
|
{
|
|
2587
2572
|
"aria-label": "Who can see it",
|
|
@@ -2590,8 +2575,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2590
2575
|
data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
|
|
2591
2576
|
}
|
|
2592
2577
|
) }) }),
|
|
2593
|
-
/* @__PURE__ */ jsxs13(
|
|
2594
|
-
/* @__PURE__ */ jsx13(
|
|
2578
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "Automation", children: [
|
|
2579
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ jsx13(
|
|
2595
2580
|
Field5,
|
|
2596
2581
|
{
|
|
2597
2582
|
ref: envRef,
|
|
@@ -2611,10 +2596,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2611
2596
|
}
|
|
2612
2597
|
}
|
|
2613
2598
|
) }),
|
|
2614
|
-
/* @__PURE__ */ jsx13(
|
|
2599
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
|
|
2615
2600
|
] }),
|
|
2616
|
-
/* @__PURE__ */ jsxs13(
|
|
2617
|
-
/* @__PURE__ */ jsx13(
|
|
2601
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "Field", children: [
|
|
2602
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Description", children: /* @__PURE__ */ jsx13(
|
|
2618
2603
|
Field5,
|
|
2619
2604
|
{
|
|
2620
2605
|
className: "w-full",
|
|
@@ -2630,8 +2615,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2630
2615
|
}
|
|
2631
2616
|
}
|
|
2632
2617
|
) }),
|
|
2633
|
-
/* @__PURE__ */ jsx13(
|
|
2634
|
-
/* @__PURE__ */ jsx13(
|
|
2618
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
|
|
2619
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
|
|
2635
2620
|
] }),
|
|
2636
2621
|
error ? /* @__PURE__ */ jsx13(Problem, { children: error }) : null
|
|
2637
2622
|
] });
|
|
@@ -2662,8 +2647,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2662
2647
|
const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
|
|
2663
2648
|
return /* @__PURE__ */ jsxs13(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2664
2649
|
!canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2665
|
-
/* @__PURE__ */ jsxs13(
|
|
2666
|
-
/* @__PURE__ */ jsx13(
|
|
2650
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "In the browser", children: [
|
|
2651
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ jsx13(
|
|
2667
2652
|
Select3,
|
|
2668
2653
|
{
|
|
2669
2654
|
"aria-label": "Website matching",
|
|
@@ -2673,13 +2658,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2673
2658
|
onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
|
|
2674
2659
|
}
|
|
2675
2660
|
) }),
|
|
2676
|
-
/* @__PURE__ */ jsx13(
|
|
2661
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
|
|
2677
2662
|
promotable.map((f) => /* @__PURE__ */ jsx13(
|
|
2678
|
-
|
|
2663
|
+
VaultRow,
|
|
2679
2664
|
{
|
|
2680
2665
|
label: f.label,
|
|
2681
2666
|
hint: quietHint("Encrypted, so the browser can\u2019t match it"),
|
|
2682
|
-
actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(
|
|
2667
|
+
actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(GlobeIcon2, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
|
|
2683
2668
|
children: /* @__PURE__ */ jsx13("span", { className: "text-muted-foreground", children: "Not a website yet" })
|
|
2684
2669
|
},
|
|
2685
2670
|
f.id
|
|
@@ -2687,8 +2672,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2687
2672
|
] }),
|
|
2688
2673
|
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5", children: [
|
|
2689
2674
|
/* @__PURE__ */ jsx13(DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
|
|
2690
|
-
advanced ? /* @__PURE__ */ jsx13(
|
|
2691
|
-
|
|
2675
|
+
advanced ? /* @__PURE__ */ jsx13(VaultSection, { children: item.fields.length === 0 ? /* @__PURE__ */ jsx13(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ jsx13(
|
|
2676
|
+
VaultRow,
|
|
2692
2677
|
{
|
|
2693
2678
|
label: f.label,
|
|
2694
2679
|
actions: /* @__PURE__ */ jsx13(Button10, { variant: "quiet", icon: /* @__PURE__ */ jsx13(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
|
|
@@ -2713,6 +2698,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2713
2698
|
import { createContext as createContext5, useContext as useContext5, useEffect as useEffect12, useRef as useRef10, useState as useState15 } from "react";
|
|
2714
2699
|
import { Popover, PopoverContent, PopoverTrigger, cn as cn7 } from "@ai-matrx/design-system";
|
|
2715
2700
|
import { Button as Button11, NumberStepper, SegmentedControl as SegmentedControl2, Select as Select4, Switch as Switch2 } from "@ai-matrx/design-system/controls";
|
|
2701
|
+
import { CopyIcon as CopyIcon5 } from "@ai-matrx/design-system/icons";
|
|
2716
2702
|
|
|
2717
2703
|
// src/generator/generate.ts
|
|
2718
2704
|
import {
|
|
@@ -2870,7 +2856,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
|
|
|
2870
2856
|
/* @__PURE__ */ jsxs14("div", { className: "flex min-h-7 items-start gap-1", children: [
|
|
2871
2857
|
/* @__PURE__ */ jsx14("code", { className: cn7("min-w-0 flex-1 break-all py-1 font-mono text-sm", candidate ? "text-foreground" : "text-muted-foreground"), "data-testid": "generated-value", children: candidate ? revealed ? candidate.value : MASK3 : "\u2014" }),
|
|
2872
2858
|
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: revealed ? /* @__PURE__ */ jsx14(EyeOffGlyph, {}) : /* @__PURE__ */ jsx14(EyeGlyph, {}), "aria-label": revealed ? "Hide" : "Reveal", disabled: !candidate, onClick: () => setRevealed((r) => !r) }),
|
|
2873
|
-
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(
|
|
2859
|
+
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(CopyIcon5, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
|
|
2874
2860
|
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
|
|
2875
2861
|
] }),
|
|
2876
2862
|
strength && candidate ? /* @__PURE__ */ jsxs14("p", { className: "text-xs", children: [
|
|
@@ -2997,6 +2983,7 @@ function useLocked(lock) {
|
|
|
2997
2983
|
}
|
|
2998
2984
|
|
|
2999
2985
|
// src/io/BackupPanel.tsx
|
|
2986
|
+
import { formatFileSize } from "@ai-matrx/kit/format";
|
|
3000
2987
|
import { useEffect as useEffect13, useRef as useRef11, useState as useState17 } from "react";
|
|
3001
2988
|
import { Button as Button13, Field as Field6, SegmentedControl as SegmentedControl3, Switch as Switch3 } from "@ai-matrx/design-system/controls";
|
|
3002
2989
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
@@ -3138,17 +3125,17 @@ function omissionText(o) {
|
|
|
3138
3125
|
return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
|
|
3139
3126
|
}
|
|
3140
3127
|
function Summary({ value }) {
|
|
3141
|
-
return /* @__PURE__ */ jsxs16(
|
|
3142
|
-
/* @__PURE__ */ jsx16(
|
|
3143
|
-
/* @__PURE__ */ jsx16(
|
|
3144
|
-
/* @__PURE__ */ jsx16(
|
|
3128
|
+
return /* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3129
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Credentials", children: value.record_count }),
|
|
3130
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Protected fields", children: value.field_count }),
|
|
3131
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${formatFileSize(value.attachment_bytes)}` : "0" })
|
|
3145
3132
|
] });
|
|
3146
3133
|
}
|
|
3147
3134
|
function Omissions({ omissions, accepted, onAccepted, verb }) {
|
|
3148
3135
|
if (omissions.length === 0) return null;
|
|
3149
|
-
return /* @__PURE__ */ jsxs16(
|
|
3150
|
-
omissions.map((o, i) => /* @__PURE__ */ jsx16(
|
|
3151
|
-
/* @__PURE__ */ jsx16(
|
|
3136
|
+
return /* @__PURE__ */ jsxs16(VaultSection, { title: "Left out", children: [
|
|
3137
|
+
omissions.map((o, i) => /* @__PURE__ */ jsx16(VaultRow, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ jsx16("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
|
|
3138
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ jsx16(Switch3, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
|
|
3152
3139
|
] });
|
|
3153
3140
|
}
|
|
3154
3141
|
function BackupPanel({ port, items, onClose, onChanged }) {
|
|
@@ -3283,7 +3270,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3283
3270
|
),
|
|
3284
3271
|
mode === "backup" ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3285
3272
|
/* @__PURE__ */ jsx16(
|
|
3286
|
-
|
|
3273
|
+
VaultSection,
|
|
3287
3274
|
{
|
|
3288
3275
|
title: `${selected.size} of ${plural(items.length, "credential")}`,
|
|
3289
3276
|
actions: /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
@@ -3302,13 +3289,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3302
3289
|
backup ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3303
3290
|
/* @__PURE__ */ jsx16(Summary, { value: backup }),
|
|
3304
3291
|
/* @__PURE__ */ jsx16(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
|
|
3305
|
-
/* @__PURE__ */ jsxs16(
|
|
3306
|
-
/* @__PURE__ */ jsx16(
|
|
3307
|
-
/* @__PURE__ */ jsx16(
|
|
3292
|
+
/* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3293
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
|
|
3294
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
|
|
3308
3295
|
] })
|
|
3309
3296
|
] }) : null
|
|
3310
|
-
] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(
|
|
3311
|
-
/* @__PURE__ */ jsxs16(
|
|
3297
|
+
] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3298
|
+
/* @__PURE__ */ jsxs16(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
|
|
3312
3299
|
/* @__PURE__ */ jsx16(Button13, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
|
|
3313
3300
|
/* @__PURE__ */ jsx16(
|
|
3314
3301
|
"input",
|
|
@@ -3324,11 +3311,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3324
3311
|
}
|
|
3325
3312
|
)
|
|
3326
3313
|
] }),
|
|
3327
|
-
/* @__PURE__ */ jsx16(
|
|
3314
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Passphrase", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
|
|
3328
3315
|
] }) : /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3329
3316
|
/* @__PURE__ */ jsx16(Summary, { value: restorePreview }),
|
|
3330
3317
|
!result ? /* @__PURE__ */ jsx16(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
|
|
3331
|
-
!result ? /* @__PURE__ */ jsx16("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ jsx16(
|
|
3318
|
+
!result ? /* @__PURE__ */ jsx16("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ jsx16(VaultSection, { title: `${result.created} restored \xB7 ${result.replayed} already \xB7 ${result.refused} refused \xB7 ${result.retryable_failure} to retry`, children: result.results.map((r) => /* @__PURE__ */ jsx16(VaultRow, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ jsxs16("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
|
|
3332
3319
|
RECORD_STATUS[r.status],
|
|
3333
3320
|
r.reason === "alias_conflict" ? " \xB7 name in use" : ""
|
|
3334
3321
|
] }) }, r.source_item_id)) })
|
|
@@ -3433,7 +3420,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3433
3420
|
] })
|
|
3434
3421
|
] }),
|
|
3435
3422
|
children: [
|
|
3436
|
-
/* @__PURE__ */ jsx17(
|
|
3423
|
+
/* @__PURE__ */ jsx17(VaultSection, { children: /* @__PURE__ */ jsx17(VaultRow, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ jsx17(
|
|
3437
3424
|
Select5,
|
|
3438
3425
|
{
|
|
3439
3426
|
value: profile,
|
|
@@ -3446,7 +3433,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3446
3433
|
}
|
|
3447
3434
|
) }) }),
|
|
3448
3435
|
/* @__PURE__ */ jsx17(
|
|
3449
|
-
|
|
3436
|
+
VaultSection,
|
|
3450
3437
|
{
|
|
3451
3438
|
title: `${selected.size} of ${plural(logins.length, "login")}`,
|
|
3452
3439
|
actions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
|
|
@@ -4517,13 +4504,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4517
4504
|
/* @__PURE__ */ jsx18(Button15, { variant: "primary", onClick: onClose, children: "Done" })
|
|
4518
4505
|
] });
|
|
4519
4506
|
return /* @__PURE__ */ jsxs18(Panel, { title: "Import", size: "xl", onClose, footer, children: [
|
|
4520
|
-
stage === "choose" ? /* @__PURE__ */ jsxs18(
|
|
4521
|
-
/* @__PURE__ */ jsx18(
|
|
4507
|
+
stage === "choose" ? /* @__PURE__ */ jsxs18(VaultSection, { children: [
|
|
4508
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ jsx18(Button15, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ jsx18(Select6, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
|
|
4522
4509
|
setSource(s);
|
|
4523
4510
|
setError(null);
|
|
4524
4511
|
} }) }),
|
|
4525
|
-
source === "env" ? /* @__PURE__ */ jsx18(
|
|
4526
|
-
/* @__PURE__ */ jsxs18(
|
|
4512
|
+
source === "env" ? /* @__PURE__ */ jsx18(VaultRow, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ jsx18(Textarea2, { mono: true, rows: 7, value: envText, autoComplete: "off", spellCheck: false, "aria-label": ".env text", placeholder: "OPENAI_API_KEY=sk-...\nDATABASE_URL=postgres://...", onChange: (e) => setEnvText(e.target.value) }) }) : null,
|
|
4513
|
+
/* @__PURE__ */ jsxs18(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
|
|
4527
4514
|
/* @__PURE__ */ jsx18(Button15, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
|
|
4528
4515
|
/* @__PURE__ */ jsx18(
|
|
4529
4516
|
"input",
|
|
@@ -4540,12 +4527,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4540
4527
|
}
|
|
4541
4528
|
)
|
|
4542
4529
|
] }),
|
|
4543
|
-
source === "env" ? /* @__PURE__ */ jsx18(
|
|
4530
|
+
source === "env" ? /* @__PURE__ */ jsx18(VaultRow, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ jsx18(Switch4, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
|
|
4544
4531
|
] }) : null,
|
|
4545
4532
|
stage === "review" && draft ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
|
|
4546
|
-
organizations.length > 0 ? /* @__PURE__ */ jsx18(
|
|
4533
|
+
organizations.length > 0 ? /* @__PURE__ */ jsx18(VaultSection, { children: /* @__PURE__ */ jsx18(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx18(Select6, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
|
|
4547
4534
|
/* @__PURE__ */ jsx18(
|
|
4548
|
-
|
|
4535
|
+
VaultSection,
|
|
4549
4536
|
{
|
|
4550
4537
|
title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
|
|
4551
4538
|
actions: /* @__PURE__ */ jsxs18(Fragment11, { children: [
|
|
@@ -4573,11 +4560,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4573
4560
|
)
|
|
4574
4561
|
}
|
|
4575
4562
|
),
|
|
4576
|
-
draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ jsx18(
|
|
4563
|
+
draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ jsx18(VaultSection, { children: /* @__PURE__ */ jsx18(VaultRow, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ jsx18(Switch4, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
|
|
4577
4564
|
draft.kind === "file" ? /* @__PURE__ */ jsx18(Notices, { draft }) : null,
|
|
4578
|
-
draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(
|
|
4579
|
-
/* @__PURE__ */ jsx18(
|
|
4580
|
-
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(
|
|
4565
|
+
draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(VaultSection, { children: [
|
|
4566
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ jsx18(Switch4, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
|
|
4567
|
+
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(VaultRow, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ jsx18(
|
|
4581
4568
|
Select6,
|
|
4582
4569
|
{
|
|
4583
4570
|
value: draft.mapping[index] ?? "keep",
|
|
@@ -4589,16 +4576,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4589
4576
|
] }) }) : null,
|
|
4590
4577
|
ambiguous ? /* @__PURE__ */ jsx18(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
|
|
4591
4578
|
] }) : null,
|
|
4592
|
-
stage === "done" && done ? /* @__PURE__ */ jsxs18(
|
|
4593
|
-
/* @__PURE__ */ jsx18(
|
|
4594
|
-
/* @__PURE__ */ jsx18(
|
|
4595
|
-
/* @__PURE__ */ jsx18(
|
|
4596
|
-
done.untried.length > 0 ? /* @__PURE__ */ jsx18(
|
|
4597
|
-
done.withOtp > 0 ? /* @__PURE__ */ jsx18(
|
|
4579
|
+
stage === "done" && done ? /* @__PURE__ */ jsxs18(VaultSection, { title: "Result", children: [
|
|
4580
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Created", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.created.length }) }),
|
|
4581
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Skipped", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.skipped }) }),
|
|
4582
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx18("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
|
|
4583
|
+
done.untried.length > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.untried.length }) }) : null,
|
|
4584
|
+
done.withOtp > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Codes", children: /* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground", children: [
|
|
4598
4585
|
plural(done.withOtp, "login"),
|
|
4599
4586
|
" still need the one-time password added."
|
|
4600
4587
|
] }) }) : null,
|
|
4601
|
-
done.failed.map((f) => /* @__PURE__ */ jsx18(
|
|
4588
|
+
done.failed.map((f) => /* @__PURE__ */ jsx18(VaultRow, { label: f.title, children: /* @__PURE__ */ jsx18("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
|
|
4602
4589
|
] }) : null,
|
|
4603
4590
|
/* @__PURE__ */ jsx18(ErrorLine, { message: error })
|
|
4604
4591
|
] });
|
|
@@ -4658,11 +4645,13 @@ import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCo
|
|
|
4658
4645
|
import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
|
|
4659
4646
|
|
|
4660
4647
|
// src/activity/FilesSection.tsx
|
|
4648
|
+
import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
|
|
4661
4649
|
import { useRef as useRef13, useState as useState20 } from "react";
|
|
4662
4650
|
import { Badge as Badge5, Button as Button16, Field as Field7, SegmentedControl as SegmentedControl4 } from "@ai-matrx/design-system/controls";
|
|
4663
4651
|
import { cn as cn9 } from "@ai-matrx/design-system";
|
|
4664
4652
|
import { confirm as confirm6 } from "@ai-matrx/kit/confirm-opener";
|
|
4665
4653
|
import { downloadFile as downloadFile3 } from "@ai-matrx/kit/download";
|
|
4654
|
+
import { DownloadIcon } from "@ai-matrx/design-system/icons";
|
|
4666
4655
|
import { Fragment as Fragment12, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4667
4656
|
var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
4668
4657
|
var TOO_BIG = "Files over 25 MB can't be stored.";
|
|
@@ -4721,7 +4710,7 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4721
4710
|
onDragLeave: canEdit ? () => setDragging(false) : void 0,
|
|
4722
4711
|
onDrop: canEdit ? drop : void 0,
|
|
4723
4712
|
children: /* @__PURE__ */ jsxs19(
|
|
4724
|
-
|
|
4713
|
+
VaultSection,
|
|
4725
4714
|
{
|
|
4726
4715
|
title: "Files",
|
|
4727
4716
|
actions: canEdit ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
|
|
@@ -4732,11 +4721,11 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4732
4721
|
} }) : null,
|
|
4733
4722
|
item.attachments.map(
|
|
4734
4723
|
(a) => canEdit ? /* @__PURE__ */ jsx20(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ jsx20(
|
|
4735
|
-
|
|
4724
|
+
VaultRow,
|
|
4736
4725
|
{
|
|
4737
4726
|
label: a.label,
|
|
4738
4727
|
hint: a.description || void 0,
|
|
4739
|
-
actions: a.handling === "sealed" ? /* @__PURE__ */ jsx20(Badge5, { icon: /* @__PURE__ */ jsx20(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(
|
|
4728
|
+
actions: a.handling === "sealed" ? /* @__PURE__ */ jsx20(Badge5, { icon: /* @__PURE__ */ jsx20(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
|
|
4740
4729
|
children: /* @__PURE__ */ jsx20(FileName, { file: a })
|
|
4741
4730
|
},
|
|
4742
4731
|
a.id
|
|
@@ -4762,12 +4751,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4762
4751
|
}
|
|
4763
4752
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4764
4753
|
/* @__PURE__ */ jsx20(
|
|
4765
|
-
|
|
4754
|
+
VaultRow,
|
|
4766
4755
|
{
|
|
4767
4756
|
label: a.label,
|
|
4768
4757
|
hint: a.description || void 0,
|
|
4769
4758
|
actions: /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4770
|
-
canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(
|
|
4759
|
+
canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
|
|
4771
4760
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
|
|
4772
4761
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
|
|
4773
4762
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
|
|
@@ -4798,7 +4787,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4798
4787
|
function FileName({ file }) {
|
|
4799
4788
|
return /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4800
4789
|
/* @__PURE__ */ jsx20("span", { className: "truncate", children: file.fileName }),
|
|
4801
|
-
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4790
|
+
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.sizeBytes) })
|
|
4802
4791
|
] });
|
|
4803
4792
|
}
|
|
4804
4793
|
function Protection({ value, locked, onChange }) {
|
|
@@ -4821,13 +4810,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
|
|
|
4821
4810
|
await onAdd({ label: label.trim(), description: description.trim() || null, handling });
|
|
4822
4811
|
}
|
|
4823
4812
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4824
|
-
/* @__PURE__ */ jsx20(
|
|
4813
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "New file", children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4825
4814
|
/* @__PURE__ */ jsx20("span", { className: "truncate", children: file.name }),
|
|
4826
|
-
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4815
|
+
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.size) })
|
|
4827
4816
|
] }) }),
|
|
4828
|
-
/* @__PURE__ */ jsx20(
|
|
4829
|
-
/* @__PURE__ */ jsx20(
|
|
4830
|
-
/* @__PURE__ */ jsx20(
|
|
4817
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4818
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
|
|
4819
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: false, onChange: setHandling }) }),
|
|
4831
4820
|
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4832
4821
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4833
4822
|
/* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
|
|
@@ -4845,10 +4834,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
|
|
|
4845
4834
|
await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
|
|
4846
4835
|
}
|
|
4847
4836
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4848
|
-
/* @__PURE__ */ jsx20(
|
|
4849
|
-
/* @__PURE__ */ jsx20(
|
|
4850
|
-
/* @__PURE__ */ jsx20(
|
|
4851
|
-
/* @__PURE__ */ jsx20(
|
|
4837
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4838
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
|
|
4839
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "File name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
|
|
4840
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
|
|
4852
4841
|
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4853
4842
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4854
4843
|
/* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
|
|
@@ -4867,6 +4856,7 @@ function confirmSeal(label) {
|
|
|
4867
4856
|
// src/fields/RecoveryCodesRow.tsx
|
|
4868
4857
|
import { useState as useState21 } from "react";
|
|
4869
4858
|
import { Badge as Badge6, Button as Button17, Textarea as Textarea3 } from "@ai-matrx/design-system/controls";
|
|
4859
|
+
import { CopyIcon as CopyIcon6 } from "@ai-matrx/design-system/icons";
|
|
4870
4860
|
import { Fragment as Fragment13, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4871
4861
|
var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
4872
4862
|
var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
@@ -4907,7 +4897,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4907
4897
|
};
|
|
4908
4898
|
if (draft !== null) {
|
|
4909
4899
|
return /* @__PURE__ */ jsxs20(
|
|
4910
|
-
|
|
4900
|
+
VaultRow,
|
|
4911
4901
|
{
|
|
4912
4902
|
label: "Recovery codes",
|
|
4913
4903
|
top: true,
|
|
@@ -4927,7 +4917,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4927
4917
|
}
|
|
4928
4918
|
if (!field) {
|
|
4929
4919
|
if (!canEdit) return null;
|
|
4930
|
-
return /* @__PURE__ */ jsx21(
|
|
4920
|
+
return /* @__PURE__ */ jsx21(VaultRow, { label: "Recovery codes", actions: /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "None" }) });
|
|
4931
4921
|
}
|
|
4932
4922
|
const sealed = field.handling === "sealed";
|
|
4933
4923
|
const canSee = !sealed && item.capabilities.canReveal;
|
|
@@ -4949,7 +4939,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4949
4939
|
});
|
|
4950
4940
|
};
|
|
4951
4941
|
return /* @__PURE__ */ jsx21(
|
|
4952
|
-
|
|
4942
|
+
VaultRow,
|
|
4953
4943
|
{
|
|
4954
4944
|
label: "Recovery codes",
|
|
4955
4945
|
top: codes !== null,
|
|
@@ -4960,7 +4950,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4960
4950
|
children: sealed ? /* @__PURE__ */ jsx21(Badge6, { icon: /* @__PURE__ */ jsx21(LockGlyph, {}), children: "Sealed" }) : codes ? /* @__PURE__ */ jsxs20("ul", { className: "flex flex-col gap-0.5", "aria-label": "Recovery codes", children: [
|
|
4961
4951
|
codes.map((code, i) => /* @__PURE__ */ jsxs20("li", { className: "flex min-h-7 items-center gap-1", children: [
|
|
4962
4952
|
/* @__PURE__ */ jsx21("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
|
|
4963
|
-
/* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(
|
|
4953
|
+
/* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CopyIcon6, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
|
|
4964
4954
|
canEdit ? /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
|
|
4965
4955
|
] }, `${i}-${code}`)),
|
|
4966
4956
|
error ? /* @__PURE__ */ jsx21("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
|
|
@@ -4969,33 +4959,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4969
4959
|
);
|
|
4970
4960
|
}
|
|
4971
4961
|
|
|
4962
|
+
// src/ItemPane.tsx
|
|
4963
|
+
import { HistoryIcon, SettingsIcon, UsersIcon as UsersIcon2 } from "@ai-matrx/design-system/icons";
|
|
4964
|
+
import { dropKeptDraft, keepDraft, readKeptDraft } from "@ai-matrx/kit/drafts";
|
|
4965
|
+
|
|
4972
4966
|
// src/draft-keep.ts
|
|
4973
4967
|
var PREFIX = "matrx.vault.draft:";
|
|
4974
4968
|
function draftKey(itemId, definitionKey) {
|
|
4975
4969
|
return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
|
|
4976
4970
|
}
|
|
4977
|
-
function
|
|
4978
|
-
|
|
4979
|
-
try {
|
|
4980
|
-
globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
|
|
4981
|
-
} catch {
|
|
4982
|
-
}
|
|
4983
|
-
}
|
|
4984
|
-
function readKeptDraft(key, basedOn) {
|
|
4985
|
-
try {
|
|
4986
|
-
const raw = globalThis.sessionStorage?.getItem(key);
|
|
4987
|
-
if (!raw) return null;
|
|
4988
|
-
const kept = JSON.parse(raw);
|
|
4989
|
-
return kept.basedOn === basedOn ? kept.draft : null;
|
|
4990
|
-
} catch {
|
|
4991
|
-
return null;
|
|
4992
|
-
}
|
|
4993
|
-
}
|
|
4994
|
-
function dropKeptDraft(key) {
|
|
4995
|
-
try {
|
|
4996
|
-
globalThis.sessionStorage?.removeItem(key);
|
|
4997
|
-
} catch {
|
|
4998
|
-
}
|
|
4971
|
+
function keptFieldsOf(d) {
|
|
4972
|
+
return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
|
|
4999
4973
|
}
|
|
5000
4974
|
|
|
5001
4975
|
// src/extension/page-logic.ts
|
|
@@ -5142,6 +5116,7 @@ import { useEffect as useEffect15, useState as useState25 } from "react";
|
|
|
5142
5116
|
import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
|
|
5143
5117
|
import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select8 } from "@ai-matrx/design-system/controls";
|
|
5144
5118
|
import { cn as cn11 } from "@ai-matrx/design-system";
|
|
5119
|
+
import { UsersIcon } from "@ai-matrx/design-system/icons";
|
|
5145
5120
|
|
|
5146
5121
|
// src/sharing/logic.ts
|
|
5147
5122
|
var LEVEL_OPTIONS = [
|
|
@@ -5173,7 +5148,7 @@ function copyRefusal(message2) {
|
|
|
5173
5148
|
return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
|
|
5174
5149
|
}
|
|
5175
5150
|
var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
|
|
5176
|
-
function
|
|
5151
|
+
function itemMoveConsequence(item, to) {
|
|
5177
5152
|
if (item.authenticator) return "One-time password stays behind; set it up again";
|
|
5178
5153
|
return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
|
|
5179
5154
|
}
|
|
@@ -5263,7 +5238,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5263
5238
|
const to = destinationOf(moveChoice.value);
|
|
5264
5239
|
const ok = await confirm7({
|
|
5265
5240
|
title: `Move to ${moveChoice.label}?`,
|
|
5266
|
-
description: `"${item.name}" stays the same item, so everything using it keeps working. ${
|
|
5241
|
+
description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
|
|
5267
5242
|
confirmLabel: "Move"
|
|
5268
5243
|
});
|
|
5269
5244
|
if (!ok) return;
|
|
@@ -5299,17 +5274,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5299
5274
|
/* @__PURE__ */ jsx24(StatusLine, { error, notice }),
|
|
5300
5275
|
/* @__PURE__ */ jsx24(Button19, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
|
|
5301
5276
|
] }),
|
|
5302
|
-
children: nothing ? /* @__PURE__ */ jsx24(
|
|
5277
|
+
children: nothing ? /* @__PURE__ */ jsx24(VaultSection, { children: /* @__PURE__ */ jsx24(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs22(VaultSection, { children: [
|
|
5303
5278
|
canMove && moves.length > 0 ? /* @__PURE__ */ jsx24(
|
|
5304
|
-
|
|
5279
|
+
VaultRow,
|
|
5305
5280
|
{
|
|
5306
5281
|
label: "Move to",
|
|
5307
|
-
hint: moveChoice ?
|
|
5282
|
+
hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
|
|
5308
5283
|
actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
|
|
5309
5284
|
children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
|
|
5310
5285
|
}
|
|
5311
5286
|
) : null,
|
|
5312
|
-
canGive ? /* @__PURE__ */ jsx24(
|
|
5287
|
+
canGive ? /* @__PURE__ */ jsx24(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx24(Button19, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx24(
|
|
5313
5288
|
Field8,
|
|
5314
5289
|
{
|
|
5315
5290
|
className: "w-full",
|
|
@@ -5323,7 +5298,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5323
5298
|
onChange: (e) => setEmail(e.target.value)
|
|
5324
5299
|
}
|
|
5325
5300
|
) }) : null,
|
|
5326
|
-
canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(
|
|
5301
|
+
canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
|
|
5327
5302
|
] })
|
|
5328
5303
|
}
|
|
5329
5304
|
);
|
|
@@ -5405,7 +5380,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5405
5380
|
}
|
|
5406
5381
|
};
|
|
5407
5382
|
if (!item.capabilities.canManage) {
|
|
5408
|
-
return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(
|
|
5383
|
+
return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(VaultSection, { children: /* @__PURE__ */ jsx25(Empty, { children: "Only the owner can change who has access." }) }) });
|
|
5409
5384
|
}
|
|
5410
5385
|
return /* @__PURE__ */ jsxs23(
|
|
5411
5386
|
Panel,
|
|
@@ -5418,9 +5393,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5418
5393
|
/* @__PURE__ */ jsx25(Button20, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
|
|
5419
5394
|
] }),
|
|
5420
5395
|
children: [
|
|
5421
|
-
/* @__PURE__ */ jsxs23(
|
|
5396
|
+
/* @__PURE__ */ jsxs23(VaultSection, { title: "Who has access", children: [
|
|
5422
5397
|
isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
|
|
5423
|
-
isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph:
|
|
5398
|
+
isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ jsx25(
|
|
5424
5399
|
Select8,
|
|
5425
5400
|
{
|
|
5426
5401
|
variant: "inline",
|
|
@@ -5481,7 +5456,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
|
|
|
5481
5456
|
const [level, setLevel] = useState25("use");
|
|
5482
5457
|
const chosen = open.find((o) => o.id === target);
|
|
5483
5458
|
if (item.owner.kind !== "me") return null;
|
|
5484
|
-
return /* @__PURE__ */ jsx25(
|
|
5459
|
+
return /* @__PURE__ */ jsx25(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs23(Fragment14, { children: [
|
|
5485
5460
|
/* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
|
|
5486
5461
|
/* @__PURE__ */ jsx25(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
5487
5462
|
/* @__PURE__ */ jsx25(Select8, { className: "min-w-0 flex-1", "aria-label": "Organization", value: target || "__none__", onValueChange: (v) => setTarget(v === "__none__" ? "" : v), options: [{ value: "__none__", label: "Choose an organization" }, ...open.map((o) => ({ value: o.id, label: o.name }))] }),
|
|
@@ -5531,7 +5506,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
|
|
|
5531
5506
|
const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
|
|
5532
5507
|
if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
|
|
5533
5508
|
};
|
|
5534
|
-
return /* @__PURE__ */ jsxs23(
|
|
5509
|
+
return /* @__PURE__ */ jsxs23(VaultSection, { title: `${organizationName} vault access`, children: [
|
|
5535
5510
|
loadError ? /* @__PURE__ */ jsx25(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ jsx25(RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ jsx25(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ jsx25(
|
|
5536
5511
|
Select8,
|
|
5537
5512
|
{
|
|
@@ -5607,7 +5582,7 @@ function ItemPane(props) {
|
|
|
5607
5582
|
if (was && was.id === id && was.mode === mode && editing) {
|
|
5608
5583
|
setDraft((d) => rebaseDraft(was.base, base, d));
|
|
5609
5584
|
} else {
|
|
5610
|
-
const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
|
|
5585
|
+
const kept = editing ? readKeptDraft(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
|
|
5611
5586
|
setDraft(kept ? { ...base, ...kept } : base);
|
|
5612
5587
|
setTagsText((kept ?? base).tags.join(", "));
|
|
5613
5588
|
setError(null);
|
|
@@ -5622,7 +5597,7 @@ function ItemPane(props) {
|
|
|
5622
5597
|
useEffect16(() => onDirty(dirty), [dirty, onDirty]);
|
|
5623
5598
|
const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
|
|
5624
5599
|
useEffect16(() => {
|
|
5625
|
-
if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new"
|
|
5600
|
+
if (editing && dirty) keepDraft(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
|
|
5626
5601
|
else if (!editing) dropKeptDraft(keepKey);
|
|
5627
5602
|
}, [editing, dirty, draft, keepKey, item?.updatedAt]);
|
|
5628
5603
|
useEffect16(() => {
|
|
@@ -5709,7 +5684,7 @@ function ItemPane(props) {
|
|
|
5709
5684
|
const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
|
|
5710
5685
|
const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
|
|
5711
5686
|
const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
|
|
5712
|
-
const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx26(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx26(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx26(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx26(BuildingGlyph, {}) : /* @__PURE__ */ jsx26(
|
|
5687
|
+
const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx26(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx26(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx26(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx26(BuildingGlyph, {}) : /* @__PURE__ */ jsx26(UsersIcon2, {}) } : null;
|
|
5713
5688
|
const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
|
|
5714
5689
|
const descriptionVisible = showDescription || draft.description !== "";
|
|
5715
5690
|
const header = /* @__PURE__ */ jsxs24("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-5", children: [
|
|
@@ -5766,7 +5741,7 @@ function ItemPane(props) {
|
|
|
5766
5741
|
"Send securely"
|
|
5767
5742
|
] }) : null,
|
|
5768
5743
|
/* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
|
|
5769
|
-
/* @__PURE__ */ jsx26(
|
|
5744
|
+
/* @__PURE__ */ jsx26(HistoryIcon, { className: "size-4" }),
|
|
5770
5745
|
"Password history"
|
|
5771
5746
|
] }),
|
|
5772
5747
|
/* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
|
|
@@ -5774,7 +5749,7 @@ function ItemPane(props) {
|
|
|
5774
5749
|
"Activity"
|
|
5775
5750
|
] }),
|
|
5776
5751
|
canEdit ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
|
|
5777
|
-
/* @__PURE__ */ jsx26(
|
|
5752
|
+
/* @__PURE__ */ jsx26(SettingsIcon, { className: "size-4" }),
|
|
5778
5753
|
"Settings"
|
|
5779
5754
|
] }) : null,
|
|
5780
5755
|
canManage ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
@@ -5794,8 +5769,8 @@ function ItemPane(props) {
|
|
|
5794
5769
|
error ? /* @__PURE__ */ jsx26("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
|
|
5795
5770
|
notice && !editing ? /* @__PURE__ */ jsx26("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
|
|
5796
5771
|
/* @__PURE__ */ jsx26("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx26("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-4 sm:px-6 sm:py-6", children: editing ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5797
|
-
/* @__PURE__ */ jsxs24(
|
|
5798
|
-
mode === "new" ? /* @__PURE__ */ jsx26(
|
|
5772
|
+
/* @__PURE__ */ jsxs24(VaultSection, { children: [
|
|
5773
|
+
mode === "new" ? /* @__PURE__ */ jsx26(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx26(
|
|
5799
5774
|
OptionCombobox,
|
|
5800
5775
|
{
|
|
5801
5776
|
value: owner,
|
|
@@ -5816,7 +5791,7 @@ function ItemPane(props) {
|
|
|
5816
5791
|
/* @__PURE__ */ jsx26(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
|
|
5817
5792
|
mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5818
5793
|
/* @__PURE__ */ jsx26(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
|
|
5819
|
-
declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(
|
|
5794
|
+
declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ jsx26(Switch5, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
|
|
5820
5795
|
] }) : null,
|
|
5821
5796
|
declared.map((f) => {
|
|
5822
5797
|
const existing = item?.fields.find((x) => x.key === f.key);
|
|
@@ -5836,7 +5811,7 @@ function ItemPane(props) {
|
|
|
5836
5811
|
actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5837
5812
|
hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
|
|
5838
5813
|
secretKind ? /* @__PURE__ */ jsx26(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
|
|
5839
|
-
existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(
|
|
5814
|
+
existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
|
|
5840
5815
|
] })
|
|
5841
5816
|
},
|
|
5842
5817
|
f.key
|
|
@@ -5854,7 +5829,7 @@ function ItemPane(props) {
|
|
|
5854
5829
|
removeLabel: `Delete ${f.label}`,
|
|
5855
5830
|
actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5856
5831
|
f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
|
|
5857
|
-
/* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(
|
|
5832
|
+
/* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
|
|
5858
5833
|
] })
|
|
5859
5834
|
},
|
|
5860
5835
|
f.id
|
|
@@ -5887,9 +5862,9 @@ function ItemPane(props) {
|
|
|
5887
5862
|
/* @__PURE__ */ jsx26(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
|
|
5888
5863
|
item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5889
5864
|
] }),
|
|
5890
|
-
/* @__PURE__ */ jsx26(
|
|
5865
|
+
/* @__PURE__ */ jsx26(VaultSection, { children: /* @__PURE__ */ jsx26(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
|
|
5891
5866
|
/* @__PURE__ */ jsxs24(
|
|
5892
|
-
|
|
5867
|
+
VaultSection,
|
|
5893
5868
|
{
|
|
5894
5869
|
title: "More",
|
|
5895
5870
|
actions: /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
|
|
@@ -5923,7 +5898,7 @@ function ItemPane(props) {
|
|
|
5923
5898
|
),
|
|
5924
5899
|
filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: true }) : null
|
|
5925
5900
|
] }) : item ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5926
|
-
/* @__PURE__ */ jsxs24(
|
|
5901
|
+
/* @__PURE__ */ jsxs24(VaultSection, { children: [
|
|
5927
5902
|
declared.map((f) => {
|
|
5928
5903
|
if (f.storage === "metadata") {
|
|
5929
5904
|
const v = metaValue(f.key);
|
|
@@ -5938,10 +5913,10 @@ function ItemPane(props) {
|
|
|
5938
5913
|
item.authenticator ? /* @__PURE__ */ jsx26(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ jsx26(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
|
|
5939
5914
|
!item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5940
5915
|
] }),
|
|
5941
|
-
/* @__PURE__ */ jsx26(
|
|
5942
|
-
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(
|
|
5916
|
+
/* @__PURE__ */ jsx26(VaultSection, { children: item.notes ? /* @__PURE__ */ jsx26(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ jsx26(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
|
|
5917
|
+
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(VaultSection, { title: "More", children: [
|
|
5943
5918
|
item.description ? /* @__PURE__ */ jsx26(PlainRow, { label: "Description", value: item.description }) : null,
|
|
5944
|
-
item.tags.length > 0 ? /* @__PURE__ */ jsx26(
|
|
5919
|
+
item.tags.length > 0 ? /* @__PURE__ */ jsx26(VaultRow, { label: "Tags", children: /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ jsx26("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
|
|
5945
5920
|
viewCustom.map((c) => /* @__PURE__ */ jsx26(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
|
|
5946
5921
|
] }) : null,
|
|
5947
5922
|
filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
|
|
@@ -6189,13 +6164,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
|
|
|
6189
6164
|
refused ? null : /* @__PURE__ */ jsx28(Button23, { variant: "primary", icon: /* @__PURE__ */ jsx28(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
|
|
6190
6165
|
] }),
|
|
6191
6166
|
children: [
|
|
6192
|
-
loading ? /* @__PURE__ */ jsx28(
|
|
6193
|
-
/* @__PURE__ */ jsx28(
|
|
6194
|
-
/* @__PURE__ */ jsx28(
|
|
6195
|
-
preview.passkeys === 1 ? /* @__PURE__ */ jsx28(
|
|
6196
|
-
/* @__PURE__ */ jsx28(
|
|
6197
|
-
preview.priorWasDisabled ? /* @__PURE__ */ jsx28(
|
|
6198
|
-
] }) : preview ? /* @__PURE__ */ jsx28(
|
|
6167
|
+
loading ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(VaultSection, { title: "Comes back", children: [
|
|
6168
|
+
/* @__PURE__ */ jsx28(VaultRow, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
|
|
6169
|
+
/* @__PURE__ */ jsx28(VaultRow, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
|
|
6170
|
+
preview.passkeys === 1 ? /* @__PURE__ */ jsx28(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
|
|
6171
|
+
/* @__PURE__ */ jsx28(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
|
|
6172
|
+
preview.priorWasDisabled ? /* @__PURE__ */ jsx28(VaultRow, { label: "Before", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
|
|
6173
|
+
] }) : preview ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
|
|
6199
6174
|
error ? /* @__PURE__ */ jsx28("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
|
|
6200
6175
|
]
|
|
6201
6176
|
}
|
|
@@ -6227,7 +6202,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6227
6202
|
};
|
|
6228
6203
|
return /* @__PURE__ */ jsxs27("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
|
|
6229
6204
|
header,
|
|
6230
|
-
/* @__PURE__ */ jsx29(
|
|
6205
|
+
/* @__PURE__ */ jsx29(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ jsx29(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
|
|
6231
6206
|
// A list row, not a field row: the name gets the whole width (on a phone a label column
|
|
6232
6207
|
// left "Vau…" for every row), the deletion date sits under it.
|
|
6233
6208
|
/* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
|
|
@@ -6247,6 +6222,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6247
6222
|
import { useMemo as useMemo4, useState as useState30 } from "react";
|
|
6248
6223
|
import { cn as cn14 } from "@ai-matrx/design-system";
|
|
6249
6224
|
import { Button as Button25, Field as Field10, SearchField as SearchField2 } from "@ai-matrx/design-system/controls";
|
|
6225
|
+
import { GlobeIcon as GlobeIcon3 } from "@ai-matrx/design-system/icons";
|
|
6250
6226
|
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
6251
6227
|
function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
6252
6228
|
const [search, setSearch] = useState30("");
|
|
@@ -6281,7 +6257,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
|
6281
6257
|
"aria-label": "Website address",
|
|
6282
6258
|
inputMode: "url",
|
|
6283
6259
|
autoFocus: true,
|
|
6284
|
-
icon: /* @__PURE__ */ jsx30(
|
|
6260
|
+
icon: /* @__PURE__ */ jsx30(GlobeIcon3, {})
|
|
6285
6261
|
}
|
|
6286
6262
|
),
|
|
6287
6263
|
guess && login ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
|
|
@@ -6531,9 +6507,9 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6531
6507
|
] }),
|
|
6532
6508
|
children: [
|
|
6533
6509
|
remedy ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
|
|
6534
|
-
/* @__PURE__ */ jsxs29(
|
|
6535
|
-
/* @__PURE__ */ jsx31(
|
|
6536
|
-
/* @__PURE__ */ jsx31(
|
|
6510
|
+
/* @__PURE__ */ jsxs29(VaultSection, { title: "Recipient", children: [
|
|
6511
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Email", children: /* @__PURE__ */ jsx31(Field11, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
|
|
6512
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx31(
|
|
6537
6513
|
Field11,
|
|
6538
6514
|
{
|
|
6539
6515
|
type: "tel",
|
|
@@ -6549,8 +6525,8 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6549
6525
|
className: "w-full"
|
|
6550
6526
|
}
|
|
6551
6527
|
) }),
|
|
6552
|
-
/* @__PURE__ */ jsx31(
|
|
6553
|
-
plan && !plan.same ? /* @__PURE__ */ jsx31(
|
|
6528
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ jsx31(Field11, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
|
|
6529
|
+
plan && !plan.same ? /* @__PURE__ */ jsx31(VaultRow, { label: "Link by", children: /* @__PURE__ */ jsx31(
|
|
6554
6530
|
SegmentedControl5,
|
|
6555
6531
|
{
|
|
6556
6532
|
"aria-label": "Send the link by",
|
|
@@ -6562,26 +6538,26 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6562
6538
|
]
|
|
6563
6539
|
}
|
|
6564
6540
|
) }) : null,
|
|
6565
|
-
email.trim() ? /* @__PURE__ */ jsx31(
|
|
6541
|
+
email.trim() ? /* @__PURE__ */ jsx31(VaultRow, { label: "Delivery", children: /* @__PURE__ */ jsx31("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
|
|
6566
6542
|
] }),
|
|
6567
|
-
/* @__PURE__ */ jsx31(
|
|
6543
|
+
/* @__PURE__ */ jsx31(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ jsxs29("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
|
|
6568
6544
|
/* @__PURE__ */ jsx31(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
|
|
6569
6545
|
/* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
|
|
6570
6546
|
!f.available && f.reason ? /* @__PURE__ */ jsx31("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
|
|
6571
6547
|
] }, f.key)) }),
|
|
6572
|
-
/* @__PURE__ */ jsx31(
|
|
6573
|
-
options ? /* @__PURE__ */ jsxs29(
|
|
6574
|
-
/* @__PURE__ */ jsx31(
|
|
6575
|
-
/* @__PURE__ */ jsx31(
|
|
6548
|
+
/* @__PURE__ */ jsx31(VaultSection, { title: "Message", children: /* @__PURE__ */ jsx31("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ jsx31(Textarea4, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
|
|
6549
|
+
options ? /* @__PURE__ */ jsxs29(VaultSection, { title: "Link", children: [
|
|
6550
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
|
|
6551
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Link expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
|
|
6576
6552
|
"After ",
|
|
6577
6553
|
lifetimeWords(options.linkMinutes)
|
|
6578
6554
|
] }) }),
|
|
6579
|
-
/* @__PURE__ */ jsx31(
|
|
6555
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Code expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
|
|
6580
6556
|
"After ",
|
|
6581
6557
|
lifetimeWords(options.codeMinutes)
|
|
6582
6558
|
] }) })
|
|
6583
6559
|
] }) : null,
|
|
6584
|
-
sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(
|
|
6560
|
+
sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ jsxs29(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
|
|
6585
6561
|
/* @__PURE__ */ jsx31(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
|
|
6586
6562
|
row.status === "pending" ? /* @__PURE__ */ jsx31(Button26, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
|
|
6587
6563
|
] }, row.id)) }) : null
|
|
@@ -6723,10 +6699,10 @@ function DevicesPanel({ port, onClose }) {
|
|
|
6723
6699
|
};
|
|
6724
6700
|
return /* @__PURE__ */ jsxs30(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
|
|
6725
6701
|
/* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
|
|
6726
|
-
/* @__PURE__ */ jsx32(
|
|
6702
|
+
/* @__PURE__ */ jsx32(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
|
|
6727
6703
|
const off = isRevoked(device);
|
|
6728
6704
|
return /* @__PURE__ */ jsx32(
|
|
6729
|
-
|
|
6705
|
+
VaultRow,
|
|
6730
6706
|
{
|
|
6731
6707
|
label: off ? "Turned off" : "Can fill",
|
|
6732
6708
|
hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
|
|
@@ -6814,18 +6790,18 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6814
6790
|
/* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
|
|
6815
6791
|
canApprove ? /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
|
|
6816
6792
|
] });
|
|
6817
|
-
return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(
|
|
6793
|
+
return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(VaultSection, { children: /* @__PURE__ */ jsxs30(Empty, { children: [
|
|
6818
6794
|
"This link names no key. Start again from ",
|
|
6819
6795
|
where,
|
|
6820
6796
|
"."
|
|
6821
6797
|
] }) }) : /* @__PURE__ */ jsxs30(Fragment17, { children: [
|
|
6822
|
-
/* @__PURE__ */ jsxs30(
|
|
6823
|
-
/* @__PURE__ */ jsx32(
|
|
6824
|
-
name ? /* @__PURE__ */ jsx32(
|
|
6825
|
-
/* @__PURE__ */ jsx32(
|
|
6798
|
+
/* @__PURE__ */ jsxs30(VaultSection, { title: "What is asking", children: [
|
|
6799
|
+
/* @__PURE__ */ jsx32(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
|
|
6800
|
+
name ? /* @__PURE__ */ jsx32(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
|
|
6801
|
+
/* @__PURE__ */ jsx32(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx32("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
|
|
6826
6802
|
] }),
|
|
6827
6803
|
/* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
|
|
6828
|
-
/* @__PURE__ */ jsx32(
|
|
6804
|
+
/* @__PURE__ */ jsx32(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ jsx32(VaultRow, { label: "Approved", actions: /* @__PURE__ */ jsx32(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
|
|
6829
6805
|
"Return to ",
|
|
6830
6806
|
where,
|
|
6831
6807
|
" by ",
|
|
@@ -6836,7 +6812,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6836
6812
|
where,
|
|
6837
6813
|
"."
|
|
6838
6814
|
] }) : !here ? /* @__PURE__ */ jsx32(
|
|
6839
|
-
|
|
6815
|
+
VaultRow,
|
|
6840
6816
|
{
|
|
6841
6817
|
label: "Passkey",
|
|
6842
6818
|
hint: `Passkeys work only on ${passkeys.rpId}`,
|
|
@@ -6844,14 +6820,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6844
6820
|
children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: "Not on this page" })
|
|
6845
6821
|
}
|
|
6846
6822
|
) : methods === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ jsx32(
|
|
6847
|
-
|
|
6823
|
+
VaultRow,
|
|
6848
6824
|
{
|
|
6849
6825
|
label: "Passkey",
|
|
6850
6826
|
hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
|
|
6851
6827
|
actions: /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
|
|
6852
6828
|
children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
|
|
6853
6829
|
}
|
|
6854
|
-
) : /* @__PURE__ */ jsx32(
|
|
6830
|
+
) : /* @__PURE__ */ jsx32(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Ready" }) }) })
|
|
6855
6831
|
] }) });
|
|
6856
6832
|
}
|
|
6857
6833
|
|
|
@@ -7129,7 +7105,7 @@ var TONE = {
|
|
|
7129
7105
|
};
|
|
7130
7106
|
function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
|
|
7131
7107
|
if (!bridge) {
|
|
7132
|
-
return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(
|
|
7108
|
+
return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(VaultSection, { children: /* @__PURE__ */ jsx33(Empty, { children: "Passkey import needs the desktop app." }) }) });
|
|
7133
7109
|
}
|
|
7134
7110
|
return /* @__PURE__ */ jsx33(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
|
|
7135
7111
|
}
|
|
@@ -7176,25 +7152,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7176
7152
|
/* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" })
|
|
7177
7153
|
] }) : /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: onClose, children: "Close" });
|
|
7178
7154
|
return /* @__PURE__ */ jsxs31(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
|
|
7179
|
-
screen.kind === "idle" ? /* @__PURE__ */ jsxs31(
|
|
7180
|
-
/* @__PURE__ */ jsx33(
|
|
7181
|
-
/* @__PURE__ */ jsx33(
|
|
7182
|
-
/* @__PURE__ */ jsx33(
|
|
7155
|
+
screen.kind === "idle" ? /* @__PURE__ */ jsxs31(VaultSection, { children: [
|
|
7156
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
|
|
7157
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
|
|
7158
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
|
|
7183
7159
|
] }) : null,
|
|
7184
|
-
preview ? /* @__PURE__ */ jsx33(
|
|
7160
|
+
preview ? /* @__PURE__ */ jsx33(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx33(
|
|
7185
7161
|
Windowed,
|
|
7186
7162
|
{
|
|
7187
7163
|
items: preview.slots,
|
|
7188
|
-
render: (slot) => /* @__PURE__ */ jsx33(
|
|
7164
|
+
render: (slot) => /* @__PURE__ */ jsx33(VaultRow, { label: /* @__PURE__ */ jsx33(Badge9, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ jsx33("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
|
|
7189
7165
|
}
|
|
7190
7166
|
) }) : null,
|
|
7191
|
-
status && !preview ? /* @__PURE__ */ jsxs31(
|
|
7192
|
-
/* @__PURE__ */ jsx33(
|
|
7193
|
-
/* @__PURE__ */ jsx33(
|
|
7194
|
-
/* @__PURE__ */ jsx33(
|
|
7195
|
-
/* @__PURE__ */ jsx33(
|
|
7196
|
-
status.uncertain > 0 ? /* @__PURE__ */ jsx33(
|
|
7197
|
-
status.not_attempted > 0 ? /* @__PURE__ */ jsx33(
|
|
7167
|
+
status && !preview ? /* @__PURE__ */ jsxs31(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
|
|
7168
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
|
|
7169
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
|
|
7170
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
|
|
7171
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
|
|
7172
|
+
status.uncertain > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
|
|
7173
|
+
status.not_attempted > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.not_attempted }) }) : null
|
|
7198
7174
|
] }) : null,
|
|
7199
7175
|
screen.message ? /* @__PURE__ */ jsx33("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
|
|
7200
7176
|
/* @__PURE__ */ jsx33(ErrorLine, { message: limitError })
|
|
@@ -7205,6 +7181,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7205
7181
|
import { useState as useState38 } from "react";
|
|
7206
7182
|
import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem4, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
|
|
7207
7183
|
import { Button as Button32 } from "@ai-matrx/design-system/controls";
|
|
7184
|
+
import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
|
|
7208
7185
|
|
|
7209
7186
|
// src/extension/CaptureCard.tsx
|
|
7210
7187
|
import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
@@ -7347,6 +7324,7 @@ function FillSetupCard({ fillSetup }) {
|
|
|
7347
7324
|
import { useState as useState37 } from "react";
|
|
7348
7325
|
import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
|
|
7349
7326
|
import { Button as Button31 } from "@ai-matrx/design-system/controls";
|
|
7327
|
+
import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
|
|
7350
7328
|
import { Fragment as Fragment20, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
7351
7329
|
var HOLD_MS = 6e4;
|
|
7352
7330
|
function PageGenerator({ fields }) {
|
|
@@ -7400,11 +7378,11 @@ function PageGenerator({ fields }) {
|
|
|
7400
7378
|
const value = held.value;
|
|
7401
7379
|
return /* @__PURE__ */ jsxs34(Fragment20, { children: [
|
|
7402
7380
|
/* @__PURE__ */ jsx36(
|
|
7403
|
-
|
|
7381
|
+
VaultRow,
|
|
7404
7382
|
{
|
|
7405
7383
|
label: "New password",
|
|
7406
7384
|
actions: /* @__PURE__ */ jsxs34(Fragment20, { children: [
|
|
7407
|
-
value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(
|
|
7385
|
+
value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(CopyIcon7, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
|
|
7408
7386
|
/* @__PURE__ */ jsxs34(Popover2, { open, onOpenChange: setOpen, children: [
|
|
7409
7387
|
/* @__PURE__ */ jsx36(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx36(Button31, { variant: "outline", icon: /* @__PURE__ */ jsx36(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
|
|
7410
7388
|
/* @__PURE__ */ jsx36(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx36(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
|
|
@@ -7413,7 +7391,7 @@ function PageGenerator({ fields }) {
|
|
|
7413
7391
|
children: said ? /* @__PURE__ */ jsx36("span", { role: "status", className: said.tone === "success" ? "line-clamp-2 text-xs text-foreground" : "line-clamp-2 text-xs text-muted-foreground", children: said.text }) : targets.length > 0 ? /* @__PURE__ */ jsx36("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ jsx36("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
|
|
7414
7392
|
}
|
|
7415
7393
|
),
|
|
7416
|
-
value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(
|
|
7394
|
+
value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ jsx36(Button31, { variant: "primary", icon: /* @__PURE__ */ jsx36(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ jsx36("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
|
|
7417
7395
|
] });
|
|
7418
7396
|
}
|
|
7419
7397
|
|
|
@@ -7475,7 +7453,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7475
7453
|
return /* @__PURE__ */ jsx37("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ jsxs35("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
|
|
7476
7454
|
header,
|
|
7477
7455
|
/* @__PURE__ */ jsxs35("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
|
|
7478
|
-
/* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback:
|
|
7456
|
+
/* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
|
|
7479
7457
|
/* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
|
|
7480
7458
|
page.refresh ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
|
|
7481
7459
|
onBrowse ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
|
|
@@ -7483,7 +7461,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7483
7461
|
fillSetup ? /* @__PURE__ */ jsx37(FillSetupCard, { fillSetup }) : null,
|
|
7484
7462
|
capture ? /* @__PURE__ */ jsx37(CaptureCard, { capture, onChanged }) : null,
|
|
7485
7463
|
/* @__PURE__ */ jsx37(
|
|
7486
|
-
|
|
7464
|
+
VaultSection,
|
|
7487
7465
|
{
|
|
7488
7466
|
title: "This site",
|
|
7489
7467
|
actions: canSave ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
|
|
@@ -7491,7 +7469,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7491
7469
|
}
|
|
7492
7470
|
),
|
|
7493
7471
|
said ? /* @__PURE__ */ jsx37(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ jsx37("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
|
|
7494
|
-
newPasswordFields && canSave ? /* @__PURE__ */ jsx37(
|
|
7472
|
+
newPasswordFields && canSave ? /* @__PURE__ */ jsx37(VaultSection, { children: /* @__PURE__ */ jsx37(PageGenerator, { fields: newPasswordFields }) }) : null
|
|
7495
7473
|
] }) });
|
|
7496
7474
|
}
|
|
7497
7475
|
function Outcome({ said, onDismiss }) {
|
|
@@ -7553,6 +7531,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7553
7531
|
import { useState as useState39 } from "react";
|
|
7554
7532
|
import { cn as cn15, useLook as useLook2 } from "@ai-matrx/design-system";
|
|
7555
7533
|
import { Select as Select10 } from "@ai-matrx/design-system/controls";
|
|
7534
|
+
import { GlobeIcon as GlobeIcon5 } from "@ai-matrx/design-system/icons";
|
|
7556
7535
|
import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
7557
7536
|
function vaultChoices(items, organizations, current) {
|
|
7558
7537
|
const n = (f) => items.filter(f).length;
|
|
@@ -7568,7 +7547,7 @@ function vaultChoices(items, organizations, current) {
|
|
|
7568
7547
|
function VaultSelect({ value, choices, onChange }) {
|
|
7569
7548
|
return /* @__PURE__ */ jsx38(Select10, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
|
|
7570
7549
|
}
|
|
7571
|
-
var CATEGORY_GLYPHS = { logins:
|
|
7550
|
+
var CATEGORY_GLYPHS = { logins: GlobeIcon5, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
|
|
7572
7551
|
var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
7573
7552
|
function itemCategory(item, definitions) {
|
|
7574
7553
|
return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
|
|
@@ -7633,7 +7612,7 @@ function Group({ title, children }) {
|
|
|
7633
7612
|
children
|
|
7634
7613
|
] });
|
|
7635
7614
|
}
|
|
7636
|
-
function
|
|
7615
|
+
function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
|
|
7637
7616
|
const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
|
|
7638
7617
|
return /* @__PURE__ */ jsxs36("nav", { "aria-label": "Vault", className: "flex h-full min-h-0 flex-col border-r border-sidebar-border bg-sidebar-background text-sidebar-foreground", children: [
|
|
7639
7618
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
|
|
@@ -7642,7 +7621,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
|
|
|
7642
7621
|
] }),
|
|
7643
7622
|
/* @__PURE__ */ jsxs36("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
|
|
7644
7623
|
/* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
|
|
7645
|
-
hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph:
|
|
7624
|
+
hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph: GlobeIcon5, label: "This page", onClick: () => onView("page") }) : null,
|
|
7646
7625
|
/* @__PURE__ */ jsx38(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
|
|
7647
7626
|
hasFavorites ? /* @__PURE__ */ jsx38(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
|
|
7648
7627
|
hasRecents ? /* @__PURE__ */ jsx38(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
|
|
@@ -7682,7 +7661,7 @@ var NO_HOST = {};
|
|
|
7682
7661
|
var ITEM_PANELS = {
|
|
7683
7662
|
share: SharePanel,
|
|
7684
7663
|
move: MovePanel,
|
|
7685
|
-
history:
|
|
7664
|
+
history: ItemHistoryPanel,
|
|
7686
7665
|
activity: ActivityPanel,
|
|
7687
7666
|
settings: ItemSettingsPanel,
|
|
7688
7667
|
field: FieldSettingsPanel,
|
|
@@ -8073,7 +8052,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8073
8052
|
] }) : null,
|
|
8074
8053
|
/* @__PURE__ */ jsxs37("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
|
|
8075
8054
|
mode === "full" ? /* @__PURE__ */ jsx39(
|
|
8076
|
-
|
|
8055
|
+
VaultSidebar,
|
|
8077
8056
|
{
|
|
8078
8057
|
vault: loc.vault,
|
|
8079
8058
|
choices,
|
|
@@ -8814,7 +8793,7 @@ function createApiVaultPort(api, options = {}) {
|
|
|
8814
8793
|
lists.forEach((l, i) => {
|
|
8815
8794
|
const sharedList = i === lists.length - 1;
|
|
8816
8795
|
for (const w of l.items) {
|
|
8817
|
-
if (seen.has(w.id) || deleted.has(w.id)) continue;
|
|
8796
|
+
if (seen.has(w.id) || deleted.has(w.id) || isHiddenItem(w)) continue;
|
|
8818
8797
|
const owner = sharedList ? orgOf(w.organization_id, null, false) : orgOf(w.organization_id, w.user_id, i === 0);
|
|
8819
8798
|
const item = itemOf(w, sharedList && !w.organization_id ? { kind: "shared", label: "Shared with me", organizationId: null } : owner, defs, auth);
|
|
8820
8799
|
(isDeleted(w) ? deleted : seen).set(w.id, item);
|
|
@@ -8925,6 +8904,7 @@ export {
|
|
|
8925
8904
|
CATEGORIES,
|
|
8926
8905
|
DEFAULT_LOCATION,
|
|
8927
8906
|
GenerateButton,
|
|
8907
|
+
HIDDEN_ITEM_TAG,
|
|
8928
8908
|
LOCKED_MESSAGE,
|
|
8929
8909
|
VaultApp,
|
|
8930
8910
|
VaultLockedError,
|
|
@@ -8935,6 +8915,7 @@ export {
|
|
|
8935
8915
|
createVaultKnobs,
|
|
8936
8916
|
guardPort,
|
|
8937
8917
|
inferFromUrl,
|
|
8918
|
+
isHiddenItem,
|
|
8938
8919
|
locationFromParams,
|
|
8939
8920
|
locationToParams,
|
|
8940
8921
|
loginSiteOf,
|