@majikah/majik-file 0.0.8 → 0.0.9
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/core/types.d.ts +4 -0
- package/dist/majik-file.js +23 -8
- package/package.json +1 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -53,6 +53,8 @@ export interface MjkbSinglePayload {
|
|
|
53
53
|
n: string | null;
|
|
54
54
|
/** Original MIME type (e.g. "image/png"). Short key keeps the binary compact. */
|
|
55
55
|
m: string | null;
|
|
56
|
+
/** Usage context — determines downstream UX and access control. */
|
|
57
|
+
c: FileContext | null;
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
60
|
* JSON payload embedded in a group .mjkb binary.
|
|
@@ -66,6 +68,8 @@ export interface MjkbGroupPayload {
|
|
|
66
68
|
n: string | null;
|
|
67
69
|
/** Original MIME type (e.g. "image/png"). Short key keeps the binary compact. */
|
|
68
70
|
m: string | null;
|
|
71
|
+
/** Usage context — determines downstream UX and access control. */
|
|
72
|
+
c: FileContext | null;
|
|
69
73
|
}
|
|
70
74
|
export type MjkbPayload = MjkbSinglePayload | MjkbGroupPayload;
|
|
71
75
|
export declare function isMjkbGroupPayload(p: MjkbPayload): p is MjkbGroupPayload;
|
package/dist/majik-file.js
CHANGED
|
@@ -214,7 +214,7 @@ export class MajikFile {
|
|
|
214
214
|
* @throws MajikFileError on validation or crypto failure
|
|
215
215
|
*/
|
|
216
216
|
static async create(options) {
|
|
217
|
-
const { data, identity, context, recipients = [], originalName = null, mimeType: rawMimeType = null, isTemporary = false, isShared = false, id = generateUUID(), bypassSizeLimit = false, expiresAt = null, chatMessageId = null, threadMessageId = null, conversationId = null, userId } = options;
|
|
217
|
+
const { data, identity, context, recipients = [], originalName = null, mimeType: rawMimeType = null, isTemporary = false, isShared = false, id = generateUUID(), bypassSizeLimit = false, expiresAt = null, chatMessageId = null, threadMessageId = null, conversationId = null, userId, } = options;
|
|
218
218
|
// ── Input validation ─────────────────────────────────────────────────
|
|
219
219
|
if (!data)
|
|
220
220
|
throw MajikFileError.invalidInput("data is required");
|
|
@@ -292,7 +292,9 @@ export class MajikFile {
|
|
|
292
292
|
// WebP and therefore skipped here — WebP is already codec-compressed.
|
|
293
293
|
// For user_upload and thread_attachment, compressible images (PNG, BMP,
|
|
294
294
|
// TIFF, SVG, etc.) are Zstd-compressed at level 22.
|
|
295
|
-
const compressible =
|
|
295
|
+
const compressible = context === "user_upload" || context === "thread_attachment"
|
|
296
|
+
? true
|
|
297
|
+
: shouldCompress(resolvedMimeType);
|
|
296
298
|
const compressed = compressible
|
|
297
299
|
? await MajikCompressor.compress(processedBytes)
|
|
298
300
|
: processedBytes;
|
|
@@ -317,6 +319,7 @@ export class MajikFile {
|
|
|
317
319
|
mlKemCipherText: arrayToBase64(mlKemCT),
|
|
318
320
|
n: originalName ?? null,
|
|
319
321
|
m: resolvedMimeType ?? null,
|
|
322
|
+
c: context ?? null,
|
|
320
323
|
};
|
|
321
324
|
}
|
|
322
325
|
else {
|
|
@@ -349,6 +352,7 @@ export class MajikFile {
|
|
|
349
352
|
keys,
|
|
350
353
|
n: originalName ?? null,
|
|
351
354
|
m: resolvedMimeType ?? null,
|
|
355
|
+
c: context ?? null,
|
|
352
356
|
};
|
|
353
357
|
}
|
|
354
358
|
// ── 6. Encode .mjkb ───────────────────────────────────────────────
|
|
@@ -451,11 +455,17 @@ export class MajikFile {
|
|
|
451
455
|
else {
|
|
452
456
|
throw MajikFileError.formatError(".mjkb payload JSON is neither a single nor group payload");
|
|
453
457
|
}
|
|
454
|
-
const
|
|
455
|
-
if (!
|
|
458
|
+
const decrypted = aesGcmDecrypt(aesKey, iv, ciphertext);
|
|
459
|
+
if (!decrypted) {
|
|
456
460
|
throw MajikFileError.decryptionFailed("Decryption failed — wrong key or corrupted .mjkb file");
|
|
457
461
|
}
|
|
458
|
-
|
|
462
|
+
const compressible = payload.c === "user_upload" || payload.c === "thread_attachment"
|
|
463
|
+
? true
|
|
464
|
+
: shouldCompress(payload.m);
|
|
465
|
+
const returnData = compressible
|
|
466
|
+
? await MajikCompressor.decompress(decrypted)
|
|
467
|
+
: decrypted;
|
|
468
|
+
return returnData;
|
|
459
469
|
}
|
|
460
470
|
catch (err) {
|
|
461
471
|
if (err instanceof MajikFileError)
|
|
@@ -509,11 +519,16 @@ export class MajikFile {
|
|
|
509
519
|
else {
|
|
510
520
|
throw MajikFileError.formatError(".mjkb payload JSON is neither a single nor group payload");
|
|
511
521
|
}
|
|
512
|
-
const
|
|
513
|
-
if (!
|
|
522
|
+
const decrypted = aesGcmDecrypt(aesKey, iv, ciphertext);
|
|
523
|
+
if (!decrypted) {
|
|
514
524
|
throw MajikFileError.decryptionFailed("Decryption failed — wrong key or corrupted .mjkb file");
|
|
515
525
|
}
|
|
516
|
-
const
|
|
526
|
+
const compressible = payload.c === "user_upload" || payload.c === "thread_attachment"
|
|
527
|
+
? true
|
|
528
|
+
: shouldCompress(payload.m);
|
|
529
|
+
const bytes = compressible
|
|
530
|
+
? await MajikCompressor.decompress(decrypted)
|
|
531
|
+
: decrypted;
|
|
517
532
|
// Extract original filename and MIME type from the payload.
|
|
518
533
|
// Written at encryption time as short keys n/m to keep the binary compact.
|
|
519
534
|
// Older .mjkb files without these fields return null — callers should fall
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@majikah/majik-file",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Majik File is the core cryptographic engine for secure file handling in the Majikah ecosystem. It provides a post-quantum secure \"MJKB\" format designed for file encryption, multi-recipient key encapsulation, and transparent compression using NIST-standardized algorithms.",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.9",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "Zelijah",
|
|
8
8
|
"main": "./dist/index.js",
|