@majikah/majik-signature-client 0.6.1 → 0.6.2

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.
@@ -218,16 +218,6 @@ export declare class MajikSignatureClient {
218
218
  getBlockedContacts(): MajikContact[];
219
219
  clearDirectory(): Promise<this>;
220
220
  resolveSignerLabel(signerId: string): string;
221
- /**
222
- * Sign content with the active account.
223
- *
224
- * The active account must be unlocked and have signing keys.
225
- * Use unlockAccount() first if needed.
226
- *
227
- * @param content - Raw bytes or UTF-8 string to sign
228
- * @param options - Optional content type and timestamp override
229
- * @param accountId - Override which account signs. Defaults to active account.
230
- */
231
221
  sign(content: Uint8Array | string, options?: SignOptions, accountId?: string): Promise<SignResult>;
232
222
  /**
233
223
  * Sign content and immediately serialize to a base64 string.
@@ -451,12 +441,7 @@ export declare class MajikSignatureClient {
451
441
  mimeType?: string;
452
442
  accountId?: string;
453
443
  expectedSigners?: ExpectedSigner[];
454
- }): Promise<{
455
- blob: Blob;
456
- signature: MajikSignature;
457
- handler: string;
458
- mimeType: string;
459
- }>;
444
+ }): Promise<ReturnType<typeof MajikSignature.signFile>>;
460
445
  /**
461
446
  * Sign multiple file blobs with the active (or specified) account in one call.
462
447
  *
@@ -646,12 +631,7 @@ export declare class MajikSignatureClient {
646
631
  timestamp?: string;
647
632
  mimeType?: string;
648
633
  accountId?: string;
649
- }): Promise<{
650
- blob: Blob;
651
- signature: MajikSignature;
652
- handler: string;
653
- mimeType: string;
654
- }>;
634
+ }): Promise<ReturnType<typeof MajikSignature.signFile>>;
655
635
  /**
656
636
  * Extract metadata from a file's embedded signature without verifying it.
657
637
  *
@@ -708,10 +688,7 @@ export declare class MajikSignatureClient {
708
688
  */
709
689
  canSign(file: Blob, key: MajikKey, options?: {
710
690
  mimeType?: string;
711
- }): Promise<{
712
- permitted: boolean;
713
- reason?: string;
714
- }>;
691
+ }): Promise<ReturnType<typeof MajikSignature.canSign>>;
715
692
  /**
716
693
  * Returns true when the file has a restricted multi-sig envelope
717
694
  * (allowlist with more than one expected signer).
@@ -803,12 +780,7 @@ export declare class MajikSignatureClient {
803
780
  mimeType?: string;
804
781
  timestamp?: string;
805
782
  accountId?: string;
806
- }): Promise<{
807
- blob: Blob;
808
- sealInfo: SealInfo;
809
- handler: string;
810
- mimeType: string;
811
- }>;
783
+ }): Promise<ReturnType<typeof MajikSignature.seal>>;
812
784
  /**
813
785
  * Verify the seal hash against the current signatories and seal timestamp.
814
786
  * Returns invalid if the envelope is not sealed.
@@ -631,31 +631,22 @@ export class MajikSignatureClient {
631
631
  return `${signerId.slice(0, 16)}…`;
632
632
  }
633
633
  // ── Signing ───────────────────────────────────────────────────────────────
634
- /**
635
- * Sign content with the active account.
636
- *
637
- * The active account must be unlocked and have signing keys.
638
- * Use unlockAccount() first if needed.
639
- *
640
- * @param content - Raw bytes or UTF-8 string to sign
641
- * @param options - Optional content type and timestamp override
642
- * @param accountId - Override which account signs. Defaults to active account.
643
- */
644
634
  async sign(content, options, accountId) {
635
+ const id = accountId ?? this.getActiveAccount()?.id;
636
+ if (!id)
637
+ throw new Error("No active account — call setActiveAccount() first");
638
+ let key;
639
+ let shouldRelock = false;
645
640
  try {
646
- const id = accountId ?? this.getActiveAccount()?.id;
647
- if (!id)
648
- throw new Error("No active account — call setActiveAccount() first");
649
- const key = this._keys.get(id);
641
+ await this._keys.ensureUnlocked(id);
642
+ key = this._keys.get(id);
650
643
  if (!key)
651
644
  throw new Error(`Account not found in keystore: "${id}"`);
652
- if (key.isLocked) {
653
- throw new Error(`Account "${id}" is locked. Call unlockAccount() before signing.`);
654
- }
655
645
  if (!key.hasSigningKeys) {
656
646
  throw new Error(`Account "${id}" has no signing keys. ` +
657
647
  `Re-import via importAccountFromMnemonicBackup() to enable signing.`);
658
648
  }
649
+ shouldRelock = !(await this.isOnetimeUnlockEnabled());
659
650
  const signature = await MajikSignature.sign(content, key, options);
660
651
  const result = {
661
652
  signature,
@@ -671,6 +662,10 @@ export class MajikSignatureClient {
671
662
  this._emit("error", err, { context: "sign" });
672
663
  throw err;
673
664
  }
665
+ finally {
666
+ if (shouldRelock)
667
+ key?.lock();
668
+ }
674
669
  }
675
670
  /**
676
671
  * Sign content and immediately serialize to a base64 string.
@@ -1017,16 +1012,19 @@ export class MajikSignatureClient {
1017
1012
  const id = options?.accountId ?? this.getActiveAccount()?.id;
1018
1013
  if (!id)
1019
1014
  throw new Error("No active account — call setActiveAccount() first");
1015
+ let key;
1016
+ let shouldRelock = false;
1020
1017
  try {
1021
1018
  await this._keys.ensureUnlocked(id);
1022
- const key = this._keys.get(id);
1019
+ key = this._keys.get(id);
1023
1020
  if (!key)
1024
1021
  throw new Error(`Account not found in keystore: "${id}"`);
1025
1022
  if (!key.hasSigningKeys) {
1026
1023
  throw new Error(`Account "${id}" has no signing keys. ` +
1027
1024
  `Re-import via importAccountFromMnemonicBackup() to enable signing.`);
1028
1025
  }
1029
- return MajikSignature.sign(content, key, {
1026
+ shouldRelock = !(await this.isOnetimeUnlockEnabled());
1027
+ return await MajikSignature.sign(content, key, {
1030
1028
  contentType: options?.contentType,
1031
1029
  timestamp: options?.timestamp,
1032
1030
  });
@@ -1035,6 +1033,10 @@ export class MajikSignatureClient {
1035
1033
  this._emit("error", err, { context: "signContent" });
1036
1034
  throw err;
1037
1035
  }
1036
+ finally {
1037
+ if (shouldRelock)
1038
+ key?.lock();
1039
+ }
1038
1040
  }
1039
1041
  /**
1040
1042
  * Sign a file and embed the signature directly into it using the active account.
@@ -1054,26 +1056,34 @@ export class MajikSignatureClient {
1054
1056
  const id = options?.accountId ?? this.getActiveAccount()?.id;
1055
1057
  if (!id)
1056
1058
  throw new Error("No active account — call setActiveAccount() first");
1059
+ let key;
1060
+ let shouldRelock = false;
1057
1061
  try {
1058
1062
  await this._keys.ensureUnlocked(id);
1059
- const key = this._keys.get(id);
1063
+ key = this._keys.get(id);
1060
1064
  if (!key)
1061
1065
  throw new Error(`Account not found in keystore: "${id}"`);
1062
1066
  if (!key.hasSigningKeys) {
1063
1067
  throw new Error(`Account "${id}" has no signing keys. ` +
1064
1068
  `Re-import via importAccountFromMnemonicBackup() to enable signing.`);
1065
1069
  }
1066
- return MajikSignature.signFile(file, key, {
1070
+ shouldRelock = !(await this.isOnetimeUnlockEnabled());
1071
+ const signedResponse = await MajikSignature.signFile(file, key, {
1067
1072
  contentType: options?.contentType,
1068
1073
  timestamp: options?.timestamp,
1069
1074
  mimeType: options?.mimeType,
1070
1075
  expectedSigners: options?.expectedSigners,
1071
1076
  });
1077
+ return signedResponse;
1072
1078
  }
1073
1079
  catch (err) {
1074
1080
  this._emit("error", err, { context: "signFile" });
1075
1081
  throw err;
1076
1082
  }
1083
+ finally {
1084
+ if (shouldRelock)
1085
+ key?.lock();
1086
+ }
1077
1087
  }
1078
1088
  /**
1079
1089
  * Sign multiple file blobs with the active (or specified) account in one call.
@@ -1622,11 +1632,19 @@ export class MajikSignatureClient {
1622
1632
  const id = options?.accountId ?? this.getActiveAccount()?.id;
1623
1633
  if (!id)
1624
1634
  throw new Error("No active account — call setActiveAccount() first");
1635
+ let key;
1636
+ let shouldRelock = false;
1625
1637
  try {
1626
- const key = this._keys.get(id);
1638
+ await this._keys.ensureUnlocked(id);
1639
+ key = this._keys.get(id);
1627
1640
  if (!key)
1628
1641
  throw new Error(`Account not found in keystore: "${id}"`);
1629
- return MajikSignature.seal(file, key, {
1642
+ if (!key.hasSigningKeys) {
1643
+ throw new Error(`Account "${id}" has no signing keys. ` +
1644
+ `Re-import via importAccountFromMnemonicBackup() to enable signing.`);
1645
+ }
1646
+ shouldRelock = !(await this.isOnetimeUnlockEnabled());
1647
+ return await MajikSignature.seal(file, key, {
1630
1648
  mimeType: options?.mimeType,
1631
1649
  timestamp: options?.timestamp,
1632
1650
  });
@@ -1635,6 +1653,10 @@ export class MajikSignatureClient {
1635
1653
  this._emit("error", err, { context: "seal" });
1636
1654
  throw err;
1637
1655
  }
1656
+ finally {
1657
+ if (shouldRelock)
1658
+ key?.lock();
1659
+ }
1638
1660
  }
1639
1661
  /**
1640
1662
  * Verify the seal hash against the current signatories and seal timestamp.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@majikah/majik-signature-client",
3
3
  "type": "module",
4
4
  "description": "Majik Signature Client is a hybrid post-quantum content signing and verification library for the Majikah ecosystem. Built on top of Majik Key, it provides tamper-proof, forgery-resistant digital signatures for any content format — using a dual-algorithm architecture that combines classical Ed25519 with post-quantum ML-DSA-87 (FIPS-204).",
5
- "version": "0.6.1",
5
+ "version": "0.6.2",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Zelijah",
8
8
  "main": "./dist/index.js",