@majikah/majik-signature-client 0.6.13 → 0.6.15
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 +1 -1
- package/dist/core/types.d.ts +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/majik-signature-client.d.ts +34 -1
- package/dist/majik-signature-client.js +85 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Designed to be used natively within the Majikah ecosystem, it inherits all core
|
|
|
20
20
|
You can instantiate and fully hydrate the client and its storage adapters in a single call using the static `create` method.
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
|
-
import { MajikSignatureClient } from "
|
|
23
|
+
import { MajikSignatureClient } from "@majikah/majik-signature-client";
|
|
24
24
|
|
|
25
25
|
// 1. Initialize and hydrate the client state, keys, contacts, and stamps
|
|
26
26
|
const client = await MajikSignatureClient.create({
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MajikContactManagerJSON } from "./contacts/types";
|
|
2
2
|
import { MajikSignatureStampJSON } from "./stamp/majik-signature-stamp";
|
|
3
3
|
import { UserAppPreferences } from "./storage";
|
|
4
|
-
export type ISODateString = string;
|
|
5
4
|
export interface MAJIK_API_RESPONSE {
|
|
6
5
|
success: boolean;
|
|
7
6
|
message: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./core/crypto/constants";
|
|
|
7
7
|
export * from "./core/crypto/keystore-manager";
|
|
8
8
|
export * from "./core/storage";
|
|
9
9
|
export * from "./core/stamp/majik-signature-stamp";
|
|
10
|
+
export * from "@majikah/majik-key";
|
|
10
11
|
export { DEFAULT_USER_APP_PREFERENCES } from "./core/client-state-manager";
|
|
11
12
|
export * from "./core/utils/utilities";
|
|
12
13
|
export { migrateMajikMessageJSON } from "./core/contacts/majik-contact-migration";
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from "./core/crypto/constants";
|
|
|
6
6
|
export * from "./core/crypto/keystore-manager";
|
|
7
7
|
export * from "./core/storage";
|
|
8
8
|
export * from "./core/stamp/majik-signature-stamp";
|
|
9
|
+
export * from "@majikah/majik-key";
|
|
9
10
|
export { DEFAULT_USER_APP_PREFERENCES } from "./core/client-state-manager";
|
|
10
11
|
export * from "./core/utils/utilities";
|
|
11
12
|
export { migrateMajikMessageJSON } from "./core/contacts/majik-contact-migration";
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { MajikKey, MajikKeyAddress } from "@majikah/majik-key";
|
|
18
18
|
import { MajikSignature } from "@majikah/majik-signature";
|
|
19
|
-
import type { EnvelopeInfo, ExpectedSigner, MajikSignatureJSON, MajikSignerPublicKeys, SealInfo, SealVerificationResult, SignatoriesFilter, SignatoriesResult, SignatoryInfo, SignOptions, VerificationResult } from "@majikah/majik-signature";
|
|
19
|
+
import type { EnvelopeInfo, ExpectedSigner, MajikSignatureEnvelope, MajikSignatureEnvelopeJSON, MajikSignatureJSON, MajikSignerPublicKeys, SealInfo, SealVerificationResult, SignatoriesFilter, SignatoriesResult, SignatoryInfo, SignOptions, VerificationResult } from "@majikah/majik-signature";
|
|
20
20
|
import { MAJIK_API_RESPONSE } from "./core/types";
|
|
21
21
|
import { ImageSignatureStub, ImageSignOptions, ImageVerificationResult } from "@majikah/majik-signature/dist/core/stamp";
|
|
22
22
|
import { MajikContactManager, MajikContactManagerAdapters } from "./core/contacts/majik-contact-manager";
|
|
@@ -320,6 +320,22 @@ export declare class MajikSignatureClient extends MajikKeyClient<MajikContact, M
|
|
|
320
320
|
accountId?: string;
|
|
321
321
|
expectedSigners?: ExpectedSigner[];
|
|
322
322
|
}): Promise<ReturnType<typeof MajikSignature.signFile>>;
|
|
323
|
+
/**
|
|
324
|
+
* Sign a file with a detached signature envelope.
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* const { blob: signedPdf } = await majik.signFileDetached(pdfBlob);
|
|
328
|
+
*
|
|
329
|
+
* @example — non-active account
|
|
330
|
+
* const { blob } = await majik.signFileDetached(wavBlob, { accountId: "acc_xyz" });
|
|
331
|
+
*/
|
|
332
|
+
signFileDetached(file: Blob, options?: {
|
|
333
|
+
contentType?: string;
|
|
334
|
+
timestamp?: string;
|
|
335
|
+
mimeType?: string;
|
|
336
|
+
accountId?: string;
|
|
337
|
+
expectedSigners?: ExpectedSigner[];
|
|
338
|
+
}): Promise<ReturnType<typeof MajikSignature.signFileDetached>>;
|
|
323
339
|
/**
|
|
324
340
|
* Sign multiple file blobs with the active (or specified) account in one call.
|
|
325
341
|
*
|
|
@@ -383,6 +399,23 @@ export declare class MajikSignatureClient extends MajikKeyClient<MajikContact, M
|
|
|
383
399
|
handler?: string;
|
|
384
400
|
reason?: string;
|
|
385
401
|
}>;
|
|
402
|
+
/**
|
|
403
|
+
* Verify a file's detached signature.
|
|
404
|
+
*
|
|
405
|
+
* @example — verify a signed PDF's detached signature against a known contact
|
|
406
|
+
* const result = await majik.verifyFileDetached(signedPdf, envelope, { contactId: "contact_abc" });
|
|
407
|
+
* if (result.valid) console.log("Verified:", result.signerId, result.timestamp);
|
|
408
|
+
*/
|
|
409
|
+
verifyFileDetached(file: Blob, envelope: MajikSignatureEnvelope | MajikSignatureEnvelopeJSON, options?: {
|
|
410
|
+
contactId?: string;
|
|
411
|
+
publicKeyBase64?: string;
|
|
412
|
+
key?: MajikKey;
|
|
413
|
+
expectedSignerId?: string;
|
|
414
|
+
mimeType?: string;
|
|
415
|
+
}): Promise<VerificationResult & {
|
|
416
|
+
handler?: string;
|
|
417
|
+
reason?: string;
|
|
418
|
+
}>;
|
|
386
419
|
/**
|
|
387
420
|
* Verify multiple files' embedded signatures against the same signer in
|
|
388
421
|
* one call.
|
|
@@ -779,6 +779,48 @@ export class MajikSignatureClient extends MajikKeyClient {
|
|
|
779
779
|
key?.lock();
|
|
780
780
|
}
|
|
781
781
|
}
|
|
782
|
+
/**
|
|
783
|
+
* Sign a file with a detached signature envelope.
|
|
784
|
+
*
|
|
785
|
+
* @example
|
|
786
|
+
* const { blob: signedPdf } = await majik.signFileDetached(pdfBlob);
|
|
787
|
+
*
|
|
788
|
+
* @example — non-active account
|
|
789
|
+
* const { blob } = await majik.signFileDetached(wavBlob, { accountId: "acc_xyz" });
|
|
790
|
+
*/
|
|
791
|
+
async signFileDetached(file, options) {
|
|
792
|
+
const id = options?.accountId ?? this.getActiveAccount()?.id;
|
|
793
|
+
if (!id)
|
|
794
|
+
throw new Error("No active account — call setActiveAccount() first");
|
|
795
|
+
let key;
|
|
796
|
+
let shouldRelock = false;
|
|
797
|
+
try {
|
|
798
|
+
await this._keys.ensureUnlocked(id);
|
|
799
|
+
key = this._keys.get(id);
|
|
800
|
+
if (!key)
|
|
801
|
+
throw new Error(`Account not found in keystore: "${id}"`);
|
|
802
|
+
if (!key.hasSigningKeys) {
|
|
803
|
+
throw new Error(`Account "${id}" has no signing keys. ` +
|
|
804
|
+
`Re-import via importAccountFromMnemonicBackup() to enable signing.`);
|
|
805
|
+
}
|
|
806
|
+
shouldRelock = !(await this.isOnetimeUnlockEnabled());
|
|
807
|
+
const signedResponse = await MajikSignature.signFileDetached(file, key, {
|
|
808
|
+
contentType: options?.contentType,
|
|
809
|
+
timestamp: options?.timestamp,
|
|
810
|
+
mimeType: options?.mimeType,
|
|
811
|
+
expectedSigners: options?.expectedSigners,
|
|
812
|
+
});
|
|
813
|
+
return signedResponse;
|
|
814
|
+
}
|
|
815
|
+
catch (err) {
|
|
816
|
+
this._emit("error", err, { context: "signFileDetached" });
|
|
817
|
+
throw err;
|
|
818
|
+
}
|
|
819
|
+
finally {
|
|
820
|
+
if (shouldRelock)
|
|
821
|
+
key?.lock();
|
|
822
|
+
}
|
|
823
|
+
}
|
|
782
824
|
/**
|
|
783
825
|
* Sign multiple file blobs with the active (or specified) account in one call.
|
|
784
826
|
*
|
|
@@ -897,7 +939,49 @@ export class MajikSignatureClient extends MajikKeyClient {
|
|
|
897
939
|
const results = await MajikSignature.verifyFile(file, firstSig.extractPublicKeys(), {
|
|
898
940
|
expectedSignerId: firstSig.signerId,
|
|
899
941
|
mimeType: options?.mimeType,
|
|
900
|
-
}
|
|
942
|
+
});
|
|
943
|
+
return results[0];
|
|
944
|
+
}
|
|
945
|
+
catch (err) {
|
|
946
|
+
this._emit("error", err, { context: "verifyFile" });
|
|
947
|
+
throw err;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* Verify a file's detached signature.
|
|
952
|
+
*
|
|
953
|
+
* @example — verify a signed PDF's detached signature against a known contact
|
|
954
|
+
* const result = await majik.verifyFileDetached(signedPdf, envelope, { contactId: "contact_abc" });
|
|
955
|
+
* if (result.valid) console.log("Verified:", result.signerId, result.timestamp);
|
|
956
|
+
*/
|
|
957
|
+
async verifyFileDetached(file, envelope, options) {
|
|
958
|
+
try {
|
|
959
|
+
const publicKeys = await this._resolveSignerPublicKeys(options);
|
|
960
|
+
if (publicKeys) {
|
|
961
|
+
const results = await MajikSignature.verifyFileDetached(file, envelope, publicKeys, {
|
|
962
|
+
expectedSignerId: options?.expectedSignerId,
|
|
963
|
+
mimeType: options?.mimeType,
|
|
964
|
+
});
|
|
965
|
+
return results[0];
|
|
966
|
+
}
|
|
967
|
+
// No signer provided — extract and use self-reported keys from first signature.
|
|
968
|
+
const extracted = await MajikSignature.extractFrom(file, {
|
|
969
|
+
mimeType: options?.mimeType,
|
|
970
|
+
});
|
|
971
|
+
if (!extracted.length) {
|
|
972
|
+
return {
|
|
973
|
+
valid: false,
|
|
974
|
+
signerId: "",
|
|
975
|
+
contentHash: "",
|
|
976
|
+
timestamp: new Date().toISOString(),
|
|
977
|
+
reason: "No embedded signature found",
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
const firstSig = extracted[0];
|
|
981
|
+
const results = await MajikSignature.verifyFileDetached(file, envelope, firstSig.extractPublicKeys(), {
|
|
982
|
+
expectedSignerId: firstSig.signerId,
|
|
983
|
+
mimeType: options?.mimeType,
|
|
984
|
+
});
|
|
901
985
|
return results[0];
|
|
902
986
|
}
|
|
903
987
|
catch (err) {
|
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 Client, 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.
|
|
5
|
+
"version": "0.6.15",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "Zelijah",
|
|
8
8
|
"main": "./dist/index.js",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@majikah/majik-file": "^0.2.4",
|
|
58
58
|
"@majikah/majik-key": "^0.3.4",
|
|
59
59
|
"@majikah/majik-key-client": "^0.1.8",
|
|
60
|
-
"@majikah/majik-signature": "^0.2.
|
|
60
|
+
"@majikah/majik-signature": "^0.2.3",
|
|
61
61
|
"@stablelib/ed25519": "^2.1.0",
|
|
62
62
|
"ed2curve": "^0.3.0",
|
|
63
63
|
"fflate": "^0.8.3"
|