@brftech/filex-core 0.6.0 → 0.7.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/dist/{ArchiveViewer-EGgNqLPE.js → ArchiveViewer-w6GDJJt9.js} +2 -2
- package/dist/{ArchiveViewer-EGgNqLPE.js.map → ArchiveViewer-w6GDJJt9.js.map} +1 -1
- package/dist/{CsvViewer-BvriJ42M.js → CsvViewer-Ci5-mke8.js} +2 -2
- package/dist/{CsvViewer-BvriJ42M.js.map → CsvViewer-Ci5-mke8.js.map} +1 -1
- package/dist/{DrawioViewer-B_bSPsWX.js → DrawioViewer-D2iMuQfD.js} +2 -2
- package/dist/{DrawioViewer-B_bSPsWX.js.map → DrawioViewer-D2iMuQfD.js.map} +1 -1
- package/dist/{EpubViewer-hl68h4gG.js → EpubViewer-D4ydsa9X.js} +2 -2
- package/dist/{EpubViewer-hl68h4gG.js.map → EpubViewer-D4ydsa9X.js.map} +1 -1
- package/dist/{IpynbViewer-lhwOjXK7.js → IpynbViewer-CWBwiFKX.js} +2 -2
- package/dist/{IpynbViewer-lhwOjXK7.js.map → IpynbViewer-CWBwiFKX.js.map} +1 -1
- package/dist/{MermaidViewer-H2Z6AYXg.js → MermaidViewer-CDhuqQli.js} +2 -2
- package/dist/{MermaidViewer-H2Z6AYXg.js.map → MermaidViewer-CDhuqQli.js.map} +1 -1
- package/dist/{PsdViewer-Bsk-11yH.js → PsdViewer-C_TkFb2H.js} +2 -2
- package/dist/{PsdViewer-Bsk-11yH.js.map → PsdViewer-C_TkFb2H.js.map} +1 -1
- package/dist/{TiffViewer-D-j9vycG.js → TiffViewer-BmWCXR7e.js} +2 -2
- package/dist/{TiffViewer-D-j9vycG.js.map → TiffViewer-BmWCXR7e.js.map} +1 -1
- package/dist/{Viewer3D-Bcr70rTe.js → Viewer3D-5kPT1QsY.js} +2 -2
- package/dist/{Viewer3D-Bcr70rTe.js.map → Viewer3D-5kPT1QsY.js.map} +1 -1
- package/dist/filex-core.js +66 -50
- package/dist/filex-core.umd.cjs +53 -53
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/index-nc0-oI_l.js +11723 -0
- package/dist/index-nc0-oI_l.js.map +1 -0
- package/dist/index.d.ts +130 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +389 -9
- package/src/components/EncryptedFolderModal.vue +125 -0
- package/src/components/GalleryView.vue +1 -0
- package/src/components/GridView.vue +1 -0
- package/src/components/ListView.vue +1 -0
- package/src/composables/useFileApi.ts +7 -0
- package/src/index.ts +21 -0
- package/src/lib/e2ecrypto.ts +299 -0
- package/src/locales/en.ts +34 -0
- package/src/locales/tr.ts +34 -0
- package/src/modals/NewFolderModal.vue +18 -0
- package/src/modals/PreviewModal.vue +7 -2
- package/src/styles/base.css +93 -0
- package/src/types/FileNode.ts +3 -0
- package/dist/index-C_ZSnk_I.js +0 -11109
- package/dist/index-C_ZSnk_I.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,13 @@ declare type __VLS_Props_11 = {
|
|
|
45
45
|
active?: boolean;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
declare type __VLS_Props_12 = {
|
|
49
|
+
open: boolean;
|
|
50
|
+
locale: LocaleCode;
|
|
51
|
+
/** True while the parent is creating the folder + uploading the marker. */
|
|
52
|
+
busy?: boolean;
|
|
53
|
+
};
|
|
54
|
+
|
|
48
55
|
declare type __VLS_Props_2 = {
|
|
49
56
|
open: boolean;
|
|
50
57
|
locale: LocaleCode;
|
|
@@ -63,6 +70,7 @@ declare type __VLS_Props_2 = {
|
|
|
63
70
|
pdfSaveUrl?: string | null;
|
|
64
71
|
/** Standalone full-screen viewer route — `?path=…&storage=…&type=…`. */
|
|
65
72
|
viewerBaseUrl?: string | null;
|
|
73
|
+
newTabEnabled?: boolean;
|
|
66
74
|
/** Drop the dialog chrome (backdrop tint, header bar, footer actions)
|
|
67
75
|
* so the viewer fills the full viewport. Used by the standalone
|
|
68
76
|
* /files/edit route where the browser tab IS the container — a
|
|
@@ -249,16 +257,122 @@ declare interface ContextAction {
|
|
|
249
257
|
divider?: boolean;
|
|
250
258
|
}
|
|
251
259
|
|
|
260
|
+
/**
|
|
261
|
+
* Tiny per-explorer key ring: encrypted-folder root (wire path) → KEK.
|
|
262
|
+
* Lives ONLY in memory — "Kilitle" drops the entry, a reload drops all.
|
|
263
|
+
*/
|
|
264
|
+
export declare function createKeyRing(): {
|
|
265
|
+
get(root: string): CryptoKey | undefined;
|
|
266
|
+
set(root: string, kek: CryptoKey): void;
|
|
267
|
+
/** Drop one folder's key ("Kilitle"). */
|
|
268
|
+
lock(root: string): void;
|
|
269
|
+
has(root: string): boolean;
|
|
270
|
+
clear(): void;
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/** Create a fresh folder marker for `password` (also returns the derived KEK). */
|
|
274
|
+
export declare function createMarker(password: string, iterations?: number): Promise<{
|
|
275
|
+
marker: E2eMarker;
|
|
276
|
+
kek: CryptoKey;
|
|
277
|
+
}>;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Decrypt a 'filexe2e' blob with the folder KEK. Throws E2eDecryptError on
|
|
281
|
+
* a wrong key / tampered data, and a plain Error when the header is not an
|
|
282
|
+
* e2e file at all.
|
|
283
|
+
*/
|
|
284
|
+
export declare function decryptFile(kek: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer>;
|
|
285
|
+
|
|
252
286
|
export declare const DEFAULT_THEME_ID = "default";
|
|
253
287
|
|
|
254
288
|
declare type Density = 'comfortable' | 'compact';
|
|
255
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Derive the folder KEK from a password. Returns a NON-extractable
|
|
292
|
+
* AES-256-GCM CryptoKey — it can encrypt/decrypt but never be exported,
|
|
293
|
+
* so even a same-origin script can't read the raw key material back.
|
|
294
|
+
*/
|
|
295
|
+
export declare function deriveKek(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey>;
|
|
296
|
+
|
|
297
|
+
export declare const E2E_DEFAULT_ITERATIONS = 600000;
|
|
298
|
+
|
|
299
|
+
export declare const E2E_MAGIC = "filexe2e";
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* e2ecrypto — client-side crypto for E2E-encrypted folders (wiring:e2).
|
|
303
|
+
*
|
|
304
|
+
* WebCrypto ONLY — zero dependencies. Design doc: docs/E2E-ENCRYPTION.md.
|
|
305
|
+
*
|
|
306
|
+
* Scheme (v1):
|
|
307
|
+
* folder password ─PBKDF2-SHA256(600k iter, per-folder 16B salt)─▶ KEK (AES-256-GCM)
|
|
308
|
+
* per-file random 32B DEK (AES-256-GCM) encrypts the content one-shot;
|
|
309
|
+
* the DEK is wrapped with the KEK and stored in the file's own header.
|
|
310
|
+
*
|
|
311
|
+
* File layout ('filexe2e' magic, fixed 97-byte header):
|
|
312
|
+
* [0..8) magic "filexe2e"
|
|
313
|
+
* [8] version 0x01
|
|
314
|
+
* [9..21) wrapIV (12B) — GCM IV of the DEK wrap
|
|
315
|
+
* [21..69) wrappedDEK (48B = 32B DEK + 16B GCM tag)
|
|
316
|
+
* [69..81) dataIV (12B) — GCM IV of the content
|
|
317
|
+
* [81..97) reserved (zeros; v2 chunking/metadata)
|
|
318
|
+
* [97..) ciphertext (content + 16B GCM tag)
|
|
319
|
+
*
|
|
320
|
+
* Folder marker `.filex-e2e.json` at the encrypted-folder root:
|
|
321
|
+
* { v:1, salt:<b64 16B>, iter:600000, verify:<b64 12B IV || GCM('filex-e2e-verify-v1')> }
|
|
322
|
+
*
|
|
323
|
+
* The KEK NEVER leaves memory — no storage of any kind. Password loss is
|
|
324
|
+
* data loss by design (no recovery path exists anywhere).
|
|
325
|
+
*/
|
|
326
|
+
export declare const E2E_MARKER_NAME = ".filex-e2e.json";
|
|
327
|
+
|
|
328
|
+
/** MVP single-shot in-memory ceiling — larger uploads are refused with a warning. */
|
|
329
|
+
export declare const E2E_MAX_FILE_BYTES: number;
|
|
330
|
+
|
|
331
|
+
export declare const E2E_MIN_PASSWORD_LEN = 8;
|
|
332
|
+
|
|
333
|
+
export declare const E2E_VERSION = 1;
|
|
334
|
+
|
|
335
|
+
/** Thrown on wrong password / corrupted ciphertext (GCM tag mismatch). */
|
|
336
|
+
export declare class E2eDecryptError extends Error {
|
|
337
|
+
constructor(msg?: string);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export declare type E2eKeyRing = ReturnType<typeof createKeyRing>;
|
|
341
|
+
|
|
342
|
+
export declare interface E2eMarker {
|
|
343
|
+
v: number;
|
|
344
|
+
salt: string;
|
|
345
|
+
iter: number;
|
|
346
|
+
verify: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
256
349
|
/** Current combo for an action ('' = unbound). */
|
|
257
350
|
export declare function effectiveCombo(id: string): string;
|
|
258
351
|
|
|
259
352
|
/** English UI strings. */
|
|
260
353
|
export declare const en: Record<string, string>;
|
|
261
354
|
|
|
355
|
+
export declare const EncryptedFolderModal: DefineComponent<__VLS_Props_12, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
356
|
+
close: () => any;
|
|
357
|
+
submit: (payload: {
|
|
358
|
+
name: string;
|
|
359
|
+
password: string;
|
|
360
|
+
}) => any;
|
|
361
|
+
}, string, PublicProps, Readonly<__VLS_Props_12> & Readonly<{
|
|
362
|
+
onClose?: (() => any) | undefined;
|
|
363
|
+
onSubmit?: ((payload: {
|
|
364
|
+
name: string;
|
|
365
|
+
password: string;
|
|
366
|
+
}) => any) | undefined;
|
|
367
|
+
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Encrypt `content` under the folder KEK: mints a fresh DEK, encrypts the
|
|
371
|
+
* content one-shot, wraps the DEK with the KEK and prepends the fixed
|
|
372
|
+
* 'filexe2e' header. Throws when content exceeds E2E_MAX_FILE_BYTES.
|
|
373
|
+
*/
|
|
374
|
+
export declare function encryptFile(kek: CryptoKey, content: ArrayBuffer): Promise<ArrayBuffer>;
|
|
375
|
+
|
|
262
376
|
/**
|
|
263
377
|
* Resolved endpoint map. `useFileApi` derives this once on construction
|
|
264
378
|
* — components never need to think about config/apiBase precedence.
|
|
@@ -843,6 +957,7 @@ export declare interface FileNode {
|
|
|
843
957
|
* projectFileNodes emits it when a storage has RBAC on). '' / undefined =
|
|
844
958
|
* ACL not enforced. Used to gate edit/manage affordances client-side. */
|
|
845
959
|
perm?: 'none' | 'viewer' | 'editor' | 'owner';
|
|
960
|
+
e2e?: boolean;
|
|
846
961
|
/** Generic — any additional fields the backend wants to inline. */
|
|
847
962
|
[k: string]: unknown;
|
|
848
963
|
}
|
|
@@ -910,6 +1025,9 @@ declare interface Grant {
|
|
|
910
1025
|
inherited?: boolean;
|
|
911
1026
|
}
|
|
912
1027
|
|
|
1028
|
+
/** True when the buffer starts with the 'filexe2e' magic. */
|
|
1029
|
+
export declare function hasMagic(buf: ArrayBuffer | Uint8Array): boolean;
|
|
1030
|
+
|
|
913
1031
|
declare interface InviteResponse {
|
|
914
1032
|
mode: 'granted' | 'user_created' | 'shared';
|
|
915
1033
|
user_id?: number;
|
|
@@ -935,6 +1053,8 @@ export declare interface ManagerResponse {
|
|
|
935
1053
|
/** RBAC effective level for the current user on this directory ('' when ACL
|
|
936
1054
|
* is not enforced on the storage). Gates the folder-level write actions. */
|
|
937
1055
|
perm?: 'none' | 'viewer' | 'editor' | 'owner';
|
|
1056
|
+
e2e?: boolean;
|
|
1057
|
+
e2e_root?: string;
|
|
938
1058
|
files: FileNode[];
|
|
939
1059
|
}
|
|
940
1060
|
|
|
@@ -1053,6 +1173,9 @@ export declare type OperationsStore = ReturnType<typeof useOperations>;
|
|
|
1053
1173
|
|
|
1054
1174
|
export declare type OperationStatus = 'running' | 'done' | 'error' | 'aborted';
|
|
1055
1175
|
|
|
1176
|
+
/** Parse marker JSON text; returns null when the shape is not a v1 marker. */
|
|
1177
|
+
export declare function parseMarker(text: string): E2eMarker | null;
|
|
1178
|
+
|
|
1056
1179
|
export declare interface PendingOp {
|
|
1057
1180
|
id: number;
|
|
1058
1181
|
op_type: 'copy' | 'move' | 'delete';
|
|
@@ -1823,6 +1946,13 @@ export declare function useUploadChunked(config: ExplorerConfig, api: FileApi):
|
|
|
1823
1946
|
uploadFile: (opts: UploadOptions) => Promise<UploadFinalizeResponse>;
|
|
1824
1947
|
};
|
|
1825
1948
|
|
|
1949
|
+
/**
|
|
1950
|
+
* Check `password` against a folder marker. Resolves to the derived KEK on
|
|
1951
|
+
* success, or `null` on a wrong password (GCM tag mismatch on the verify
|
|
1952
|
+
* blob). Never talks to any server.
|
|
1953
|
+
*/
|
|
1954
|
+
export declare function verifyPassword(marker: E2eMarker, password: string): Promise<CryptoKey | null>;
|
|
1955
|
+
|
|
1826
1956
|
export declare type ViewMode = 'list' | 'grid' | 'gallery';
|
|
1827
1957
|
|
|
1828
1958
|
export { }
|