@ai-matrx/vault 0.1.8 → 0.1.10
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 +37 -0
- package/dist/index.cjs +246 -267
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +231 -252
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -102,7 +102,7 @@ var init_keepass_xml_worker_client = __esm({
|
|
|
102
102
|
|
|
103
103
|
// src/VaultApp.tsx
|
|
104
104
|
import { useCallback as useCallback5, useEffect as useEffect23, useMemo as useMemo6, useRef as useRef19, useState as useState40 } from "react";
|
|
105
|
-
import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger6 } from "@ai-matrx/design-system";
|
|
105
|
+
import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger6, LookScope } from "@ai-matrx/design-system";
|
|
106
106
|
import { Button as Button33, SearchField as SearchField4, Select as Select11 } from "@ai-matrx/design-system/controls";
|
|
107
107
|
import { confirm as confirm13 } from "@ai-matrx/kit/confirm-opener";
|
|
108
108
|
|
|
@@ -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";
|
|
@@ -560,7 +548,7 @@ function useElementWidth(ref) {
|
|
|
560
548
|
// src/ui.tsx
|
|
561
549
|
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect4, useState as useState4 } from "react";
|
|
562
550
|
import { Dialog as Dialog2, DialogContent as DialogContent2, DialogFooter, DialogHeader as DialogHeader2, DialogTitle as DialogTitle2 } from "@ai-matrx/design-system";
|
|
563
|
-
import { cn as cn2 } from "@ai-matrx/design-system";
|
|
551
|
+
import { cn as cn2, useLook } from "@ai-matrx/design-system";
|
|
564
552
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
565
553
|
var InPanel = createContext4(false);
|
|
566
554
|
var Room = createContext4(null);
|
|
@@ -579,14 +567,15 @@ 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);
|
|
572
|
+
const desktop = useLook() === "desktop";
|
|
584
573
|
return /* @__PURE__ */ jsxs4("section", { className: cn2("flex flex-col gap-1.5", className), children: [
|
|
585
574
|
title || actions ? /* @__PURE__ */ jsxs4("div", { className: "flex min-h-7 items-center justify-between gap-2 px-1", children: [
|
|
586
|
-
title ? /* @__PURE__ */ jsx4("h3", { className: "text-xs font-medium text-muted-foreground", children: title }) : /* @__PURE__ */ jsx4("span", {}),
|
|
575
|
+
title ? /* @__PURE__ */ jsx4("h3", { className: desktop ? "text-sm font-semibold text-foreground" : "text-xs font-medium text-muted-foreground", children: title }) : /* @__PURE__ */ jsx4("span", {}),
|
|
587
576
|
actions ? /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-1", children: actions }) : null
|
|
588
577
|
] }) : null,
|
|
589
|
-
/* @__PURE__ */ jsx4("div", { className: flat ? "-mx-3 flex flex-col sm:-mx-4" : "flex flex-col rounded-xl border border-border bg-card py-1", children })
|
|
578
|
+
/* @__PURE__ */ jsx4("div", { className: flat ? "-mx-3 flex flex-col sm:-mx-4" : desktop ? "flex flex-col divide-y divide-border rounded-xl bg-card" : "flex flex-col rounded-xl border border-border bg-card py-1", children })
|
|
590
579
|
] });
|
|
591
580
|
}
|
|
592
581
|
var ROW_GRID = {
|
|
@@ -594,7 +583,7 @@ var ROW_GRID = {
|
|
|
594
583
|
roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
|
|
595
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"
|
|
596
585
|
};
|
|
597
|
-
function
|
|
586
|
+
function VaultRow({ label, hint, children, actions, top = false, className }) {
|
|
598
587
|
const room = useContext4(Room);
|
|
599
588
|
return /* @__PURE__ */ jsxs4("div", { className: cn2("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
|
|
600
589
|
/* @__PURE__ */ jsxs4("div", { className: cn2("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
|
|
@@ -615,11 +604,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
|
|
|
615
604
|
footer ? /* @__PURE__ */ jsx4(DialogFooter, { children: footer }) : null
|
|
616
605
|
] }) });
|
|
617
606
|
}
|
|
618
|
-
function formatBytes(n) {
|
|
619
|
-
if (n < 1024) return `${n} B`;
|
|
620
|
-
if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
|
|
621
|
-
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
622
|
-
}
|
|
623
607
|
var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
|
|
624
608
|
|
|
625
609
|
// src/FieldRows.tsx
|
|
@@ -678,14 +662,14 @@ function SecretRow({ port, item, field, extra }) {
|
|
|
678
662
|
const multiline = field.kind === "multiline";
|
|
679
663
|
const shown = visible ? plain : secret.value;
|
|
680
664
|
return /* @__PURE__ */ jsx5(
|
|
681
|
-
|
|
665
|
+
VaultRow,
|
|
682
666
|
{
|
|
683
667
|
label: field.label,
|
|
684
668
|
top: multiline && shown !== null,
|
|
685
669
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
686
670
|
extra,
|
|
687
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,
|
|
688
|
-
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
|
|
689
673
|
] }),
|
|
690
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 })
|
|
691
675
|
}
|
|
@@ -695,7 +679,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
695
679
|
const copyValue2 = useCopy();
|
|
696
680
|
const isUrl = /^https?:\/\//i.test(value);
|
|
697
681
|
return /* @__PURE__ */ jsx5(
|
|
698
|
-
|
|
682
|
+
VaultRow,
|
|
699
683
|
{
|
|
700
684
|
label,
|
|
701
685
|
hint,
|
|
@@ -703,7 +687,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
703
687
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
704
688
|
extra,
|
|
705
689
|
isUrl && openUrl ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
|
|
706
|
-
/* @__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 }) })
|
|
707
691
|
] }),
|
|
708
692
|
children: isUrl && openUrl ? (
|
|
709
693
|
// A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
|
|
@@ -726,12 +710,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
726
710
|
);
|
|
727
711
|
}
|
|
728
712
|
function AddRow({ label, onAdd, children = "Add" }) {
|
|
729
|
-
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" }) });
|
|
730
714
|
}
|
|
731
715
|
function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
|
|
732
716
|
const [shown, setShown] = useState5(false);
|
|
733
717
|
return /* @__PURE__ */ jsx5(
|
|
734
|
-
|
|
718
|
+
VaultRow,
|
|
735
719
|
{
|
|
736
720
|
label,
|
|
737
721
|
hint,
|
|
@@ -748,7 +732,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
|
|
|
748
732
|
function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
749
733
|
const [shown, setShown] = useState5(false);
|
|
750
734
|
return /* @__PURE__ */ jsx5(
|
|
751
|
-
|
|
735
|
+
VaultRow,
|
|
752
736
|
{
|
|
753
737
|
label: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
|
|
754
738
|
actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
@@ -761,6 +745,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
|
|
|
761
745
|
}
|
|
762
746
|
|
|
763
747
|
// src/activity/HistoryPanel.tsx
|
|
748
|
+
import { CopyIcon as CopyIcon2 } from "@ai-matrx/design-system/icons";
|
|
764
749
|
import { formatAbsoluteDate as formatAbsoluteDate2 } from "@ai-matrx/kit/format";
|
|
765
750
|
|
|
766
751
|
// src/activity/logic.ts
|
|
@@ -1253,7 +1238,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1253
1238
|
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,
|
|
1254
1239
|
children: [
|
|
1255
1240
|
error ? /* @__PURE__ */ jsx6("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1256
|
-
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(
|
|
1241
|
+
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(
|
|
1257
1242
|
day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
|
|
1258
1243
|
(r) => `${r.s.what}|${r.s.who ?? ""}`
|
|
1259
1244
|
).map(({ row: { entry, s }, times }) => {
|
|
@@ -1276,7 +1261,7 @@ function ActivityPanel({ item, port, onClose }) {
|
|
|
1276
1261
|
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1277
1262
|
var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
1278
1263
|
var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
1279
|
-
function
|
|
1264
|
+
function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
1280
1265
|
const eligible = historyEligible(item);
|
|
1281
1266
|
const [page, setPage] = useState7(null);
|
|
1282
1267
|
const [loading, setLoading] = useState7(eligible);
|
|
@@ -1338,7 +1323,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
|
1338
1323
|
error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
|
|
1339
1324
|
notice ? /* @__PURE__ */ jsx7("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
|
|
1340
1325
|
page && groups.length === 0 ? /* @__PURE__ */ jsx7(Empty, { children: "No earlier values yet." }) : null,
|
|
1341
|
-
page ? groups.map((g) => /* @__PURE__ */ jsx7(
|
|
1326
|
+
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,
|
|
1342
1327
|
page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
|
|
1343
1328
|
page.captureStartedAt ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
|
|
1344
1329
|
"Kept since ",
|
|
@@ -1399,12 +1384,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1399
1384
|
}
|
|
1400
1385
|
}
|
|
1401
1386
|
return /* @__PURE__ */ jsx7(
|
|
1402
|
-
|
|
1387
|
+
VaultRow,
|
|
1403
1388
|
{
|
|
1404
1389
|
label: when,
|
|
1405
1390
|
actions: entry.available ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1406
1391
|
/* @__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() }),
|
|
1407
|
-
/* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(
|
|
1392
|
+
/* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(CopyIcon2, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
|
|
1408
1393
|
canRestore(page, entry) ? /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
|
|
1409
1394
|
] }) : null,
|
|
1410
1395
|
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 })
|
|
@@ -1416,6 +1401,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1416
1401
|
import { useEffect as useEffect11, useState as useState13 } from "react";
|
|
1417
1402
|
import { Button as Button9 } from "@ai-matrx/design-system/controls";
|
|
1418
1403
|
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";
|
|
1404
|
+
import { CopyIcon as CopyIcon4 } from "@ai-matrx/design-system/icons";
|
|
1419
1405
|
|
|
1420
1406
|
// src/authenticator/AddOtpPanel.tsx
|
|
1421
1407
|
import { useState as useState12 } from "react";
|
|
@@ -1425,8 +1411,11 @@ import { Button as Button8, Field as Field4, Select as Select2 } from "@ai-matrx
|
|
|
1425
1411
|
import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
|
|
1426
1412
|
import { Button as Button5 } from "@ai-matrx/design-system/controls";
|
|
1427
1413
|
import { cn as cn5 } from "@ai-matrx/design-system";
|
|
1414
|
+
import { CopyIcon as CopyIcon3 } from "@ai-matrx/design-system/icons";
|
|
1415
|
+
import { groupCode as groupCode2 } from "@ai-matrx/kit/format";
|
|
1428
1416
|
|
|
1429
1417
|
// src/authenticator/otpauth.ts
|
|
1418
|
+
import { groupCode } from "@ai-matrx/kit/format";
|
|
1430
1419
|
var TOTP_DEFAULT_DIGITS = 6;
|
|
1431
1420
|
var TOTP_DEFAULT_PERIOD = 30;
|
|
1432
1421
|
var TOTP_DEFAULT_ALGORITHM = "SHA1";
|
|
@@ -1494,12 +1483,6 @@ function describeEnrollment(parsed) {
|
|
|
1494
1483
|
const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
|
|
1495
1484
|
return parts.length ? parts.join(" \xB7 ") : "Setup key";
|
|
1496
1485
|
}
|
|
1497
|
-
function groupCode(code) {
|
|
1498
|
-
const c = code.replace(/\s/g, "");
|
|
1499
|
-
if (c.length < 6) return c;
|
|
1500
|
-
const head = Math.ceil(c.length / 2);
|
|
1501
|
-
return `${c.slice(0, head)} ${c.slice(head)}`;
|
|
1502
|
-
}
|
|
1503
1486
|
function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
|
|
1504
1487
|
return groupCode("\u2022".repeat(Math.max(6, digits)));
|
|
1505
1488
|
}
|
|
@@ -1577,7 +1560,7 @@ function useCopied() {
|
|
|
1577
1560
|
}
|
|
1578
1561
|
function CodeButton({ live, digits, size = "md", label }) {
|
|
1579
1562
|
const { copied, copy } = useCopied();
|
|
1580
|
-
const shown = live.code ?
|
|
1563
|
+
const shown = live.code ? groupCode2(live.code) : maskedCode(digits);
|
|
1581
1564
|
return /* @__PURE__ */ jsxs8(
|
|
1582
1565
|
"button",
|
|
1583
1566
|
{
|
|
@@ -1596,7 +1579,7 @@ function CodeButton({ live, digits, size = "md", label }) {
|
|
|
1596
1579
|
}
|
|
1597
1580
|
function CopyCodeButton({ live, label }) {
|
|
1598
1581
|
const { copied, copy } = useCopied();
|
|
1599
|
-
return /* @__PURE__ */ jsx8(Button5, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx8(CheckGlyph, {}) : /* @__PURE__ */ jsx8(
|
|
1582
|
+
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) });
|
|
1600
1583
|
}
|
|
1601
1584
|
|
|
1602
1585
|
// src/authenticator/live-code.ts
|
|
@@ -1868,7 +1851,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
|
|
|
1868
1851
|
className: dragging ? "rounded-lg bg-accent" : void 0,
|
|
1869
1852
|
children: [
|
|
1870
1853
|
/* @__PURE__ */ jsxs9(
|
|
1871
|
-
|
|
1854
|
+
VaultRow,
|
|
1872
1855
|
{
|
|
1873
1856
|
label,
|
|
1874
1857
|
actions: /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
@@ -2018,7 +2001,7 @@ function TotpRow({ port, item, onChanged }) {
|
|
|
2018
2001
|
] })
|
|
2019
2002
|
] }) : null;
|
|
2020
2003
|
return /* @__PURE__ */ jsx10(
|
|
2021
|
-
|
|
2004
|
+
VaultRow,
|
|
2022
2005
|
{
|
|
2023
2006
|
label: "One-time password",
|
|
2024
2007
|
actions: /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
@@ -2077,7 +2060,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
|
|
|
2077
2060
|
const [busy, setBusy] = useState11(false);
|
|
2078
2061
|
const [error, setError] = useState11(null);
|
|
2079
2062
|
const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
|
|
2080
|
-
return /* @__PURE__ */ jsx10(
|
|
2063
|
+
return /* @__PURE__ */ jsx10(VaultRow, { label: "Two-factor", hint: error ? /* @__PURE__ */ jsx10("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ jsx10(
|
|
2081
2064
|
Select,
|
|
2082
2065
|
{
|
|
2083
2066
|
value: value ?? "none",
|
|
@@ -2192,7 +2175,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2192
2175
|
/* @__PURE__ */ jsx11(Button8, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
|
|
2193
2176
|
] }),
|
|
2194
2177
|
children: [
|
|
2195
|
-
/* @__PURE__ */ jsxs11(
|
|
2178
|
+
/* @__PURE__ */ jsxs11(VaultSection, { children: [
|
|
2196
2179
|
/* @__PURE__ */ jsx11(
|
|
2197
2180
|
OtpSetupRow,
|
|
2198
2181
|
{
|
|
@@ -2214,7 +2197,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2214
2197
|
status: image ? `QR image ready \xB7 ${image.name}` : null
|
|
2215
2198
|
}
|
|
2216
2199
|
),
|
|
2217
|
-
/* @__PURE__ */ jsx11(
|
|
2200
|
+
/* @__PURE__ */ jsx11(VaultRow, { label: "Add to", children: /* @__PURE__ */ jsx11(
|
|
2218
2201
|
Select2,
|
|
2219
2202
|
{
|
|
2220
2203
|
value: target,
|
|
@@ -2228,7 +2211,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2228
2211
|
}
|
|
2229
2212
|
) }),
|
|
2230
2213
|
isNew ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
2231
|
-
/* @__PURE__ */ jsx11(
|
|
2214
|
+
/* @__PURE__ */ jsx11(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx11(
|
|
2232
2215
|
Field4,
|
|
2233
2216
|
{
|
|
2234
2217
|
className: "w-full",
|
|
@@ -2242,7 +2225,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
|
|
|
2242
2225
|
"aria-label": "Name"
|
|
2243
2226
|
}
|
|
2244
2227
|
) }),
|
|
2245
|
-
/* @__PURE__ */ jsx11(
|
|
2228
|
+
/* @__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 }) })
|
|
2246
2229
|
] }) : null
|
|
2247
2230
|
] }),
|
|
2248
2231
|
error ? /* @__PURE__ */ jsx11("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
|
|
@@ -2310,7 +2293,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
|
|
|
2310
2293
|
/* @__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" }) }),
|
|
2311
2294
|
/* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
|
|
2312
2295
|
/* @__PURE__ */ jsx12(Button9, { variant: "primary", icon: /* @__PURE__ */ jsx12(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
|
|
2313
|
-
] }) : 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(
|
|
2296
|
+
] }) : 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(
|
|
2314
2297
|
OtpListRow,
|
|
2315
2298
|
{
|
|
2316
2299
|
port,
|
|
@@ -2404,7 +2387,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2404
2387
|
"Open login"
|
|
2405
2388
|
] }),
|
|
2406
2389
|
live.code ? /* @__PURE__ */ jsxs12(DropdownMenuItem2, { onSelect: () => live.code && void copy(live.code), children: [
|
|
2407
|
-
/* @__PURE__ */ jsx12(
|
|
2390
|
+
/* @__PURE__ */ jsx12(CopyIcon4, { className: "size-4" }),
|
|
2408
2391
|
"Copy code"
|
|
2409
2392
|
] }) : null,
|
|
2410
2393
|
canManage ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
@@ -2431,6 +2414,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
|
|
|
2431
2414
|
import { useRef as useRef9, useState as useState14 } from "react";
|
|
2432
2415
|
import { Badge as Badge3, Button as Button10, DisclosureHeader, Field as Field5, SegmentedControl, Select as Select3, Switch } from "@ai-matrx/design-system/controls";
|
|
2433
2416
|
import { confirm as confirm3 } from "@ai-matrx/kit/confirm-opener";
|
|
2417
|
+
import { GlobeIcon as GlobeIcon2 } from "@ai-matrx/design-system/icons";
|
|
2434
2418
|
|
|
2435
2419
|
// src/fields/rules.ts
|
|
2436
2420
|
var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -2580,7 +2564,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2580
2564
|
const locked = !canEdit || busy !== null;
|
|
2581
2565
|
return /* @__PURE__ */ jsxs13(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2582
2566
|
!canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2583
|
-
/* @__PURE__ */ jsx13(
|
|
2567
|
+
/* @__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(
|
|
2584
2568
|
SegmentedControl,
|
|
2585
2569
|
{
|
|
2586
2570
|
"aria-label": "Who can see it",
|
|
@@ -2589,8 +2573,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2589
2573
|
data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
|
|
2590
2574
|
}
|
|
2591
2575
|
) }) }),
|
|
2592
|
-
/* @__PURE__ */ jsxs13(
|
|
2593
|
-
/* @__PURE__ */ jsx13(
|
|
2576
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "Automation", children: [
|
|
2577
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ jsx13(
|
|
2594
2578
|
Field5,
|
|
2595
2579
|
{
|
|
2596
2580
|
ref: envRef,
|
|
@@ -2610,10 +2594,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2610
2594
|
}
|
|
2611
2595
|
}
|
|
2612
2596
|
) }),
|
|
2613
|
-
/* @__PURE__ */ jsx13(
|
|
2597
|
+
/* @__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) }) })
|
|
2614
2598
|
] }),
|
|
2615
|
-
/* @__PURE__ */ jsxs13(
|
|
2616
|
-
/* @__PURE__ */ jsx13(
|
|
2599
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "Field", children: [
|
|
2600
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Description", children: /* @__PURE__ */ jsx13(
|
|
2617
2601
|
Field5,
|
|
2618
2602
|
{
|
|
2619
2603
|
className: "w-full",
|
|
@@ -2629,8 +2613,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
|
|
|
2629
2613
|
}
|
|
2630
2614
|
}
|
|
2631
2615
|
) }),
|
|
2632
|
-
/* @__PURE__ */ jsx13(
|
|
2633
|
-
/* @__PURE__ */ jsx13(
|
|
2616
|
+
/* @__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 }) }) }),
|
|
2617
|
+
/* @__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 }) }) })
|
|
2634
2618
|
] }),
|
|
2635
2619
|
error ? /* @__PURE__ */ jsx13(Problem, { children: error }) : null
|
|
2636
2620
|
] });
|
|
@@ -2661,8 +2645,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2661
2645
|
const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
|
|
2662
2646
|
return /* @__PURE__ */ jsxs13(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
|
|
2663
2647
|
!canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
|
|
2664
|
-
/* @__PURE__ */ jsxs13(
|
|
2665
|
-
/* @__PURE__ */ jsx13(
|
|
2648
|
+
/* @__PURE__ */ jsxs13(VaultSection, { title: "In the browser", children: [
|
|
2649
|
+
/* @__PURE__ */ jsx13(VaultRow, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ jsx13(
|
|
2666
2650
|
Select3,
|
|
2667
2651
|
{
|
|
2668
2652
|
"aria-label": "Website matching",
|
|
@@ -2672,13 +2656,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2672
2656
|
onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
|
|
2673
2657
|
}
|
|
2674
2658
|
) }),
|
|
2675
|
-
/* @__PURE__ */ jsx13(
|
|
2659
|
+
/* @__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 })) }) }),
|
|
2676
2660
|
promotable.map((f) => /* @__PURE__ */ jsx13(
|
|
2677
|
-
|
|
2661
|
+
VaultRow,
|
|
2678
2662
|
{
|
|
2679
2663
|
label: f.label,
|
|
2680
2664
|
hint: quietHint("Encrypted, so the browser can\u2019t match it"),
|
|
2681
|
-
actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(
|
|
2665
|
+
actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(GlobeIcon2, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
|
|
2682
2666
|
children: /* @__PURE__ */ jsx13("span", { className: "text-muted-foreground", children: "Not a website yet" })
|
|
2683
2667
|
},
|
|
2684
2668
|
f.id
|
|
@@ -2686,8 +2670,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2686
2670
|
] }),
|
|
2687
2671
|
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5", children: [
|
|
2688
2672
|
/* @__PURE__ */ jsx13(DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
|
|
2689
|
-
advanced ? /* @__PURE__ */ jsx13(
|
|
2690
|
-
|
|
2673
|
+
advanced ? /* @__PURE__ */ jsx13(VaultSection, { children: item.fields.length === 0 ? /* @__PURE__ */ jsx13(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ jsx13(
|
|
2674
|
+
VaultRow,
|
|
2691
2675
|
{
|
|
2692
2676
|
label: f.label,
|
|
2693
2677
|
actions: /* @__PURE__ */ jsx13(Button10, { variant: "quiet", icon: /* @__PURE__ */ jsx13(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
|
|
@@ -2712,6 +2696,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
|
|
|
2712
2696
|
import { createContext as createContext5, useContext as useContext5, useEffect as useEffect12, useRef as useRef10, useState as useState15 } from "react";
|
|
2713
2697
|
import { Popover, PopoverContent, PopoverTrigger, cn as cn7 } from "@ai-matrx/design-system";
|
|
2714
2698
|
import { Button as Button11, NumberStepper, SegmentedControl as SegmentedControl2, Select as Select4, Switch as Switch2 } from "@ai-matrx/design-system/controls";
|
|
2699
|
+
import { CopyIcon as CopyIcon5 } from "@ai-matrx/design-system/icons";
|
|
2715
2700
|
|
|
2716
2701
|
// src/generator/generate.ts
|
|
2717
2702
|
import {
|
|
@@ -2869,7 +2854,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
|
|
|
2869
2854
|
/* @__PURE__ */ jsxs14("div", { className: "flex min-h-7 items-start gap-1", children: [
|
|
2870
2855
|
/* @__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" }),
|
|
2871
2856
|
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: revealed ? /* @__PURE__ */ jsx14(EyeOffGlyph, {}) : /* @__PURE__ */ jsx14(EyeGlyph, {}), "aria-label": revealed ? "Hide" : "Reveal", disabled: !candidate, onClick: () => setRevealed((r) => !r) }),
|
|
2872
|
-
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(
|
|
2857
|
+
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(CopyIcon5, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
|
|
2873
2858
|
/* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
|
|
2874
2859
|
] }),
|
|
2875
2860
|
strength && candidate ? /* @__PURE__ */ jsxs14("p", { className: "text-xs", children: [
|
|
@@ -2996,6 +2981,7 @@ function useLocked(lock) {
|
|
|
2996
2981
|
}
|
|
2997
2982
|
|
|
2998
2983
|
// src/io/BackupPanel.tsx
|
|
2984
|
+
import { formatFileSize } from "@ai-matrx/kit/format";
|
|
2999
2985
|
import { useEffect as useEffect13, useRef as useRef11, useState as useState17 } from "react";
|
|
3000
2986
|
import { Button as Button13, Field as Field6, SegmentedControl as SegmentedControl3, Switch as Switch3 } from "@ai-matrx/design-system/controls";
|
|
3001
2987
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
@@ -3137,17 +3123,17 @@ function omissionText(o) {
|
|
|
3137
3123
|
return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
|
|
3138
3124
|
}
|
|
3139
3125
|
function Summary({ value }) {
|
|
3140
|
-
return /* @__PURE__ */ jsxs16(
|
|
3141
|
-
/* @__PURE__ */ jsx16(
|
|
3142
|
-
/* @__PURE__ */ jsx16(
|
|
3143
|
-
/* @__PURE__ */ jsx16(
|
|
3126
|
+
return /* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3127
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Credentials", children: value.record_count }),
|
|
3128
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Protected fields", children: value.field_count }),
|
|
3129
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${formatFileSize(value.attachment_bytes)}` : "0" })
|
|
3144
3130
|
] });
|
|
3145
3131
|
}
|
|
3146
3132
|
function Omissions({ omissions, accepted, onAccepted, verb }) {
|
|
3147
3133
|
if (omissions.length === 0) return null;
|
|
3148
|
-
return /* @__PURE__ */ jsxs16(
|
|
3149
|
-
omissions.map((o, i) => /* @__PURE__ */ jsx16(
|
|
3150
|
-
/* @__PURE__ */ jsx16(
|
|
3134
|
+
return /* @__PURE__ */ jsxs16(VaultSection, { title: "Left out", children: [
|
|
3135
|
+
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}`)),
|
|
3136
|
+
/* @__PURE__ */ jsx16(VaultRow, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ jsx16(Switch3, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
|
|
3151
3137
|
] });
|
|
3152
3138
|
}
|
|
3153
3139
|
function BackupPanel({ port, items, onClose, onChanged }) {
|
|
@@ -3282,7 +3268,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3282
3268
|
),
|
|
3283
3269
|
mode === "backup" ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3284
3270
|
/* @__PURE__ */ jsx16(
|
|
3285
|
-
|
|
3271
|
+
VaultSection,
|
|
3286
3272
|
{
|
|
3287
3273
|
title: `${selected.size} of ${plural(items.length, "credential")}`,
|
|
3288
3274
|
actions: /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
@@ -3301,13 +3287,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3301
3287
|
backup ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3302
3288
|
/* @__PURE__ */ jsx16(Summary, { value: backup }),
|
|
3303
3289
|
/* @__PURE__ */ jsx16(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
|
|
3304
|
-
/* @__PURE__ */ jsxs16(
|
|
3305
|
-
/* @__PURE__ */ jsx16(
|
|
3306
|
-
/* @__PURE__ */ jsx16(
|
|
3290
|
+
/* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3291
|
+
/* @__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) }) }),
|
|
3292
|
+
/* @__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) }) })
|
|
3307
3293
|
] })
|
|
3308
3294
|
] }) : null
|
|
3309
|
-
] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(
|
|
3310
|
-
/* @__PURE__ */ jsxs16(
|
|
3295
|
+
] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(VaultSection, { children: [
|
|
3296
|
+
/* @__PURE__ */ jsxs16(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
|
|
3311
3297
|
/* @__PURE__ */ jsx16(Button13, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
|
|
3312
3298
|
/* @__PURE__ */ jsx16(
|
|
3313
3299
|
"input",
|
|
@@ -3323,11 +3309,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3323
3309
|
}
|
|
3324
3310
|
)
|
|
3325
3311
|
] }),
|
|
3326
|
-
/* @__PURE__ */ jsx16(
|
|
3312
|
+
/* @__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) }) })
|
|
3327
3313
|
] }) : /* @__PURE__ */ jsxs16(Fragment9, { children: [
|
|
3328
3314
|
/* @__PURE__ */ jsx16(Summary, { value: restorePreview }),
|
|
3329
3315
|
!result ? /* @__PURE__ */ jsx16(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
|
|
3330
|
-
!result ? /* @__PURE__ */ jsx16("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ jsx16(
|
|
3316
|
+
!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: [
|
|
3331
3317
|
RECORD_STATUS[r.status],
|
|
3332
3318
|
r.reason === "alias_conflict" ? " \xB7 name in use" : ""
|
|
3333
3319
|
] }) }, r.source_item_id)) })
|
|
@@ -3432,7 +3418,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3432
3418
|
] })
|
|
3433
3419
|
] }),
|
|
3434
3420
|
children: [
|
|
3435
|
-
/* @__PURE__ */ jsx17(
|
|
3421
|
+
/* @__PURE__ */ jsx17(VaultSection, { children: /* @__PURE__ */ jsx17(VaultRow, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ jsx17(
|
|
3436
3422
|
Select5,
|
|
3437
3423
|
{
|
|
3438
3424
|
value: profile,
|
|
@@ -3445,7 +3431,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3445
3431
|
}
|
|
3446
3432
|
) }) }),
|
|
3447
3433
|
/* @__PURE__ */ jsx17(
|
|
3448
|
-
|
|
3434
|
+
VaultSection,
|
|
3449
3435
|
{
|
|
3450
3436
|
title: `${selected.size} of ${plural(logins.length, "login")}`,
|
|
3451
3437
|
actions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
|
|
@@ -4516,13 +4502,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4516
4502
|
/* @__PURE__ */ jsx18(Button15, { variant: "primary", onClick: onClose, children: "Done" })
|
|
4517
4503
|
] });
|
|
4518
4504
|
return /* @__PURE__ */ jsxs18(Panel, { title: "Import", size: "xl", onClose, footer, children: [
|
|
4519
|
-
stage === "choose" ? /* @__PURE__ */ jsxs18(
|
|
4520
|
-
/* @__PURE__ */ jsx18(
|
|
4505
|
+
stage === "choose" ? /* @__PURE__ */ jsxs18(VaultSection, { children: [
|
|
4506
|
+
/* @__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) => {
|
|
4521
4507
|
setSource(s);
|
|
4522
4508
|
setError(null);
|
|
4523
4509
|
} }) }),
|
|
4524
|
-
source === "env" ? /* @__PURE__ */ jsx18(
|
|
4525
|
-
/* @__PURE__ */ jsxs18(
|
|
4510
|
+
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,
|
|
4511
|
+
/* @__PURE__ */ jsxs18(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
|
|
4526
4512
|
/* @__PURE__ */ jsx18(Button15, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
|
|
4527
4513
|
/* @__PURE__ */ jsx18(
|
|
4528
4514
|
"input",
|
|
@@ -4539,12 +4525,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4539
4525
|
}
|
|
4540
4526
|
)
|
|
4541
4527
|
] }),
|
|
4542
|
-
source === "env" ? /* @__PURE__ */ jsx18(
|
|
4528
|
+
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
|
|
4543
4529
|
] }) : null,
|
|
4544
4530
|
stage === "review" && draft ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
|
|
4545
|
-
organizations.length > 0 ? /* @__PURE__ */ jsx18(
|
|
4531
|
+
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,
|
|
4546
4532
|
/* @__PURE__ */ jsx18(
|
|
4547
|
-
|
|
4533
|
+
VaultSection,
|
|
4548
4534
|
{
|
|
4549
4535
|
title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
|
|
4550
4536
|
actions: /* @__PURE__ */ jsxs18(Fragment11, { children: [
|
|
@@ -4572,11 +4558,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4572
4558
|
)
|
|
4573
4559
|
}
|
|
4574
4560
|
),
|
|
4575
|
-
draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ jsx18(
|
|
4561
|
+
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,
|
|
4576
4562
|
draft.kind === "file" ? /* @__PURE__ */ jsx18(Notices, { draft }) : null,
|
|
4577
|
-
draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(
|
|
4578
|
-
/* @__PURE__ */ jsx18(
|
|
4579
|
-
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(
|
|
4563
|
+
draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(VaultSection, { children: [
|
|
4564
|
+
/* @__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" }) }),
|
|
4565
|
+
draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(VaultRow, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ jsx18(
|
|
4580
4566
|
Select6,
|
|
4581
4567
|
{
|
|
4582
4568
|
value: draft.mapping[index] ?? "keep",
|
|
@@ -4588,16 +4574,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4588
4574
|
] }) }) : null,
|
|
4589
4575
|
ambiguous ? /* @__PURE__ */ jsx18(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
|
|
4590
4576
|
] }) : null,
|
|
4591
|
-
stage === "done" && done ? /* @__PURE__ */ jsxs18(
|
|
4592
|
-
/* @__PURE__ */ jsx18(
|
|
4593
|
-
/* @__PURE__ */ jsx18(
|
|
4594
|
-
/* @__PURE__ */ jsx18(
|
|
4595
|
-
done.untried.length > 0 ? /* @__PURE__ */ jsx18(
|
|
4596
|
-
done.withOtp > 0 ? /* @__PURE__ */ jsx18(
|
|
4577
|
+
stage === "done" && done ? /* @__PURE__ */ jsxs18(VaultSection, { title: "Result", children: [
|
|
4578
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Created", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.created.length }) }),
|
|
4579
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Skipped", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.skipped }) }),
|
|
4580
|
+
/* @__PURE__ */ jsx18(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx18("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
|
|
4581
|
+
done.untried.length > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.untried.length }) }) : null,
|
|
4582
|
+
done.withOtp > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Codes", children: /* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground", children: [
|
|
4597
4583
|
plural(done.withOtp, "login"),
|
|
4598
4584
|
" still need the one-time password added."
|
|
4599
4585
|
] }) }) : null,
|
|
4600
|
-
done.failed.map((f) => /* @__PURE__ */ jsx18(
|
|
4586
|
+
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))
|
|
4601
4587
|
] }) : null,
|
|
4602
4588
|
/* @__PURE__ */ jsx18(ErrorLine, { message: error })
|
|
4603
4589
|
] });
|
|
@@ -4657,11 +4643,13 @@ import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCo
|
|
|
4657
4643
|
import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
|
|
4658
4644
|
|
|
4659
4645
|
// src/activity/FilesSection.tsx
|
|
4646
|
+
import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
|
|
4660
4647
|
import { useRef as useRef13, useState as useState20 } from "react";
|
|
4661
4648
|
import { Badge as Badge5, Button as Button16, Field as Field7, SegmentedControl as SegmentedControl4 } from "@ai-matrx/design-system/controls";
|
|
4662
4649
|
import { cn as cn9 } from "@ai-matrx/design-system";
|
|
4663
4650
|
import { confirm as confirm6 } from "@ai-matrx/kit/confirm-opener";
|
|
4664
4651
|
import { downloadFile as downloadFile3 } from "@ai-matrx/kit/download";
|
|
4652
|
+
import { DownloadIcon } from "@ai-matrx/design-system/icons";
|
|
4665
4653
|
import { Fragment as Fragment12, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4666
4654
|
var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
4667
4655
|
var TOO_BIG = "Files over 25 MB can't be stored.";
|
|
@@ -4720,7 +4708,7 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4720
4708
|
onDragLeave: canEdit ? () => setDragging(false) : void 0,
|
|
4721
4709
|
onDrop: canEdit ? drop : void 0,
|
|
4722
4710
|
children: /* @__PURE__ */ jsxs19(
|
|
4723
|
-
|
|
4711
|
+
VaultSection,
|
|
4724
4712
|
{
|
|
4725
4713
|
title: "Files",
|
|
4726
4714
|
actions: canEdit ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
|
|
@@ -4731,11 +4719,11 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4731
4719
|
} }) : null,
|
|
4732
4720
|
item.attachments.map(
|
|
4733
4721
|
(a) => canEdit ? /* @__PURE__ */ jsx20(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ jsx20(
|
|
4734
|
-
|
|
4722
|
+
VaultRow,
|
|
4735
4723
|
{
|
|
4736
4724
|
label: a.label,
|
|
4737
4725
|
hint: a.description || void 0,
|
|
4738
|
-
actions: a.handling === "sealed" ? /* @__PURE__ */ jsx20(Badge5, { icon: /* @__PURE__ */ jsx20(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(
|
|
4726
|
+
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,
|
|
4739
4727
|
children: /* @__PURE__ */ jsx20(FileName, { file: a })
|
|
4740
4728
|
},
|
|
4741
4729
|
a.id
|
|
@@ -4761,12 +4749,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4761
4749
|
}
|
|
4762
4750
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4763
4751
|
/* @__PURE__ */ jsx20(
|
|
4764
|
-
|
|
4752
|
+
VaultRow,
|
|
4765
4753
|
{
|
|
4766
4754
|
label: a.label,
|
|
4767
4755
|
hint: a.description || void 0,
|
|
4768
4756
|
actions: /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4769
|
-
canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(
|
|
4757
|
+
canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
|
|
4770
4758
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
|
|
4771
4759
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
|
|
4772
4760
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
|
|
@@ -4797,7 +4785,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
|
|
|
4797
4785
|
function FileName({ file }) {
|
|
4798
4786
|
return /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4799
4787
|
/* @__PURE__ */ jsx20("span", { className: "truncate", children: file.fileName }),
|
|
4800
|
-
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4788
|
+
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.sizeBytes) })
|
|
4801
4789
|
] });
|
|
4802
4790
|
}
|
|
4803
4791
|
function Protection({ value, locked, onChange }) {
|
|
@@ -4820,13 +4808,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
|
|
|
4820
4808
|
await onAdd({ label: label.trim(), description: description.trim() || null, handling });
|
|
4821
4809
|
}
|
|
4822
4810
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4823
|
-
/* @__PURE__ */ jsx20(
|
|
4811
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "New file", children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
4824
4812
|
/* @__PURE__ */ jsx20("span", { className: "truncate", children: file.name }),
|
|
4825
|
-
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children:
|
|
4813
|
+
/* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.size) })
|
|
4826
4814
|
] }) }),
|
|
4827
|
-
/* @__PURE__ */ jsx20(
|
|
4828
|
-
/* @__PURE__ */ jsx20(
|
|
4829
|
-
/* @__PURE__ */ jsx20(
|
|
4815
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4816
|
+
/* @__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) }) }),
|
|
4817
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: false, onChange: setHandling }) }),
|
|
4830
4818
|
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4831
4819
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4832
4820
|
/* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
|
|
@@ -4844,10 +4832,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
|
|
|
4844
4832
|
await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
|
|
4845
4833
|
}
|
|
4846
4834
|
return /* @__PURE__ */ jsxs19(Fragment12, { children: [
|
|
4847
|
-
/* @__PURE__ */ jsx20(
|
|
4848
|
-
/* @__PURE__ */ jsx20(
|
|
4849
|
-
/* @__PURE__ */ jsx20(
|
|
4850
|
-
/* @__PURE__ */ jsx20(
|
|
4835
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
|
|
4836
|
+
/* @__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) }) }),
|
|
4837
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "File name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
|
|
4838
|
+
/* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
|
|
4851
4839
|
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
|
|
4852
4840
|
/* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
|
|
4853
4841
|
/* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
|
|
@@ -4866,6 +4854,7 @@ function confirmSeal(label) {
|
|
|
4866
4854
|
// src/fields/RecoveryCodesRow.tsx
|
|
4867
4855
|
import { useState as useState21 } from "react";
|
|
4868
4856
|
import { Badge as Badge6, Button as Button17, Textarea as Textarea3 } from "@ai-matrx/design-system/controls";
|
|
4857
|
+
import { CopyIcon as CopyIcon6 } from "@ai-matrx/design-system/icons";
|
|
4869
4858
|
import { Fragment as Fragment13, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4870
4859
|
var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
4871
4860
|
var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
@@ -4906,7 +4895,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4906
4895
|
};
|
|
4907
4896
|
if (draft !== null) {
|
|
4908
4897
|
return /* @__PURE__ */ jsxs20(
|
|
4909
|
-
|
|
4898
|
+
VaultRow,
|
|
4910
4899
|
{
|
|
4911
4900
|
label: "Recovery codes",
|
|
4912
4901
|
top: true,
|
|
@@ -4926,7 +4915,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4926
4915
|
}
|
|
4927
4916
|
if (!field) {
|
|
4928
4917
|
if (!canEdit) return null;
|
|
4929
|
-
return /* @__PURE__ */ jsx21(
|
|
4918
|
+
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" }) });
|
|
4930
4919
|
}
|
|
4931
4920
|
const sealed = field.handling === "sealed";
|
|
4932
4921
|
const canSee = !sealed && item.capabilities.canReveal;
|
|
@@ -4948,7 +4937,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4948
4937
|
});
|
|
4949
4938
|
};
|
|
4950
4939
|
return /* @__PURE__ */ jsx21(
|
|
4951
|
-
|
|
4940
|
+
VaultRow,
|
|
4952
4941
|
{
|
|
4953
4942
|
label: "Recovery codes",
|
|
4954
4943
|
top: codes !== null,
|
|
@@ -4959,7 +4948,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4959
4948
|
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: [
|
|
4960
4949
|
codes.map((code, i) => /* @__PURE__ */ jsxs20("li", { className: "flex min-h-7 items-center gap-1", children: [
|
|
4961
4950
|
/* @__PURE__ */ jsx21("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
|
|
4962
|
-
/* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(
|
|
4951
|
+
/* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CopyIcon6, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
|
|
4963
4952
|
canEdit ? /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
|
|
4964
4953
|
] }, `${i}-${code}`)),
|
|
4965
4954
|
error ? /* @__PURE__ */ jsx21("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
|
|
@@ -4968,33 +4957,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4968
4957
|
);
|
|
4969
4958
|
}
|
|
4970
4959
|
|
|
4960
|
+
// src/ItemPane.tsx
|
|
4961
|
+
import { HistoryIcon, SettingsIcon, UsersIcon as UsersIcon2 } from "@ai-matrx/design-system/icons";
|
|
4962
|
+
import { dropKeptDraft, keepDraft, readKeptDraft } from "@ai-matrx/kit/drafts";
|
|
4963
|
+
|
|
4971
4964
|
// src/draft-keep.ts
|
|
4972
4965
|
var PREFIX = "matrx.vault.draft:";
|
|
4973
4966
|
function draftKey(itemId, definitionKey) {
|
|
4974
4967
|
return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
|
|
4975
4968
|
}
|
|
4976
|
-
function
|
|
4977
|
-
|
|
4978
|
-
try {
|
|
4979
|
-
globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
|
|
4980
|
-
} catch {
|
|
4981
|
-
}
|
|
4982
|
-
}
|
|
4983
|
-
function readKeptDraft(key, basedOn) {
|
|
4984
|
-
try {
|
|
4985
|
-
const raw = globalThis.sessionStorage?.getItem(key);
|
|
4986
|
-
if (!raw) return null;
|
|
4987
|
-
const kept = JSON.parse(raw);
|
|
4988
|
-
return kept.basedOn === basedOn ? kept.draft : null;
|
|
4989
|
-
} catch {
|
|
4990
|
-
return null;
|
|
4991
|
-
}
|
|
4992
|
-
}
|
|
4993
|
-
function dropKeptDraft(key) {
|
|
4994
|
-
try {
|
|
4995
|
-
globalThis.sessionStorage?.removeItem(key);
|
|
4996
|
-
} catch {
|
|
4997
|
-
}
|
|
4969
|
+
function keptFieldsOf(d) {
|
|
4970
|
+
return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
|
|
4998
4971
|
}
|
|
4999
4972
|
|
|
5000
4973
|
// src/extension/page-logic.ts
|
|
@@ -5141,6 +5114,7 @@ import { useEffect as useEffect15, useState as useState25 } from "react";
|
|
|
5141
5114
|
import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
|
|
5142
5115
|
import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select8 } from "@ai-matrx/design-system/controls";
|
|
5143
5116
|
import { cn as cn11 } from "@ai-matrx/design-system";
|
|
5117
|
+
import { UsersIcon } from "@ai-matrx/design-system/icons";
|
|
5144
5118
|
|
|
5145
5119
|
// src/sharing/logic.ts
|
|
5146
5120
|
var LEVEL_OPTIONS = [
|
|
@@ -5172,7 +5146,7 @@ function copyRefusal(message2) {
|
|
|
5172
5146
|
return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
|
|
5173
5147
|
}
|
|
5174
5148
|
var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
|
|
5175
|
-
function
|
|
5149
|
+
function itemMoveConsequence(item, to) {
|
|
5176
5150
|
if (item.authenticator) return "One-time password stays behind; set it up again";
|
|
5177
5151
|
return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
|
|
5178
5152
|
}
|
|
@@ -5262,7 +5236,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5262
5236
|
const to = destinationOf(moveChoice.value);
|
|
5263
5237
|
const ok = await confirm7({
|
|
5264
5238
|
title: `Move to ${moveChoice.label}?`,
|
|
5265
|
-
description: `"${item.name}" stays the same item, so everything using it keeps working. ${
|
|
5239
|
+
description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
|
|
5266
5240
|
confirmLabel: "Move"
|
|
5267
5241
|
});
|
|
5268
5242
|
if (!ok) return;
|
|
@@ -5298,17 +5272,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5298
5272
|
/* @__PURE__ */ jsx24(StatusLine, { error, notice }),
|
|
5299
5273
|
/* @__PURE__ */ jsx24(Button19, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
|
|
5300
5274
|
] }),
|
|
5301
|
-
children: nothing ? /* @__PURE__ */ jsx24(
|
|
5275
|
+
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: [
|
|
5302
5276
|
canMove && moves.length > 0 ? /* @__PURE__ */ jsx24(
|
|
5303
|
-
|
|
5277
|
+
VaultRow,
|
|
5304
5278
|
{
|
|
5305
5279
|
label: "Move to",
|
|
5306
|
-
hint: moveChoice ?
|
|
5280
|
+
hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
|
|
5307
5281
|
actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
|
|
5308
5282
|
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] })
|
|
5309
5283
|
}
|
|
5310
5284
|
) : null,
|
|
5311
|
-
canGive ? /* @__PURE__ */ jsx24(
|
|
5285
|
+
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(
|
|
5312
5286
|
Field8,
|
|
5313
5287
|
{
|
|
5314
5288
|
className: "w-full",
|
|
@@ -5322,7 +5296,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5322
5296
|
onChange: (e) => setEmail(e.target.value)
|
|
5323
5297
|
}
|
|
5324
5298
|
) }) : null,
|
|
5325
|
-
canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(
|
|
5299
|
+
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
|
|
5326
5300
|
] })
|
|
5327
5301
|
}
|
|
5328
5302
|
);
|
|
@@ -5404,7 +5378,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5404
5378
|
}
|
|
5405
5379
|
};
|
|
5406
5380
|
if (!item.capabilities.canManage) {
|
|
5407
|
-
return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(
|
|
5381
|
+
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." }) }) });
|
|
5408
5382
|
}
|
|
5409
5383
|
return /* @__PURE__ */ jsxs23(
|
|
5410
5384
|
Panel,
|
|
@@ -5417,9 +5391,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5417
5391
|
/* @__PURE__ */ jsx25(Button20, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
|
|
5418
5392
|
] }),
|
|
5419
5393
|
children: [
|
|
5420
|
-
/* @__PURE__ */ jsxs23(
|
|
5394
|
+
/* @__PURE__ */ jsxs23(VaultSection, { title: "Who has access", children: [
|
|
5421
5395
|
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" }) }),
|
|
5422
|
-
isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph:
|
|
5396
|
+
isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ jsx25(
|
|
5423
5397
|
Select8,
|
|
5424
5398
|
{
|
|
5425
5399
|
variant: "inline",
|
|
@@ -5480,7 +5454,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
|
|
|
5480
5454
|
const [level, setLevel] = useState25("use");
|
|
5481
5455
|
const chosen = open.find((o) => o.id === target);
|
|
5482
5456
|
if (item.owner.kind !== "me") return null;
|
|
5483
|
-
return /* @__PURE__ */ jsx25(
|
|
5457
|
+
return /* @__PURE__ */ jsx25(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs23(Fragment14, { children: [
|
|
5484
5458
|
/* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
|
|
5485
5459
|
/* @__PURE__ */ jsx25(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
5486
5460
|
/* @__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 }))] }),
|
|
@@ -5530,7 +5504,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
|
|
|
5530
5504
|
const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
|
|
5531
5505
|
if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
|
|
5532
5506
|
};
|
|
5533
|
-
return /* @__PURE__ */ jsxs23(
|
|
5507
|
+
return /* @__PURE__ */ jsxs23(VaultSection, { title: `${organizationName} vault access`, children: [
|
|
5534
5508
|
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(
|
|
5535
5509
|
Select8,
|
|
5536
5510
|
{
|
|
@@ -5606,7 +5580,7 @@ function ItemPane(props) {
|
|
|
5606
5580
|
if (was && was.id === id && was.mode === mode && editing) {
|
|
5607
5581
|
setDraft((d) => rebaseDraft(was.base, base, d));
|
|
5608
5582
|
} else {
|
|
5609
|
-
const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
|
|
5583
|
+
const kept = editing ? readKeptDraft(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
|
|
5610
5584
|
setDraft(kept ? { ...base, ...kept } : base);
|
|
5611
5585
|
setTagsText((kept ?? base).tags.join(", "));
|
|
5612
5586
|
setError(null);
|
|
@@ -5621,7 +5595,7 @@ function ItemPane(props) {
|
|
|
5621
5595
|
useEffect16(() => onDirty(dirty), [dirty, onDirty]);
|
|
5622
5596
|
const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
|
|
5623
5597
|
useEffect16(() => {
|
|
5624
|
-
if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new"
|
|
5598
|
+
if (editing && dirty) keepDraft(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
|
|
5625
5599
|
else if (!editing) dropKeptDraft(keepKey);
|
|
5626
5600
|
}, [editing, dirty, draft, keepKey, item?.updatedAt]);
|
|
5627
5601
|
useEffect16(() => {
|
|
@@ -5708,7 +5682,7 @@ function ItemPane(props) {
|
|
|
5708
5682
|
const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
|
|
5709
5683
|
const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
|
|
5710
5684
|
const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
|
|
5711
|
-
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(
|
|
5685
|
+
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;
|
|
5712
5686
|
const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
|
|
5713
5687
|
const descriptionVisible = showDescription || draft.description !== "";
|
|
5714
5688
|
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: [
|
|
@@ -5765,7 +5739,7 @@ function ItemPane(props) {
|
|
|
5765
5739
|
"Send securely"
|
|
5766
5740
|
] }) : null,
|
|
5767
5741
|
/* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
|
|
5768
|
-
/* @__PURE__ */ jsx26(
|
|
5742
|
+
/* @__PURE__ */ jsx26(HistoryIcon, { className: "size-4" }),
|
|
5769
5743
|
"Password history"
|
|
5770
5744
|
] }),
|
|
5771
5745
|
/* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
|
|
@@ -5773,7 +5747,7 @@ function ItemPane(props) {
|
|
|
5773
5747
|
"Activity"
|
|
5774
5748
|
] }),
|
|
5775
5749
|
canEdit ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
|
|
5776
|
-
/* @__PURE__ */ jsx26(
|
|
5750
|
+
/* @__PURE__ */ jsx26(SettingsIcon, { className: "size-4" }),
|
|
5777
5751
|
"Settings"
|
|
5778
5752
|
] }) : null,
|
|
5779
5753
|
canManage ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
@@ -5793,8 +5767,8 @@ function ItemPane(props) {
|
|
|
5793
5767
|
error ? /* @__PURE__ */ jsx26("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
|
|
5794
5768
|
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,
|
|
5795
5769
|
/* @__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: [
|
|
5796
|
-
/* @__PURE__ */ jsxs24(
|
|
5797
|
-
mode === "new" ? /* @__PURE__ */ jsx26(
|
|
5770
|
+
/* @__PURE__ */ jsxs24(VaultSection, { children: [
|
|
5771
|
+
mode === "new" ? /* @__PURE__ */ jsx26(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx26(
|
|
5798
5772
|
OptionCombobox,
|
|
5799
5773
|
{
|
|
5800
5774
|
value: owner,
|
|
@@ -5815,7 +5789,7 @@ function ItemPane(props) {
|
|
|
5815
5789
|
/* @__PURE__ */ jsx26(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
|
|
5816
5790
|
mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5817
5791
|
/* @__PURE__ */ jsx26(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
|
|
5818
|
-
declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(
|
|
5792
|
+
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
|
|
5819
5793
|
] }) : null,
|
|
5820
5794
|
declared.map((f) => {
|
|
5821
5795
|
const existing = item?.fields.find((x) => x.key === f.key);
|
|
@@ -5835,7 +5809,7 @@ function ItemPane(props) {
|
|
|
5835
5809
|
actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5836
5810
|
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,
|
|
5837
5811
|
secretKind ? /* @__PURE__ */ jsx26(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
|
|
5838
|
-
existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(
|
|
5812
|
+
existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
|
|
5839
5813
|
] })
|
|
5840
5814
|
},
|
|
5841
5815
|
f.key
|
|
@@ -5853,7 +5827,7 @@ function ItemPane(props) {
|
|
|
5853
5827
|
removeLabel: `Delete ${f.label}`,
|
|
5854
5828
|
actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5855
5829
|
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,
|
|
5856
|
-
/* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(
|
|
5830
|
+
/* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
|
|
5857
5831
|
] })
|
|
5858
5832
|
},
|
|
5859
5833
|
f.id
|
|
@@ -5886,9 +5860,9 @@ function ItemPane(props) {
|
|
|
5886
5860
|
/* @__PURE__ */ jsx26(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
|
|
5887
5861
|
item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5888
5862
|
] }),
|
|
5889
|
-
/* @__PURE__ */ jsx26(
|
|
5863
|
+
/* @__PURE__ */ jsx26(VaultSection, { children: /* @__PURE__ */ jsx26(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
|
|
5890
5864
|
/* @__PURE__ */ jsxs24(
|
|
5891
|
-
|
|
5865
|
+
VaultSection,
|
|
5892
5866
|
{
|
|
5893
5867
|
title: "More",
|
|
5894
5868
|
actions: /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
|
|
@@ -5922,7 +5896,7 @@ function ItemPane(props) {
|
|
|
5922
5896
|
),
|
|
5923
5897
|
filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: true }) : null
|
|
5924
5898
|
] }) : item ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
5925
|
-
/* @__PURE__ */ jsxs24(
|
|
5899
|
+
/* @__PURE__ */ jsxs24(VaultSection, { children: [
|
|
5926
5900
|
declared.map((f) => {
|
|
5927
5901
|
if (f.storage === "metadata") {
|
|
5928
5902
|
const v = metaValue(f.key);
|
|
@@ -5937,10 +5911,10 @@ function ItemPane(props) {
|
|
|
5937
5911
|
item.authenticator ? /* @__PURE__ */ jsx26(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ jsx26(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
|
|
5938
5912
|
!item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
|
|
5939
5913
|
] }),
|
|
5940
|
-
/* @__PURE__ */ jsx26(
|
|
5941
|
-
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(
|
|
5914
|
+
/* @__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" }) }),
|
|
5915
|
+
item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(VaultSection, { title: "More", children: [
|
|
5942
5916
|
item.description ? /* @__PURE__ */ jsx26(PlainRow, { label: "Description", value: item.description }) : null,
|
|
5943
|
-
item.tags.length > 0 ? /* @__PURE__ */ jsx26(
|
|
5917
|
+
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,
|
|
5944
5918
|
viewCustom.map((c) => /* @__PURE__ */ jsx26(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
|
|
5945
5919
|
] }) : null,
|
|
5946
5920
|
filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
|
|
@@ -6188,13 +6162,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
|
|
|
6188
6162
|
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" })
|
|
6189
6163
|
] }),
|
|
6190
6164
|
children: [
|
|
6191
|
-
loading ? /* @__PURE__ */ jsx28(
|
|
6192
|
-
/* @__PURE__ */ jsx28(
|
|
6193
|
-
/* @__PURE__ */ jsx28(
|
|
6194
|
-
preview.passkeys === 1 ? /* @__PURE__ */ jsx28(
|
|
6195
|
-
/* @__PURE__ */ jsx28(
|
|
6196
|
-
preview.priorWasDisabled ? /* @__PURE__ */ jsx28(
|
|
6197
|
-
] }) : preview ? /* @__PURE__ */ jsx28(
|
|
6165
|
+
loading ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(VaultSection, { title: "Comes back", children: [
|
|
6166
|
+
/* @__PURE__ */ jsx28(VaultRow, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
|
|
6167
|
+
/* @__PURE__ */ jsx28(VaultRow, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
|
|
6168
|
+
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,
|
|
6169
|
+
/* @__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" }) }),
|
|
6170
|
+
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
|
|
6171
|
+
] }) : 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." }) }),
|
|
6198
6172
|
error ? /* @__PURE__ */ jsx28("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
|
|
6199
6173
|
]
|
|
6200
6174
|
}
|
|
@@ -6226,7 +6200,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6226
6200
|
};
|
|
6227
6201
|
return /* @__PURE__ */ jsxs27("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
|
|
6228
6202
|
header,
|
|
6229
|
-
/* @__PURE__ */ jsx29(
|
|
6203
|
+
/* @__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) => (
|
|
6230
6204
|
// A list row, not a field row: the name gets the whole width (on a phone a label column
|
|
6231
6205
|
// left "Vau…" for every row), the deletion date sits under it.
|
|
6232
6206
|
/* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
|
|
@@ -6246,6 +6220,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6246
6220
|
import { useMemo as useMemo4, useState as useState30 } from "react";
|
|
6247
6221
|
import { cn as cn14 } from "@ai-matrx/design-system";
|
|
6248
6222
|
import { Button as Button25, Field as Field10, SearchField as SearchField2 } from "@ai-matrx/design-system/controls";
|
|
6223
|
+
import { GlobeIcon as GlobeIcon3 } from "@ai-matrx/design-system/icons";
|
|
6249
6224
|
import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
6250
6225
|
function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
6251
6226
|
const [search, setSearch] = useState30("");
|
|
@@ -6280,7 +6255,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
|
6280
6255
|
"aria-label": "Website address",
|
|
6281
6256
|
inputMode: "url",
|
|
6282
6257
|
autoFocus: true,
|
|
6283
|
-
icon: /* @__PURE__ */ jsx30(
|
|
6258
|
+
icon: /* @__PURE__ */ jsx30(GlobeIcon3, {})
|
|
6284
6259
|
}
|
|
6285
6260
|
),
|
|
6286
6261
|
guess && login ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
|
|
@@ -6530,9 +6505,9 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6530
6505
|
] }),
|
|
6531
6506
|
children: [
|
|
6532
6507
|
remedy ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
|
|
6533
|
-
/* @__PURE__ */ jsxs29(
|
|
6534
|
-
/* @__PURE__ */ jsx31(
|
|
6535
|
-
/* @__PURE__ */ jsx31(
|
|
6508
|
+
/* @__PURE__ */ jsxs29(VaultSection, { title: "Recipient", children: [
|
|
6509
|
+
/* @__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" }) }),
|
|
6510
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx31(
|
|
6536
6511
|
Field11,
|
|
6537
6512
|
{
|
|
6538
6513
|
type: "tel",
|
|
@@ -6548,8 +6523,8 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6548
6523
|
className: "w-full"
|
|
6549
6524
|
}
|
|
6550
6525
|
) }),
|
|
6551
|
-
/* @__PURE__ */ jsx31(
|
|
6552
|
-
plan && !plan.same ? /* @__PURE__ */ jsx31(
|
|
6526
|
+
/* @__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" }) }),
|
|
6527
|
+
plan && !plan.same ? /* @__PURE__ */ jsx31(VaultRow, { label: "Link by", children: /* @__PURE__ */ jsx31(
|
|
6553
6528
|
SegmentedControl5,
|
|
6554
6529
|
{
|
|
6555
6530
|
"aria-label": "Send the link by",
|
|
@@ -6561,26 +6536,26 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6561
6536
|
]
|
|
6562
6537
|
}
|
|
6563
6538
|
) }) : null,
|
|
6564
|
-
email.trim() ? /* @__PURE__ */ jsx31(
|
|
6539
|
+
email.trim() ? /* @__PURE__ */ jsx31(VaultRow, { label: "Delivery", children: /* @__PURE__ */ jsx31("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
|
|
6565
6540
|
] }),
|
|
6566
|
-
/* @__PURE__ */ jsx31(
|
|
6541
|
+
/* @__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: [
|
|
6567
6542
|
/* @__PURE__ */ jsx31(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
|
|
6568
6543
|
/* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
|
|
6569
6544
|
!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
|
|
6570
6545
|
] }, f.key)) }),
|
|
6571
|
-
/* @__PURE__ */ jsx31(
|
|
6572
|
-
options ? /* @__PURE__ */ jsxs29(
|
|
6573
|
-
/* @__PURE__ */ jsx31(
|
|
6574
|
-
/* @__PURE__ */ jsx31(
|
|
6546
|
+
/* @__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) }) }) }),
|
|
6547
|
+
options ? /* @__PURE__ */ jsxs29(VaultSection, { title: "Link", children: [
|
|
6548
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
|
|
6549
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Link expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
|
|
6575
6550
|
"After ",
|
|
6576
6551
|
lifetimeWords(options.linkMinutes)
|
|
6577
6552
|
] }) }),
|
|
6578
|
-
/* @__PURE__ */ jsx31(
|
|
6553
|
+
/* @__PURE__ */ jsx31(VaultRow, { label: "Code expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
|
|
6579
6554
|
"After ",
|
|
6580
6555
|
lifetimeWords(options.codeMinutes)
|
|
6581
6556
|
] }) })
|
|
6582
6557
|
] }) : null,
|
|
6583
|
-
sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(
|
|
6558
|
+
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: [
|
|
6584
6559
|
/* @__PURE__ */ jsx31(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
|
|
6585
6560
|
row.status === "pending" ? /* @__PURE__ */ jsx31(Button26, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
|
|
6586
6561
|
] }, row.id)) }) : null
|
|
@@ -6722,10 +6697,10 @@ function DevicesPanel({ port, onClose }) {
|
|
|
6722
6697
|
};
|
|
6723
6698
|
return /* @__PURE__ */ jsxs30(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
|
|
6724
6699
|
/* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
|
|
6725
|
-
/* @__PURE__ */ jsx32(
|
|
6700
|
+
/* @__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) => {
|
|
6726
6701
|
const off = isRevoked(device);
|
|
6727
6702
|
return /* @__PURE__ */ jsx32(
|
|
6728
|
-
|
|
6703
|
+
VaultRow,
|
|
6729
6704
|
{
|
|
6730
6705
|
label: off ? "Turned off" : "Can fill",
|
|
6731
6706
|
hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
|
|
@@ -6813,18 +6788,18 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6813
6788
|
/* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
|
|
6814
6789
|
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
|
|
6815
6790
|
] });
|
|
6816
|
-
return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(
|
|
6791
|
+
return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(VaultSection, { children: /* @__PURE__ */ jsxs30(Empty, { children: [
|
|
6817
6792
|
"This link names no key. Start again from ",
|
|
6818
6793
|
where,
|
|
6819
6794
|
"."
|
|
6820
6795
|
] }) }) : /* @__PURE__ */ jsxs30(Fragment17, { children: [
|
|
6821
|
-
/* @__PURE__ */ jsxs30(
|
|
6822
|
-
/* @__PURE__ */ jsx32(
|
|
6823
|
-
name ? /* @__PURE__ */ jsx32(
|
|
6824
|
-
/* @__PURE__ */ jsx32(
|
|
6796
|
+
/* @__PURE__ */ jsxs30(VaultSection, { title: "What is asking", children: [
|
|
6797
|
+
/* @__PURE__ */ jsx32(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
|
|
6798
|
+
name ? /* @__PURE__ */ jsx32(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
|
|
6799
|
+
/* @__PURE__ */ jsx32(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx32("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
|
|
6825
6800
|
] }),
|
|
6826
6801
|
/* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
|
|
6827
|
-
/* @__PURE__ */ jsx32(
|
|
6802
|
+
/* @__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: [
|
|
6828
6803
|
"Return to ",
|
|
6829
6804
|
where,
|
|
6830
6805
|
" by ",
|
|
@@ -6835,7 +6810,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6835
6810
|
where,
|
|
6836
6811
|
"."
|
|
6837
6812
|
] }) : !here ? /* @__PURE__ */ jsx32(
|
|
6838
|
-
|
|
6813
|
+
VaultRow,
|
|
6839
6814
|
{
|
|
6840
6815
|
label: "Passkey",
|
|
6841
6816
|
hint: `Passkeys work only on ${passkeys.rpId}`,
|
|
@@ -6843,14 +6818,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6843
6818
|
children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: "Not on this page" })
|
|
6844
6819
|
}
|
|
6845
6820
|
) : 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(
|
|
6846
|
-
|
|
6821
|
+
VaultRow,
|
|
6847
6822
|
{
|
|
6848
6823
|
label: "Passkey",
|
|
6849
6824
|
hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
|
|
6850
6825
|
actions: /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
|
|
6851
6826
|
children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
|
|
6852
6827
|
}
|
|
6853
|
-
) : /* @__PURE__ */ jsx32(
|
|
6828
|
+
) : /* @__PURE__ */ jsx32(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Ready" }) }) })
|
|
6854
6829
|
] }) });
|
|
6855
6830
|
}
|
|
6856
6831
|
|
|
@@ -7128,7 +7103,7 @@ var TONE = {
|
|
|
7128
7103
|
};
|
|
7129
7104
|
function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
|
|
7130
7105
|
if (!bridge) {
|
|
7131
|
-
return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(
|
|
7106
|
+
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." }) }) });
|
|
7132
7107
|
}
|
|
7133
7108
|
return /* @__PURE__ */ jsx33(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
|
|
7134
7109
|
}
|
|
@@ -7175,25 +7150,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7175
7150
|
/* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" })
|
|
7176
7151
|
] }) : /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: onClose, children: "Close" });
|
|
7177
7152
|
return /* @__PURE__ */ jsxs31(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
|
|
7178
|
-
screen.kind === "idle" ? /* @__PURE__ */ jsxs31(
|
|
7179
|
-
/* @__PURE__ */ jsx33(
|
|
7180
|
-
/* @__PURE__ */ jsx33(
|
|
7181
|
-
/* @__PURE__ */ jsx33(
|
|
7153
|
+
screen.kind === "idle" ? /* @__PURE__ */ jsxs31(VaultSection, { children: [
|
|
7154
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
|
|
7155
|
+
/* @__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" }) }),
|
|
7156
|
+
/* @__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" }) })
|
|
7182
7157
|
] }) : null,
|
|
7183
|
-
preview ? /* @__PURE__ */ jsx33(
|
|
7158
|
+
preview ? /* @__PURE__ */ jsx33(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx33(
|
|
7184
7159
|
Windowed,
|
|
7185
7160
|
{
|
|
7186
7161
|
items: preview.slots,
|
|
7187
|
-
render: (slot) => /* @__PURE__ */ jsx33(
|
|
7162
|
+
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)
|
|
7188
7163
|
}
|
|
7189
7164
|
) }) : null,
|
|
7190
|
-
status && !preview ? /* @__PURE__ */ jsxs31(
|
|
7191
|
-
/* @__PURE__ */ jsx33(
|
|
7192
|
-
/* @__PURE__ */ jsx33(
|
|
7193
|
-
/* @__PURE__ */ jsx33(
|
|
7194
|
-
/* @__PURE__ */ jsx33(
|
|
7195
|
-
status.uncertain > 0 ? /* @__PURE__ */ jsx33(
|
|
7196
|
-
status.not_attempted > 0 ? /* @__PURE__ */ jsx33(
|
|
7165
|
+
status && !preview ? /* @__PURE__ */ jsxs31(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
|
|
7166
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
|
|
7167
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
|
|
7168
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
|
|
7169
|
+
/* @__PURE__ */ jsx33(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
|
|
7170
|
+
status.uncertain > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
|
|
7171
|
+
status.not_attempted > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.not_attempted }) }) : null
|
|
7197
7172
|
] }) : null,
|
|
7198
7173
|
screen.message ? /* @__PURE__ */ jsx33("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
|
|
7199
7174
|
/* @__PURE__ */ jsx33(ErrorLine, { message: limitError })
|
|
@@ -7204,6 +7179,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7204
7179
|
import { useState as useState38 } from "react";
|
|
7205
7180
|
import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem4, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
|
|
7206
7181
|
import { Button as Button32 } from "@ai-matrx/design-system/controls";
|
|
7182
|
+
import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
|
|
7207
7183
|
|
|
7208
7184
|
// src/extension/CaptureCard.tsx
|
|
7209
7185
|
import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
@@ -7346,6 +7322,7 @@ function FillSetupCard({ fillSetup }) {
|
|
|
7346
7322
|
import { useState as useState37 } from "react";
|
|
7347
7323
|
import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
|
|
7348
7324
|
import { Button as Button31 } from "@ai-matrx/design-system/controls";
|
|
7325
|
+
import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
|
|
7349
7326
|
import { Fragment as Fragment20, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
7350
7327
|
var HOLD_MS = 6e4;
|
|
7351
7328
|
function PageGenerator({ fields }) {
|
|
@@ -7399,11 +7376,11 @@ function PageGenerator({ fields }) {
|
|
|
7399
7376
|
const value = held.value;
|
|
7400
7377
|
return /* @__PURE__ */ jsxs34(Fragment20, { children: [
|
|
7401
7378
|
/* @__PURE__ */ jsx36(
|
|
7402
|
-
|
|
7379
|
+
VaultRow,
|
|
7403
7380
|
{
|
|
7404
7381
|
label: "New password",
|
|
7405
7382
|
actions: /* @__PURE__ */ jsxs34(Fragment20, { children: [
|
|
7406
|
-
value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(
|
|
7383
|
+
value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(CopyIcon7, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
|
|
7407
7384
|
/* @__PURE__ */ jsxs34(Popover2, { open, onOpenChange: setOpen, children: [
|
|
7408
7385
|
/* @__PURE__ */ jsx36(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx36(Button31, { variant: "outline", icon: /* @__PURE__ */ jsx36(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
|
|
7409
7386
|
/* @__PURE__ */ jsx36(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx36(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
|
|
@@ -7412,7 +7389,7 @@ function PageGenerator({ fields }) {
|
|
|
7412
7389
|
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" })
|
|
7413
7390
|
}
|
|
7414
7391
|
),
|
|
7415
|
-
value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(
|
|
7392
|
+
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
|
|
7416
7393
|
] });
|
|
7417
7394
|
}
|
|
7418
7395
|
|
|
@@ -7474,7 +7451,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7474
7451
|
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: [
|
|
7475
7452
|
header,
|
|
7476
7453
|
/* @__PURE__ */ jsxs35("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
|
|
7477
|
-
/* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback:
|
|
7454
|
+
/* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
|
|
7478
7455
|
/* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
|
|
7479
7456
|
page.refresh ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
|
|
7480
7457
|
onBrowse ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
|
|
@@ -7482,7 +7459,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7482
7459
|
fillSetup ? /* @__PURE__ */ jsx37(FillSetupCard, { fillSetup }) : null,
|
|
7483
7460
|
capture ? /* @__PURE__ */ jsx37(CaptureCard, { capture, onChanged }) : null,
|
|
7484
7461
|
/* @__PURE__ */ jsx37(
|
|
7485
|
-
|
|
7462
|
+
VaultSection,
|
|
7486
7463
|
{
|
|
7487
7464
|
title: "This site",
|
|
7488
7465
|
actions: canSave ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
|
|
@@ -7490,7 +7467,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7490
7467
|
}
|
|
7491
7468
|
),
|
|
7492
7469
|
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,
|
|
7493
|
-
newPasswordFields && canSave ? /* @__PURE__ */ jsx37(
|
|
7470
|
+
newPasswordFields && canSave ? /* @__PURE__ */ jsx37(VaultSection, { children: /* @__PURE__ */ jsx37(PageGenerator, { fields: newPasswordFields }) }) : null
|
|
7494
7471
|
] }) });
|
|
7495
7472
|
}
|
|
7496
7473
|
function Outcome({ said, onDismiss }) {
|
|
@@ -7550,8 +7527,9 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7550
7527
|
|
|
7551
7528
|
// src/Sidebar.tsx
|
|
7552
7529
|
import { useState as useState39 } from "react";
|
|
7553
|
-
import { cn as cn15 } from "@ai-matrx/design-system";
|
|
7530
|
+
import { cn as cn15, useLook as useLook2 } from "@ai-matrx/design-system";
|
|
7554
7531
|
import { Select as Select10 } from "@ai-matrx/design-system/controls";
|
|
7532
|
+
import { GlobeIcon as GlobeIcon5 } from "@ai-matrx/design-system/icons";
|
|
7555
7533
|
import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
7556
7534
|
function vaultChoices(items, organizations, current) {
|
|
7557
7535
|
const n = (f) => items.filter(f).length;
|
|
@@ -7567,7 +7545,7 @@ function vaultChoices(items, organizations, current) {
|
|
|
7567
7545
|
function VaultSelect({ value, choices, onChange }) {
|
|
7568
7546
|
return /* @__PURE__ */ jsx38(Select10, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
|
|
7569
7547
|
}
|
|
7570
|
-
var CATEGORY_GLYPHS = { logins:
|
|
7548
|
+
var CATEGORY_GLYPHS = { logins: GlobeIcon5, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
|
|
7571
7549
|
var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
7572
7550
|
function itemCategory(item, definitions) {
|
|
7573
7551
|
return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
|
|
@@ -7610,13 +7588,14 @@ function viewOptions(views, allCount, deletedCount, hasFavorites, hasRecents, ha
|
|
|
7610
7588
|
];
|
|
7611
7589
|
}
|
|
7612
7590
|
function Entry({ on, glyph: Icon, label, count: count2, onClick }) {
|
|
7591
|
+
const desktop = useLook2() === "desktop";
|
|
7613
7592
|
return /* @__PURE__ */ jsxs36(
|
|
7614
7593
|
"button",
|
|
7615
7594
|
{
|
|
7616
7595
|
type: "button",
|
|
7617
7596
|
"aria-current": on ? "page" : void 0,
|
|
7618
7597
|
onClick,
|
|
7619
|
-
className: cn15("flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm", on ? "bg-sidebar-accent font-medium text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"),
|
|
7598
|
+
className: cn15("flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm", on ? desktop ? "bg-sidebar-accent text-primary" : "bg-sidebar-accent font-medium text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"),
|
|
7620
7599
|
children: [
|
|
7621
7600
|
/* @__PURE__ */ jsx38(Icon, { className: "size-4 shrink-0" }),
|
|
7622
7601
|
/* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
@@ -7631,7 +7610,7 @@ function Group({ title, children }) {
|
|
|
7631
7610
|
children
|
|
7632
7611
|
] });
|
|
7633
7612
|
}
|
|
7634
|
-
function
|
|
7613
|
+
function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
|
|
7635
7614
|
const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
|
|
7636
7615
|
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: [
|
|
7637
7616
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
|
|
@@ -7640,7 +7619,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
|
|
|
7640
7619
|
] }),
|
|
7641
7620
|
/* @__PURE__ */ jsxs36("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
|
|
7642
7621
|
/* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
|
|
7643
|
-
hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph:
|
|
7622
|
+
hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph: GlobeIcon5, label: "This page", onClick: () => onView("page") }) : null,
|
|
7644
7623
|
/* @__PURE__ */ jsx38(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
|
|
7645
7624
|
hasFavorites ? /* @__PURE__ */ jsx38(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
|
|
7646
7625
|
hasRecents ? /* @__PURE__ */ jsx38(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
|
|
@@ -7680,7 +7659,7 @@ var NO_HOST = {};
|
|
|
7680
7659
|
var ITEM_PANELS = {
|
|
7681
7660
|
share: SharePanel,
|
|
7682
7661
|
move: MovePanel,
|
|
7683
|
-
history:
|
|
7662
|
+
history: ItemHistoryPanel,
|
|
7684
7663
|
activity: ActivityPanel,
|
|
7685
7664
|
settings: ItemSettingsPanel,
|
|
7686
7665
|
field: FieldSettingsPanel,
|
|
@@ -7713,7 +7692,7 @@ function VaultApp(props) {
|
|
|
7713
7692
|
const lock = props.host?.lock;
|
|
7714
7693
|
const locked = useLocked(lock);
|
|
7715
7694
|
const port = useMemo6(() => lock ? guardPort(props.port, () => lock.locked()) : props.port, [props.port, lock]);
|
|
7716
|
-
return /* @__PURE__ */ jsx39("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx39(LockedScreen, { lock }) : /* @__PURE__ */ jsx39(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx39(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx39(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx39(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx39(Workspace, { ...props, port }) }) }) }) }) }) });
|
|
7695
|
+
return /* @__PURE__ */ jsx39(LookScope, { look: props.look ?? "web", className: "h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx39(LockedScreen, { lock }) : /* @__PURE__ */ jsx39(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx39(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx39(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx39(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx39(Workspace, { ...props, port }) }) }) }) }) }) }) });
|
|
7717
7696
|
}
|
|
7718
7697
|
function LockedScreen({ lock }) {
|
|
7719
7698
|
const [busy, setBusy] = useState40(false);
|
|
@@ -8071,7 +8050,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
8071
8050
|
] }) : null,
|
|
8072
8051
|
/* @__PURE__ */ jsxs37("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
|
|
8073
8052
|
mode === "full" ? /* @__PURE__ */ jsx39(
|
|
8074
|
-
|
|
8053
|
+
VaultSidebar,
|
|
8075
8054
|
{
|
|
8076
8055
|
vault: loc.vault,
|
|
8077
8056
|
choices,
|