@brftech/filex-core 0.30.0 → 0.31.0
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/README.md +11 -0
- package/dist/filex-core.js +9661 -8550
- package/dist/filex-core.js.map +1 -1
- package/dist/filex-core.umd.cjs +95 -87
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/index.d.ts +368 -64
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +602 -17
- package/src/components/Breadcrumb.vue +4 -10
- package/src/components/E2eRecoveryUnlockModal.vue +168 -0
- package/src/components/EncryptedFolderModal.vue +10 -0
- package/src/components/GalleryView.vue +37 -0
- package/src/components/GridView.vue +39 -0
- package/src/components/ListView.vue +1 -0
- package/src/components/RecoveryKeyModal.vue +133 -0
- package/src/components/SideNav.vue +168 -5
- package/src/components/StarButton.vue +27 -15
- package/src/composables/useFileApi.ts +38 -0
- package/src/composables/useKeyboardShortcuts.ts +7 -0
- package/src/index.ts +27 -1
- package/src/lib/e2ecrypto.ts +528 -70
- package/src/lib/listing.ts +79 -0
- package/src/lib/star.ts +42 -0
- package/src/lib/tags.ts +105 -0
- package/src/locales/en.ts +71 -2
- package/src/locales/tr.ts +71 -2
- package/src/styles/base.css +252 -0
- package/src/types/ExplorerConfig.ts +36 -0
- package/src/types/FileNode.ts +23 -0
package/dist/index.d.ts
CHANGED
|
@@ -61,9 +61,40 @@ declare type __VLS_Props_12 = {
|
|
|
61
61
|
locale: LocaleCode;
|
|
62
62
|
/** True while the parent is creating the folder + uploading the marker. */
|
|
63
63
|
busy?: boolean;
|
|
64
|
+
/** Short id of this installation's E2E escrow key, when one is configured.
|
|
65
|
+
* Shown BEFORE the folder is created: escrow means the operator can open
|
|
66
|
+
* it without the password, and that is not a detail to discover later. */
|
|
67
|
+
escrowKid?: string | null;
|
|
64
68
|
};
|
|
65
69
|
|
|
66
70
|
declare type __VLS_Props_13 = {
|
|
71
|
+
open: boolean;
|
|
72
|
+
locale: LocaleCode;
|
|
73
|
+
/** The key itself. Shown, copied, downloaded — never emitted or stored. */
|
|
74
|
+
recoveryKey: string;
|
|
75
|
+
/** Folder name, for the downloaded file and the dialog copy. */
|
|
76
|
+
folderName?: string;
|
|
77
|
+
/** Set when this installation holds an escrow key for the folder too. */
|
|
78
|
+
escrowKid?: string | null;
|
|
79
|
+
/** 'created' = a new folder; 'upgraded' = an existing folder gained recovery. */
|
|
80
|
+
variant?: 'created' | 'upgraded';
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
declare type __VLS_Props_14 = {
|
|
84
|
+
open: boolean;
|
|
85
|
+
locale: LocaleCode;
|
|
86
|
+
/** The folder has a user recovery key slot (v2 markers created since 0.31). */
|
|
87
|
+
hasRecovery: boolean;
|
|
88
|
+
/** The folder has an escrow slot AND this installation has escrow enabled. */
|
|
89
|
+
hasEscrow: boolean;
|
|
90
|
+
/** Short id of the escrow key the folder was sealed to. */
|
|
91
|
+
escrowKid?: string | null;
|
|
92
|
+
busy?: boolean;
|
|
93
|
+
/** Set by the parent after a failed attempt. */
|
|
94
|
+
error?: string | null;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
declare type __VLS_Props_15 = {
|
|
67
98
|
config: ExplorerConfig;
|
|
68
99
|
/** Which half to open on. */
|
|
69
100
|
initialTab?: 'storages' | 'connect';
|
|
@@ -72,7 +103,7 @@ declare type __VLS_Props_13 = {
|
|
|
72
103
|
closable?: boolean;
|
|
73
104
|
};
|
|
74
105
|
|
|
75
|
-
declare type
|
|
106
|
+
declare type __VLS_Props_16 = {
|
|
76
107
|
fields: StorageField[];
|
|
77
108
|
modelValue: Record<string, unknown>;
|
|
78
109
|
locale: LocaleCode;
|
|
@@ -81,18 +112,18 @@ declare type __VLS_Props_14 = {
|
|
|
81
112
|
disabled?: boolean;
|
|
82
113
|
};
|
|
83
114
|
|
|
84
|
-
declare type
|
|
115
|
+
declare type __VLS_Props_17 = {
|
|
85
116
|
guide: ProtocolGuide;
|
|
86
117
|
locale: LocaleCode;
|
|
87
118
|
};
|
|
88
119
|
|
|
89
|
-
declare type
|
|
120
|
+
declare type __VLS_Props_18 = {
|
|
90
121
|
config: ExplorerConfig;
|
|
91
122
|
/** Storage names the caller may see, for the confinement picker. */
|
|
92
123
|
storages: string[];
|
|
93
124
|
};
|
|
94
125
|
|
|
95
|
-
declare type
|
|
126
|
+
declare type __VLS_Props_19 = {
|
|
96
127
|
config: ExplorerConfig;
|
|
97
128
|
/**
|
|
98
129
|
* Draw the key list and the paste box.
|
|
@@ -106,27 +137,6 @@ declare type __VLS_Props_17 = {
|
|
|
106
137
|
keysVisible?: boolean;
|
|
107
138
|
};
|
|
108
139
|
|
|
109
|
-
declare type __VLS_Props_18 = {
|
|
110
|
-
config: ExplorerConfig;
|
|
111
|
-
/** Storage names the caller may see, for the confinement picker. */
|
|
112
|
-
storages: string[];
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
declare type __VLS_Props_19 = {
|
|
116
|
-
config: ExplorerConfig;
|
|
117
|
-
/**
|
|
118
|
-
* Render the full self-service key manager (scopes, folder confinement,
|
|
119
|
-
* expiry) instead of the one-field minter the guides embed.
|
|
120
|
-
*/
|
|
121
|
-
full?: boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Which protocol the surrounding guide is showing. It only changes the
|
|
124
|
-
* default label — a token minted here works on all of them, and pretending
|
|
125
|
-
* otherwise would have people mint one per protocol.
|
|
126
|
-
*/
|
|
127
|
-
protocol?: string;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
140
|
declare type __VLS_Props_2 = {
|
|
131
141
|
open: boolean;
|
|
132
142
|
locale: LocaleCode;
|
|
@@ -161,6 +171,27 @@ declare type __VLS_Props_2 = {
|
|
|
161
171
|
theme?: 'light' | 'dark' | 'auto';
|
|
162
172
|
};
|
|
163
173
|
|
|
174
|
+
declare type __VLS_Props_20 = {
|
|
175
|
+
config: ExplorerConfig;
|
|
176
|
+
/** Storage names the caller may see, for the confinement picker. */
|
|
177
|
+
storages: string[];
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
declare type __VLS_Props_21 = {
|
|
181
|
+
config: ExplorerConfig;
|
|
182
|
+
/**
|
|
183
|
+
* Render the full self-service key manager (scopes, folder confinement,
|
|
184
|
+
* expiry) instead of the one-field minter the guides embed.
|
|
185
|
+
*/
|
|
186
|
+
full?: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Which protocol the surrounding guide is showing. It only changes the
|
|
189
|
+
* default label — a token minted here works on all of them, and pretending
|
|
190
|
+
* otherwise would have people mint one per protocol.
|
|
191
|
+
*/
|
|
192
|
+
protocol?: string;
|
|
193
|
+
};
|
|
194
|
+
|
|
164
195
|
declare type __VLS_Props_3 = {
|
|
165
196
|
starred: boolean;
|
|
166
197
|
nodeId: number;
|
|
@@ -174,6 +205,17 @@ declare type __VLS_Props_3 = {
|
|
|
174
205
|
authCredentials?: RequestCredentials;
|
|
175
206
|
/** Compact mode for grid view (no label, just the icon). */
|
|
176
207
|
compact?: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Card mode — the same button sitting ON a grid/gallery tile instead of in
|
|
210
|
+
* a list cell: a round translucent chip in the tile's corner. It is the SAME
|
|
211
|
+
* component, deliberately: a card star written separately is a second
|
|
212
|
+
* starring path, and the two drift the first time one of them is fixed.
|
|
213
|
+
*/
|
|
214
|
+
card?: boolean;
|
|
215
|
+
/** Locale for the title/label. ⚠ The strings used to be hardcoded English
|
|
216
|
+
* ("Star"/"Unstar"), which is a Turkish user's only untranslated control in
|
|
217
|
+
* the row. */
|
|
218
|
+
locale?: LocaleCode;
|
|
177
219
|
};
|
|
178
220
|
|
|
179
221
|
declare type __VLS_Props_4 = {
|
|
@@ -399,11 +441,33 @@ export declare interface Capabilities {
|
|
|
399
441
|
/** Longest life a new share link may be given, in days (0 = no ceiling).
|
|
400
442
|
* Read by the share dialogs so they offer only expiries the server keeps. */
|
|
401
443
|
share_max_ttl_days?: number;
|
|
444
|
+
/** Is the caller a person (`'user'` — a session OR their own API token) or an
|
|
445
|
+
* integration (`'app'` — a host proxy, a bot, an MCP client)? The explorer
|
|
446
|
+
* reads it to decide whether to draw the identity-bearing surfaces; see
|
|
447
|
+
* ExplorerConfig.callerKind. Absent on a server older than the app/user
|
|
448
|
+
* token split, which is why every reader treats "missing" as a person. */
|
|
449
|
+
caller_kind?: 'user' | 'app';
|
|
402
450
|
external?: {
|
|
403
451
|
onlyoffice?: ExternalServiceStatus;
|
|
404
452
|
drawio?: ExternalServiceStatus;
|
|
405
453
|
mermaid?: ExternalServiceStatus;
|
|
406
454
|
};
|
|
455
|
+
/** Whether this installation holds an escrow key for E2E-encrypted folders,
|
|
456
|
+
* and the public half the browser wraps new folders' master keys to.
|
|
457
|
+
*
|
|
458
|
+
* Published on purpose. Escrow means the operator can open the folders you
|
|
459
|
+
* create here without your password, and someone about to create one is
|
|
460
|
+
* entitled to know that BEFORE they create it. Fixed at install time
|
|
461
|
+
* (FILEX_INSTALLATION_E2E_ESCROW_KEY), so this answer never changes for a
|
|
462
|
+
* running installation. */
|
|
463
|
+
e2e_escrow?: {
|
|
464
|
+
enabled: boolean;
|
|
465
|
+
/** Short id of the escrow key (SHA-256(SPKI)[:8], hex). */
|
|
466
|
+
kid?: string;
|
|
467
|
+
alg?: string;
|
|
468
|
+
/** Base64 SPKI. Public material — it can only seal, never open. */
|
|
469
|
+
public_key?: string;
|
|
470
|
+
};
|
|
407
471
|
}
|
|
408
472
|
|
|
409
473
|
export declare function clearResume(store: ResumeStorage | null, key: string): void;
|
|
@@ -421,7 +485,7 @@ export declare interface ClipboardState {
|
|
|
421
485
|
*/
|
|
422
486
|
export declare function comboFromEvent(e: KeyboardEvent): string | null;
|
|
423
487
|
|
|
424
|
-
export declare const ConnectionGuideView: DefineComponent<
|
|
488
|
+
export declare const ConnectionGuideView: DefineComponent<__VLS_Props_17, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_17> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
425
489
|
|
|
426
490
|
export declare type ConnectionsApi = ReturnType<typeof useConnections>;
|
|
427
491
|
|
|
@@ -446,13 +510,13 @@ export declare function connectionsBase(config: ExplorerConfig): string;
|
|
|
446
510
|
*/
|
|
447
511
|
export declare function connectionsOrigin(config: ExplorerConfig): string;
|
|
448
512
|
|
|
449
|
-
export declare const ConnectionsPanel: DefineComponent<
|
|
513
|
+
export declare const ConnectionsPanel: DefineComponent<__VLS_Props_15, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
450
514
|
error: (err: {
|
|
451
515
|
message: string;
|
|
452
516
|
}) => any;
|
|
453
517
|
close: () => any;
|
|
454
518
|
changed: () => any;
|
|
455
|
-
}, string, PublicProps, Readonly<
|
|
519
|
+
}, string, PublicProps, Readonly<__VLS_Props_15> & Readonly<{
|
|
456
520
|
onError?: ((err: {
|
|
457
521
|
message: string;
|
|
458
522
|
}) => any) | undefined;
|
|
@@ -478,31 +542,59 @@ declare interface ContextAction {
|
|
|
478
542
|
divider?: boolean;
|
|
479
543
|
}
|
|
480
544
|
|
|
545
|
+
export declare interface CreatedFolder {
|
|
546
|
+
marker: E2eMarker;
|
|
547
|
+
/** The folder master key, ready for encryptFile/decryptFile. */
|
|
548
|
+
fmk: CryptoKey;
|
|
549
|
+
/** Show this ONCE. filex never stores it and can never show it again. */
|
|
550
|
+
recoveryKey: string;
|
|
551
|
+
}
|
|
552
|
+
|
|
481
553
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
554
|
+
* Create a v2 encrypted folder: random FMK, wrapped under the password KEK,
|
|
555
|
+
* under a freshly minted user recovery key, and — when the installation has
|
|
556
|
+
* escrow enabled — to the escrow public key.
|
|
557
|
+
*/
|
|
558
|
+
export declare function createEncryptedFolder(password: string, opts?: CreateFolderOptions): Promise<CreatedFolder>;
|
|
559
|
+
|
|
560
|
+
export declare interface CreateFolderOptions {
|
|
561
|
+
iterations?: number;
|
|
562
|
+
/** Base64 SPKI of the installation escrow key, when escrow is enabled. */
|
|
563
|
+
escrowPublicKey?: string | null;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Tiny per-explorer key ring: encrypted-folder root (wire path) → FMK.
|
|
568
|
+
* Lives ONLY in memory — "Lock" drops the entry, a reload drops all.
|
|
484
569
|
*/
|
|
485
570
|
export declare function createKeyRing(): {
|
|
486
571
|
get(root: string): CryptoKey | undefined;
|
|
487
|
-
set(root: string,
|
|
488
|
-
/** Drop one folder's key ("
|
|
572
|
+
set(root: string, fmk: CryptoKey): void;
|
|
573
|
+
/** Drop one folder's key ("Lock"). */
|
|
489
574
|
lock(root: string): void;
|
|
490
575
|
has(root: string): boolean;
|
|
491
576
|
clear(): void;
|
|
492
577
|
};
|
|
493
578
|
|
|
494
|
-
/**
|
|
579
|
+
/**
|
|
580
|
+
* Create a v1 folder marker — the pre-0.31 format, with NO recovery of any
|
|
581
|
+
* kind.
|
|
582
|
+
*
|
|
583
|
+
* @deprecated Use `createEncryptedFolder`. Kept exported, and kept producing
|
|
584
|
+
* a genuine v1 marker, so an embedder pinned to the old API keeps creating
|
|
585
|
+
* folders this build can still open rather than half-formed v2 ones.
|
|
586
|
+
*/
|
|
495
587
|
export declare function createMarker(password: string, iterations?: number): Promise<{
|
|
496
588
|
marker: E2eMarker;
|
|
497
589
|
kek: CryptoKey;
|
|
498
590
|
}>;
|
|
499
591
|
|
|
500
592
|
/**
|
|
501
|
-
* Decrypt a 'filexe2e' blob with the folder
|
|
502
|
-
* a wrong key / tampered data, and a plain Error when the
|
|
503
|
-
* e2e file at all.
|
|
593
|
+
* Decrypt a 'filexe2e' blob with the folder master key. Throws
|
|
594
|
+
* E2eDecryptError on a wrong key / tampered data, and a plain Error when the
|
|
595
|
+
* header is not an e2e file at all.
|
|
504
596
|
*/
|
|
505
|
-
export declare function decryptFile(
|
|
597
|
+
export declare function decryptFile(fmk: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer>;
|
|
506
598
|
|
|
507
599
|
export declare const DEFAULT_THEME_ID = "default";
|
|
508
600
|
|
|
@@ -522,6 +614,9 @@ export declare function deriveKek(password: string, salt: Uint8Array, iterations
|
|
|
522
614
|
|
|
523
615
|
export declare const E2E_DEFAULT_ITERATIONS = 600000;
|
|
524
616
|
|
|
617
|
+
/** The only escrow algorithm this version understands. */
|
|
618
|
+
export declare const E2E_ESCROW_ALG = "RSA-OAEP-256";
|
|
619
|
+
|
|
525
620
|
export declare const E2E_MAGIC = "filexe2e";
|
|
526
621
|
|
|
527
622
|
/**
|
|
@@ -529,33 +624,71 @@ export declare const E2E_MAGIC = "filexe2e";
|
|
|
529
624
|
*
|
|
530
625
|
* WebCrypto ONLY — zero dependencies. Design doc: docs/E2E-ENCRYPTION.md.
|
|
531
626
|
*
|
|
532
|
-
* Scheme
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
627
|
+
* ── Scheme ────────────────────────────────────────────────────────────
|
|
628
|
+
*
|
|
629
|
+
* Every encrypted file wraps its own random DEK under ONE key, the folder
|
|
630
|
+
* master key (FMK), and stores the wrapped copy in its own 97-byte header.
|
|
631
|
+
* The FMK is what a "key slot" in the folder marker hands back:
|
|
536
632
|
*
|
|
537
|
-
*
|
|
633
|
+
* password ─PBKDF2-SHA256(600k, 16B salt)─▶ KEK ─┐
|
|
634
|
+
* recovery key ─HKDF-SHA256(16B salt)─▶ RKEK ────┼─▶ unwraps the FMK
|
|
635
|
+
* escrow private key ─RSA-OAEP-256───────────────┘
|
|
636
|
+
* │
|
|
637
|
+
* per-file random 32B DEK ◀── AES-GCM-wrapped by the FMK, in the header
|
|
638
|
+
*
|
|
639
|
+
* Adding a recovery path therefore costs one more wrapped copy of a single
|
|
640
|
+
* 32-byte key in the marker — not a re-encrypt of anything. The file format
|
|
641
|
+
* below is UNCHANGED from v1 and stays that way; only the marker grew.
|
|
642
|
+
*
|
|
643
|
+
* ── Marker versions ───────────────────────────────────────────────────
|
|
644
|
+
*
|
|
645
|
+
* v1 (shipped up to 0.30.1) has no slots: the DEK is wrapped directly by
|
|
646
|
+
* the password KEK. Read that as "the FMK *is* the KEK". Such folders keep
|
|
647
|
+
* opening with nothing but their password, forever — the v1 read path is a
|
|
648
|
+
* first-class path here, not a migration shim.
|
|
649
|
+
*
|
|
650
|
+
* v2 adds the slots. It comes in two flavours, told apart by `fmk`:
|
|
651
|
+
* - `fmk: 'wrapped'` — a fresh random FMK, held in `fmk_pw` wrapped under
|
|
652
|
+
* the password KEK. Every folder created from 0.31 on.
|
|
653
|
+
* - `fmk: 'kek'` — a v1 folder that was given recovery keys in place.
|
|
654
|
+
* Its files were already wrapped under the KEK and are not rewritten, so
|
|
655
|
+
* the FMK stays defined as "the password-derived KEK" and the recovery
|
|
656
|
+
* slots wrap those raw 32 bytes. The password path is byte-identical to
|
|
657
|
+
* v1; only the extra slots are new.
|
|
658
|
+
*
|
|
659
|
+
* ── Invariants ────────────────────────────────────────────────────────
|
|
660
|
+
*
|
|
661
|
+
* - No key, password or recovery key is ever stored, logged or sent to a
|
|
662
|
+
* server. The FMK lives in an in-memory key ring and dies with the tab.
|
|
663
|
+
* - `deriveKek` imports non-extractable. Raw KEK bytes are produced ONLY
|
|
664
|
+
* by `deriveKekBits`, only while upgrading a v1 marker, and only long
|
|
665
|
+
* enough to wrap them into the new slots.
|
|
666
|
+
* - A folder created while escrow was off carries no escrow slot, so the
|
|
667
|
+
* escrow key cannot open it. That is arithmetic, not policy.
|
|
668
|
+
*
|
|
669
|
+
* File layout ('filexe2e' magic, fixed 97-byte header) — UNCHANGED in v2:
|
|
538
670
|
* [0..8) magic "filexe2e"
|
|
539
671
|
* [8] version 0x01
|
|
540
672
|
* [9..21) wrapIV (12B) — GCM IV of the DEK wrap
|
|
541
|
-
* [21..69) wrappedDEK (48B = 32B DEK + 16B GCM tag)
|
|
673
|
+
* [21..69) wrappedDEK (48B = 32B DEK + 16B GCM tag), wrapped by the FMK
|
|
542
674
|
* [69..81) dataIV (12B) — GCM IV of the content
|
|
543
675
|
* [81..97) reserved (zeros; v2 chunking/metadata)
|
|
544
676
|
* [97..) ciphertext (content + 16B GCM tag)
|
|
545
|
-
*
|
|
546
|
-
* Folder marker `.filex-e2e.json` at the encrypted-folder root:
|
|
547
|
-
* { v:1, salt:<b64 16B>, iter:600000, verify:<b64 12B IV || GCM('filex-e2e-verify-v1')> }
|
|
548
|
-
*
|
|
549
|
-
* The KEK NEVER leaves memory — no storage of any kind. Password loss is
|
|
550
|
-
* data loss by design (no recovery path exists anywhere).
|
|
551
677
|
*/
|
|
552
678
|
export declare const E2E_MARKER_NAME = ".filex-e2e.json";
|
|
553
679
|
|
|
680
|
+
/** Marker schema version written by this build. v1 markers still read. */
|
|
681
|
+
export declare const E2E_MARKER_VERSION = 2;
|
|
682
|
+
|
|
554
683
|
/** MVP single-shot in-memory ceiling — larger uploads are refused with a warning. */
|
|
555
684
|
export declare const E2E_MAX_FILE_BYTES: number;
|
|
556
685
|
|
|
557
686
|
export declare const E2E_MIN_PASSWORD_LEN = 8;
|
|
558
687
|
|
|
688
|
+
/** Entropy of a user recovery key: 20 bytes = 160 bits = exactly 32 base32 chars. */
|
|
689
|
+
export declare const E2E_RECOVERY_KEY_BYTES = 20;
|
|
690
|
+
|
|
691
|
+
/** File-header version byte. Unchanged by the recovery work. */
|
|
559
692
|
export declare const E2E_VERSION = 1;
|
|
560
693
|
|
|
561
694
|
/** Thrown on wrong password / corrupted ciphertext (GCM tag mismatch). */
|
|
@@ -563,6 +696,17 @@ export declare class E2eDecryptError extends Error {
|
|
|
563
696
|
constructor(msg?: string);
|
|
564
697
|
}
|
|
565
698
|
|
|
699
|
+
/** Escrow slot: the FMK encrypted to the installation's escrow public key. */
|
|
700
|
+
export declare interface E2eEscrowSlot {
|
|
701
|
+
/** First 8 bytes of SHA-256(SPKI), hex — names WHICH escrow key this is. */
|
|
702
|
+
kid: string;
|
|
703
|
+
alg: string;
|
|
704
|
+
blob: string;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/** How the folder master key is obtained from the password slot. */
|
|
708
|
+
export declare type E2eFmkMode = 'kek' | 'wrapped';
|
|
709
|
+
|
|
566
710
|
export declare type E2eKeyRing = ReturnType<typeof createKeyRing>;
|
|
567
711
|
|
|
568
712
|
export declare interface E2eMarker {
|
|
@@ -570,8 +714,36 @@ export declare interface E2eMarker {
|
|
|
570
714
|
salt: string;
|
|
571
715
|
iter: number;
|
|
572
716
|
verify: string;
|
|
717
|
+
/** v2 only. Absent on a v1 marker, where the FMK is implicitly the KEK. */
|
|
718
|
+
fmk?: E2eFmkMode;
|
|
719
|
+
/** v2 + fmk==='wrapped' only: base64 12B IV || AES-GCM(KEK, FMK). */
|
|
720
|
+
fmk_pw?: string;
|
|
721
|
+
/** v2 only, optional: the user recovery key slot. */
|
|
722
|
+
rk?: E2eRecoverySlot;
|
|
723
|
+
/** v2 only, optional: the operator escrow slot. */
|
|
724
|
+
esc?: E2eEscrowSlot;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/** User-recovery-key slot: HKDF salt + the FMK wrapped under the derived key. */
|
|
728
|
+
export declare interface E2eRecoverySlot {
|
|
729
|
+
salt: string;
|
|
730
|
+
blob: string;
|
|
573
731
|
}
|
|
574
732
|
|
|
733
|
+
export declare const E2eRecoveryUnlockModal: DefineComponent<__VLS_Props_14, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
734
|
+
close: () => any;
|
|
735
|
+
submit: (payload: {
|
|
736
|
+
mode: "recovery" | "escrow";
|
|
737
|
+
value: string;
|
|
738
|
+
}) => any;
|
|
739
|
+
}, string, PublicProps, Readonly<__VLS_Props_14> & Readonly<{
|
|
740
|
+
onClose?: (() => any) | undefined;
|
|
741
|
+
onSubmit?: ((payload: {
|
|
742
|
+
mode: "recovery" | "escrow";
|
|
743
|
+
value: string;
|
|
744
|
+
}) => any) | undefined;
|
|
745
|
+
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
746
|
+
|
|
575
747
|
/** Current combo for an action ('' = unbound). */
|
|
576
748
|
export declare function effectiveCombo(id: string): string;
|
|
577
749
|
|
|
@@ -593,11 +765,14 @@ password: string;
|
|
|
593
765
|
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
594
766
|
|
|
595
767
|
/**
|
|
596
|
-
* Encrypt `content` under the folder
|
|
597
|
-
* content one-shot, wraps the DEK with the
|
|
768
|
+
* Encrypt `content` under the folder master key: mints a fresh DEK, encrypts
|
|
769
|
+
* the content one-shot, wraps the DEK with the FMK and prepends the fixed
|
|
598
770
|
* 'filexe2e' header. Throws when content exceeds E2E_MAX_FILE_BYTES.
|
|
771
|
+
*
|
|
772
|
+
* `fmk` is the key an unlock returned. On a v1 folder that is the password
|
|
773
|
+
* KEK, which is why v1 files keep working untouched.
|
|
599
774
|
*/
|
|
600
|
-
export declare function encryptFile(
|
|
775
|
+
export declare function encryptFile(fmk: CryptoKey, content: ArrayBuffer): Promise<ArrayBuffer>;
|
|
601
776
|
|
|
602
777
|
/**
|
|
603
778
|
* Resolved endpoint map. `useFileApi` derives this once on construction
|
|
@@ -635,6 +810,8 @@ export declare interface EndpointMap {
|
|
|
635
810
|
restore: string | null;
|
|
636
811
|
trashList: string | null;
|
|
637
812
|
trashRestore: string | null;
|
|
813
|
+
e2eEscrowChallenge: string | null;
|
|
814
|
+
e2eEscrowUsed: string | null;
|
|
638
815
|
}
|
|
639
816
|
|
|
640
817
|
export declare function ensureHighlight(): Promise<unknown | null>;
|
|
@@ -646,6 +823,13 @@ export declare function ensureHighlight(): Promise<unknown | null>;
|
|
|
646
823
|
*/
|
|
647
824
|
export declare function ensureMonaco(): Promise<unknown | null>;
|
|
648
825
|
|
|
826
|
+
/**
|
|
827
|
+
* Stable short name for an escrow key: first 8 bytes of SHA-256(SPKI), hex.
|
|
828
|
+
* Written into every escrow slot so a marker says WHICH key opens it, and so
|
|
829
|
+
* the UI can tell "this server's escrow key" from "some other one".
|
|
830
|
+
*/
|
|
831
|
+
export declare function escrowKeyId(spkiB64: string): Promise<string>;
|
|
832
|
+
|
|
649
833
|
export declare interface ExplorerConfig {
|
|
650
834
|
/**
|
|
651
835
|
* Modern shorthand: URL prefix for the standard /api/files/* layout.
|
|
@@ -707,6 +891,10 @@ export declare interface ExplorerConfig {
|
|
|
707
891
|
trashList?: string;
|
|
708
892
|
/** filex trash restore endpoint — `POST { node_id }`. */
|
|
709
893
|
trashRestore?: string;
|
|
894
|
+
/** E2E escrow proof-of-possession — `POST { path } → { id, challenge }`. */
|
|
895
|
+
e2eEscrowChallenge?: string;
|
|
896
|
+
/** E2E escrow use report — `POST { path, id, nonce }`. */
|
|
897
|
+
e2eEscrowUsed?: string;
|
|
710
898
|
/** Public share base URL — `${shareBase}/${uuid}` */
|
|
711
899
|
shareBase?: string;
|
|
712
900
|
/** Auth strategy (see AuthConfig). */
|
|
@@ -848,11 +1036,37 @@ export declare interface ExplorerConfig {
|
|
|
848
1036
|
* the bug this became: for a year the sole place to mint the token the FTPS
|
|
849
1037
|
* guide told you to use was the admin panel.
|
|
850
1038
|
*
|
|
1039
|
+
* ⚠ Role is not the same question as `callerKind`. "API keys" IS hidden for
|
|
1040
|
+
* an app token — not because of what that caller may do, but because there is
|
|
1041
|
+
* no single person behind it whose keys they would be. See `callerKind`.
|
|
1042
|
+
*
|
|
851
1043
|
* ⚠ The entries live in the panel, so `sideNav: false` takes them with it.
|
|
852
1044
|
* Hosts that want the surface without the panel mount `<filex-connections>`
|
|
853
1045
|
* (or `ConnectionsPanel`) on a page of their own.
|
|
854
1046
|
*/
|
|
855
1047
|
connections?: boolean;
|
|
1048
|
+
/**
|
|
1049
|
+
* Who is behind this explorer — a person, or an integration?
|
|
1050
|
+
*
|
|
1051
|
+
* `'user'` (a signed-in human, or their own API token) draws everything.
|
|
1052
|
+
* `'app'` suppresses the surfaces that only mean something for ONE person:
|
|
1053
|
+
* **API keys**, **Recent**, **Starred** and **Shared with me**. Upload, the
|
|
1054
|
+
* storage list, Trash and "How to connect" stay — an embed's users still
|
|
1055
|
+
* upload files and still need mount instructions.
|
|
1056
|
+
*
|
|
1057
|
+
* Why it exists: a filex API token authenticates AS its owner, and the embeds
|
|
1058
|
+
* we run authenticate every visitor with ONE shared token injected by the
|
|
1059
|
+
* host's proxy. v0.30.0 put "API keys" in the panel, so under that token an
|
|
1060
|
+
* embed visitor could list and revoke the credential the embed itself runs
|
|
1061
|
+
* on — and "your Recent" meant the token owner's history shown to a stranger.
|
|
1062
|
+
*
|
|
1063
|
+
* Default: read from `GET /api/files/capabilities` (`caller_kind`), which is
|
|
1064
|
+
* authoritative because only the server knows the token's kind (migration
|
|
1065
|
+
* 00030). Set this only to answer BEFORE that request lands — a host that
|
|
1066
|
+
* already knows it proxies with an app token spares its users the flash of a
|
|
1067
|
+
* Starred row that then disappears. A value here wins over the server's.
|
|
1068
|
+
*/
|
|
1069
|
+
callerKind?: 'user' | 'app';
|
|
856
1070
|
/** Default view. */
|
|
857
1071
|
viewMode?: 'list' | 'grid';
|
|
858
1072
|
/** Override max upload size (MB) — falls back to /limits otherwise. */
|
|
@@ -1454,6 +1668,12 @@ export declare interface FileNode {
|
|
|
1454
1668
|
*/
|
|
1455
1669
|
export declare function findShortcutConflict(combo: string, excludeId: string): ShortcutConflict | null;
|
|
1456
1670
|
|
|
1671
|
+
/**
|
|
1672
|
+
* Format 20 raw bytes as the string the user writes down:
|
|
1673
|
+
* `XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX` (160 bits, no padding waste).
|
|
1674
|
+
*/
|
|
1675
|
+
export declare function formatRecoveryKey(raw: Uint8Array): string;
|
|
1676
|
+
|
|
1457
1677
|
/** What an FTP client needs to be told, computed on the server. */
|
|
1458
1678
|
declare interface FTPSFacts {
|
|
1459
1679
|
enabled: boolean;
|
|
@@ -1470,6 +1690,9 @@ declare interface FTPSFacts {
|
|
|
1470
1690
|
self_signed: boolean;
|
|
1471
1691
|
}
|
|
1472
1692
|
|
|
1693
|
+
/** Mint a fresh user recovery key. Shown once, never stored by filex. */
|
|
1694
|
+
export declare function generateRecoveryKey(): string;
|
|
1695
|
+
|
|
1473
1696
|
/**
|
|
1474
1697
|
* Generate a stylesheet that mirrors styles/variables.css' selector
|
|
1475
1698
|
* cascade 1:1 (light base → explicit-dark selectors → prefers-dark media
|
|
@@ -1627,11 +1850,17 @@ export declare interface GuideFact {
|
|
|
1627
1850
|
export declare function guideProtocols(): string[];
|
|
1628
1851
|
|
|
1629
1852
|
/** True when the buffer starts with the 'filexe2e' magic. */
|
|
1630
|
-
export declare function hasMagic(
|
|
1853
|
+
export declare function hasMagic(data: ArrayBuffer | Uint8Array): boolean;
|
|
1631
1854
|
|
|
1632
1855
|
/** `https://fm.example.com` → `fm.example.com`; anything unparseable comes back whole. */
|
|
1633
1856
|
export declare function hostOf(origin: string): string;
|
|
1634
1857
|
|
|
1858
|
+
/** Import the escrow private key the admin pastes in (base64 PKCS#8, PEM tolerated). */
|
|
1859
|
+
export declare function importEscrowPrivateKey(pkcs8B64: string): Promise<CryptoKey>;
|
|
1860
|
+
|
|
1861
|
+
/** Import the installation escrow public key (base64 SPKI, as the server serves it). */
|
|
1862
|
+
export declare function importEscrowPublicKey(spkiB64: string): Promise<CryptoKey>;
|
|
1863
|
+
|
|
1635
1864
|
declare interface InviteResponse {
|
|
1636
1865
|
mode: 'granted' | 'user_created' | 'shared';
|
|
1637
1866
|
user_id?: number;
|
|
@@ -1685,6 +1914,12 @@ export declare interface ManagerResponse {
|
|
|
1685
1914
|
files: FileNode[];
|
|
1686
1915
|
}
|
|
1687
1916
|
|
|
1917
|
+
/** True when the folder has an operator escrow slot. */
|
|
1918
|
+
export declare function markerHasEscrow(m: E2eMarker | null): boolean;
|
|
1919
|
+
|
|
1920
|
+
/** True when the folder has a user recovery key slot. */
|
|
1921
|
+
export declare function markerHasRecovery(m: E2eMarker | null): boolean;
|
|
1922
|
+
|
|
1688
1923
|
/** True when the hit matched (at least partly) inside file CONTENT. */
|
|
1689
1924
|
export declare function matchedInContent(matched: unknown): boolean;
|
|
1690
1925
|
|
|
@@ -1737,7 +1972,7 @@ export declare interface NFSExportCreated extends NFSConnection {
|
|
|
1737
1972
|
path: string;
|
|
1738
1973
|
}
|
|
1739
1974
|
|
|
1740
|
-
export declare const NFSExportsPanel: DefineComponent<
|
|
1975
|
+
export declare const NFSExportsPanel: DefineComponent<__VLS_Props_20, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
1741
1976
|
active: (v: {
|
|
1742
1977
|
host: string;
|
|
1743
1978
|
port: number;
|
|
@@ -1745,7 +1980,7 @@ enabled: boolean;
|
|
|
1745
1980
|
path?: string;
|
|
1746
1981
|
readOnly: boolean;
|
|
1747
1982
|
}) => any;
|
|
1748
|
-
}, string, PublicProps, Readonly<
|
|
1983
|
+
}, string, PublicProps, Readonly<__VLS_Props_20> & Readonly<{
|
|
1749
1984
|
onActive?: ((v: {
|
|
1750
1985
|
host: string;
|
|
1751
1986
|
port: number;
|
|
@@ -1865,9 +2100,16 @@ export declare type OperationsStore = ReturnType<typeof useOperations>;
|
|
|
1865
2100
|
|
|
1866
2101
|
export declare type OperationStatus = 'running' | 'done' | 'error' | 'aborted';
|
|
1867
2102
|
|
|
1868
|
-
/** Parse marker JSON text; returns null when the shape is not a
|
|
2103
|
+
/** Parse marker JSON text; returns null when the shape is not a marker we read. */
|
|
1869
2104
|
export declare function parseMarker(text: string): E2eMarker | null;
|
|
1870
2105
|
|
|
2106
|
+
/**
|
|
2107
|
+
* Parse a typed-in recovery key back to its 20 bytes, or null when it is not
|
|
2108
|
+
* one. Forgiving about how a human retypes it: case, dashes, spaces and the
|
|
2109
|
+
* Crockford look-alikes (O to 0, I/L to 1) are all normalised away.
|
|
2110
|
+
*/
|
|
2111
|
+
export declare function parseRecoveryKey(s: string): Uint8Array | null;
|
|
2112
|
+
|
|
1871
2113
|
export declare interface PendingOp {
|
|
1872
2114
|
id: number;
|
|
1873
2115
|
op_type: 'copy' | 'move' | 'delete';
|
|
@@ -1988,6 +2230,12 @@ declare interface RecentNode {
|
|
|
1988
2230
|
last_opened?: string;
|
|
1989
2231
|
}
|
|
1990
2232
|
|
|
2233
|
+
export declare const RecoveryKeyModal: DefineComponent<__VLS_Props_13, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2234
|
+
close: () => any;
|
|
2235
|
+
}, string, PublicProps, Readonly<__VLS_Props_13> & Readonly<{
|
|
2236
|
+
onClose?: (() => any) | undefined;
|
|
2237
|
+
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
2238
|
+
|
|
1991
2239
|
declare function reload(): Promise<void>;
|
|
1992
2240
|
|
|
1993
2241
|
export declare function resetAllShortcuts(): void;
|
|
@@ -2096,14 +2344,14 @@ export declare interface S3KeyRequest {
|
|
|
2096
2344
|
expires_at?: string;
|
|
2097
2345
|
}
|
|
2098
2346
|
|
|
2099
|
-
export declare const S3KeysPanel: DefineComponent<
|
|
2347
|
+
export declare const S3KeysPanel: DefineComponent<__VLS_Props_18, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2100
2348
|
active: (v: {
|
|
2101
2349
|
accessKeyID: string;
|
|
2102
2350
|
secret?: string;
|
|
2103
2351
|
endpoint: string;
|
|
2104
2352
|
pathStyle: boolean;
|
|
2105
2353
|
}) => any;
|
|
2106
|
-
}, string, PublicProps, Readonly<
|
|
2354
|
+
}, string, PublicProps, Readonly<__VLS_Props_18> & Readonly<{
|
|
2107
2355
|
onActive?: ((v: {
|
|
2108
2356
|
accessKeyID: string;
|
|
2109
2357
|
secret?: string;
|
|
@@ -2220,6 +2468,7 @@ export declare interface ShortcutHandlers {
|
|
|
2220
2468
|
onShowHelp?: () => void;
|
|
2221
2469
|
onToggleInspector?: () => void;
|
|
2222
2470
|
onToggleHidden?: () => void;
|
|
2471
|
+
onStar?: () => void;
|
|
2223
2472
|
onQuickLook?: () => void;
|
|
2224
2473
|
onTabNew?: () => void;
|
|
2225
2474
|
onTabClose?: () => void;
|
|
@@ -2286,7 +2535,7 @@ export declare interface SSHConnection {
|
|
|
2286
2535
|
ftps?: FTPSFacts;
|
|
2287
2536
|
}
|
|
2288
2537
|
|
|
2289
|
-
export declare const SSHKeysPanel: DefineComponent<
|
|
2538
|
+
export declare const SSHKeysPanel: DefineComponent<__VLS_Props_19, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2290
2539
|
active: (v: {
|
|
2291
2540
|
host: string;
|
|
2292
2541
|
port: number;
|
|
@@ -2295,7 +2544,7 @@ enabled: boolean;
|
|
|
2295
2544
|
hasKey: boolean;
|
|
2296
2545
|
ftps?: FTPSFacts;
|
|
2297
2546
|
}) => any;
|
|
2298
|
-
}, string, PublicProps, Readonly<
|
|
2547
|
+
}, string, PublicProps, Readonly<__VLS_Props_19> & Readonly<{
|
|
2299
2548
|
onActive?: ((v: {
|
|
2300
2549
|
host: string;
|
|
2301
2550
|
port: number;
|
|
@@ -2391,9 +2640,9 @@ export declare interface StorageFieldOption {
|
|
|
2391
2640
|
i18n_key?: string;
|
|
2392
2641
|
}
|
|
2393
2642
|
|
|
2394
|
-
export declare const StorageFields: DefineComponent<
|
|
2643
|
+
export declare const StorageFields: DefineComponent<__VLS_Props_16, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2395
2644
|
"update:modelValue": (v: Record<string, unknown>) => any;
|
|
2396
|
-
}, string, PublicProps, Readonly<
|
|
2645
|
+
}, string, PublicProps, Readonly<__VLS_Props_16> & Readonly<{
|
|
2397
2646
|
"onUpdate:modelValue"?: ((v: Record<string, unknown>) => any) | undefined;
|
|
2398
2647
|
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
2399
2648
|
|
|
@@ -2550,11 +2799,11 @@ export declare const THEMES: ThemeDef[];
|
|
|
2550
2799
|
/** Map of `--fe-*` custom property → value. */
|
|
2551
2800
|
export declare type ThemeTokenMap = Record<string, string>;
|
|
2552
2801
|
|
|
2553
|
-
export declare const TokensPanel: DefineComponent<
|
|
2802
|
+
export declare const TokensPanel: DefineComponent<__VLS_Props_21, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2554
2803
|
active: (v: {
|
|
2555
2804
|
hasToken: boolean;
|
|
2556
2805
|
}) => any;
|
|
2557
|
-
}, string, PublicProps, Readonly<
|
|
2806
|
+
}, string, PublicProps, Readonly<__VLS_Props_21> & Readonly<{
|
|
2558
2807
|
onActive?: ((v: {
|
|
2559
2808
|
hasToken: boolean;
|
|
2560
2809
|
}) => any) | undefined;
|
|
@@ -2600,6 +2849,44 @@ declare interface TrashEntry {
|
|
|
2600
2849
|
ttl_days?: number | null;
|
|
2601
2850
|
}
|
|
2602
2851
|
|
|
2852
|
+
/**
|
|
2853
|
+
* Unlock with the installation escrow private key.
|
|
2854
|
+
*
|
|
2855
|
+
* Returns null when the folder has no escrow slot — which is the case for
|
|
2856
|
+
* every folder created while escrow was off, and is why escrow cannot be
|
|
2857
|
+
* turned on retroactively.
|
|
2858
|
+
*/
|
|
2859
|
+
export declare function unlockWithEscrowKey(marker: E2eMarker, privateKey: CryptoKey): Promise<CryptoKey | null>;
|
|
2860
|
+
|
|
2861
|
+
/**
|
|
2862
|
+
* Unlock with the folder password. Returns the FMK (the key `decryptFile`
|
|
2863
|
+
* wants) or null when the password is wrong.
|
|
2864
|
+
*/
|
|
2865
|
+
export declare function unlockWithPassword(marker: E2eMarker, password: string): Promise<CryptoKey | null>;
|
|
2866
|
+
|
|
2867
|
+
/**
|
|
2868
|
+
* Unlock with the user recovery key shown when the folder was created.
|
|
2869
|
+
* Returns null for a malformed key, a wrong key, or a folder that has no
|
|
2870
|
+
* recovery slot at all — the caller cannot tell those apart, and neither can
|
|
2871
|
+
* an attacker.
|
|
2872
|
+
*/
|
|
2873
|
+
export declare function unlockWithRecoveryKey(marker: E2eMarker, recoveryKey: string): Promise<CryptoKey | null>;
|
|
2874
|
+
|
|
2875
|
+
/**
|
|
2876
|
+
* Give an existing v1 folder recovery keys, in place and without rewriting a
|
|
2877
|
+
* single file.
|
|
2878
|
+
*
|
|
2879
|
+
* The v1 files are wrapped under the password KEK, so the FMK stays defined
|
|
2880
|
+
* as "the KEK" (`fmk: 'kek'`) and the new slots wrap those raw bytes. The
|
|
2881
|
+
* password path afterwards is byte-identical to what it was.
|
|
2882
|
+
*
|
|
2883
|
+
* ⚠ Requires the password — this is only callable at the one moment filex
|
|
2884
|
+
* ever has it. There is no way to give a v1 folder recovery without it.
|
|
2885
|
+
* ⚠ When the installation has escrow on, this ALSO hands the operator a key
|
|
2886
|
+
* to a folder that did not have one. The caller must say so before asking.
|
|
2887
|
+
*/
|
|
2888
|
+
export declare function upgradeMarkerV1(marker: E2eMarker, password: string, opts?: CreateFolderOptions): Promise<CreatedFolder>;
|
|
2889
|
+
|
|
2603
2890
|
export declare interface UploadFinalizeResponse {
|
|
2604
2891
|
s3Key: string;
|
|
2605
2892
|
url?: string;
|
|
@@ -2759,6 +3046,19 @@ export declare function useFileApi(config: ExplorerConfig): {
|
|
|
2759
3046
|
fetchArrayBuffer: (path: string) => Promise<ArrayBuffer>;
|
|
2760
3047
|
limits: () => Promise<UploadLimits>;
|
|
2761
3048
|
capabilities: () => Promise<Capabilities>;
|
|
3049
|
+
e2eEscrowChallenge: (path: string) => Promise<{
|
|
3050
|
+
id: string;
|
|
3051
|
+
challenge: string;
|
|
3052
|
+
kid: string;
|
|
3053
|
+
}>;
|
|
3054
|
+
e2eEscrowUsed: (payload: {
|
|
3055
|
+
path: string;
|
|
3056
|
+
id: string;
|
|
3057
|
+
nonce: string;
|
|
3058
|
+
}) => Promise<{
|
|
3059
|
+
ok: boolean;
|
|
3060
|
+
notified: boolean;
|
|
3061
|
+
}>;
|
|
2762
3062
|
createShare: (payload: {
|
|
2763
3063
|
path: string;
|
|
2764
3064
|
password?: boolean;
|
|
@@ -3271,6 +3571,10 @@ export declare function useUploadChunked(config: ExplorerConfig, api: FileApi, s
|
|
|
3271
3571
|
* Check `password` against a folder marker. Resolves to the derived KEK on
|
|
3272
3572
|
* success, or `null` on a wrong password (GCM tag mismatch on the verify
|
|
3273
3573
|
* blob). Never talks to any server.
|
|
3574
|
+
*
|
|
3575
|
+
* ⚠ This returns the KEK, not the FMK. On a v1 folder they are the same key;
|
|
3576
|
+
* on a v2 `fmk: 'wrapped'` folder they are not. Use `unlockWithPassword` to
|
|
3577
|
+
* get the key that actually decrypts files.
|
|
3274
3578
|
*/
|
|
3275
3579
|
export declare function verifyPassword(marker: E2eMarker, password: string): Promise<CryptoKey | null>;
|
|
3276
3580
|
|