@secondlayer/shared 6.22.0 → 6.23.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/src/crypto/ed25519.d.ts +22 -0
- package/dist/src/crypto/ed25519.js +80 -0
- package/dist/src/crypto/ed25519.js.map +10 -0
- package/dist/src/crypto/secondlayer-webhook.d.ts +40 -0
- package/dist/src/crypto/secondlayer-webhook.js +130 -0
- package/dist/src/crypto/secondlayer-webhook.js.map +11 -0
- package/dist/src/index.d.ts +24 -24
- package/dist/src/index.js +54 -53
- package/dist/src/index.js.map +5 -5
- package/dist/src/leader.d.ts +53 -0
- package/dist/src/leader.js +257 -0
- package/dist/src/leader.js.map +12 -0
- package/dist/src/streams-bulk-manifest.d.ts +33 -0
- package/dist/src/streams-bulk-manifest.js +104 -0
- package/dist/src/streams-bulk-manifest.js.map +11 -0
- package/package.json +17 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { KeyObject } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Asymmetric ed25519 signing for Streams response proofs.
|
|
4
|
+
*
|
|
5
|
+
* Asymmetric (not HMAC) so the proof is real: only the server holds the private
|
|
6
|
+
* key, and any consumer verifies with the published public key — no shared
|
|
7
|
+
* secret to leak. ed25519 uses node's `sign`/`verify` with a `null` algorithm.
|
|
8
|
+
* Keys are PEM (PKCS8 private / SPKI public) for env transport; load once and
|
|
9
|
+
* reuse the KeyObject on hot paths.
|
|
10
|
+
*/
|
|
11
|
+
declare function generateEd25519KeyPair(): {
|
|
12
|
+
privateKeyPem: string
|
|
13
|
+
publicKeyPem: string
|
|
14
|
+
};
|
|
15
|
+
declare function loadEd25519PrivateKey(pem: string): KeyObject;
|
|
16
|
+
declare function loadEd25519PublicKey(pem: string): KeyObject;
|
|
17
|
+
declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
|
|
18
|
+
/** Stable short id for a public key (rotation hint via X-Signature-KeyId). */
|
|
19
|
+
declare function ed25519KeyId(publicKeyPem: string): string;
|
|
20
|
+
declare function signEd25519(payload: string, privateKey: KeyObject): string;
|
|
21
|
+
declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
|
|
22
|
+
export { verifyEd25519, signEd25519, publicKeyPemFromPrivate, loadEd25519PublicKey, loadEd25519PrivateKey, generateEd25519KeyPair, ed25519KeyId };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/crypto/ed25519.ts
|
|
18
|
+
var exports_ed25519 = {};
|
|
19
|
+
__export(exports_ed25519, {
|
|
20
|
+
verifyEd25519: () => verifyEd25519,
|
|
21
|
+
signEd25519: () => signEd25519,
|
|
22
|
+
publicKeyPemFromPrivate: () => publicKeyPemFromPrivate,
|
|
23
|
+
loadEd25519PublicKey: () => loadEd25519PublicKey,
|
|
24
|
+
loadEd25519PrivateKey: () => loadEd25519PrivateKey,
|
|
25
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
26
|
+
ed25519KeyId: () => ed25519KeyId
|
|
27
|
+
});
|
|
28
|
+
import {
|
|
29
|
+
createHash,
|
|
30
|
+
createPrivateKey,
|
|
31
|
+
createPublicKey,
|
|
32
|
+
generateKeyPairSync,
|
|
33
|
+
sign as nodeSign,
|
|
34
|
+
verify as nodeVerify
|
|
35
|
+
} from "node:crypto";
|
|
36
|
+
function generateEd25519KeyPair() {
|
|
37
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
38
|
+
return {
|
|
39
|
+
privateKeyPem: privateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
|
40
|
+
publicKeyPem: publicKey.export({ format: "pem", type: "spki" }).toString()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function loadEd25519PrivateKey(pem) {
|
|
44
|
+
return createPrivateKey(pem);
|
|
45
|
+
}
|
|
46
|
+
function loadEd25519PublicKey(pem) {
|
|
47
|
+
return createPublicKey(pem);
|
|
48
|
+
}
|
|
49
|
+
function publicKeyPemFromPrivate(privateKeyPem) {
|
|
50
|
+
return createPublicKey(createPrivateKey(privateKeyPem)).export({ format: "pem", type: "spki" }).toString();
|
|
51
|
+
}
|
|
52
|
+
function ed25519KeyId(publicKeyPem) {
|
|
53
|
+
const der = createPublicKey(publicKeyPem).export({
|
|
54
|
+
format: "der",
|
|
55
|
+
type: "spki"
|
|
56
|
+
});
|
|
57
|
+
return createHash("sha256").update(der).digest("base64url").slice(0, 16);
|
|
58
|
+
}
|
|
59
|
+
function signEd25519(payload, privateKey) {
|
|
60
|
+
return nodeSign(null, Buffer.from(payload, "utf8"), privateKey).toString("base64");
|
|
61
|
+
}
|
|
62
|
+
function verifyEd25519(payload, signatureBase64, publicKey) {
|
|
63
|
+
try {
|
|
64
|
+
return nodeVerify(null, Buffer.from(payload, "utf8"), publicKey, Buffer.from(signatureBase64, "base64"));
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
verifyEd25519,
|
|
71
|
+
signEd25519,
|
|
72
|
+
publicKeyPemFromPrivate,
|
|
73
|
+
loadEd25519PublicKey,
|
|
74
|
+
loadEd25519PrivateKey,
|
|
75
|
+
generateEd25519KeyPair,
|
|
76
|
+
ed25519KeyId
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
//# debugId=B4FC95F24211B0D064756E2164756E21
|
|
80
|
+
//# sourceMappingURL=ed25519.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/crypto/ed25519.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n\ttype KeyObject,\n\tcreateHash,\n\tcreatePrivateKey,\n\tcreatePublicKey,\n\tgenerateKeyPairSync,\n\tsign as nodeSign,\n\tverify as nodeVerify,\n} from \"node:crypto\";\n\n/**\n * Asymmetric ed25519 signing for Streams response proofs.\n *\n * Asymmetric (not HMAC) so the proof is real: only the server holds the private\n * key, and any consumer verifies with the published public key — no shared\n * secret to leak. ed25519 uses node's `sign`/`verify` with a `null` algorithm.\n * Keys are PEM (PKCS8 private / SPKI public) for env transport; load once and\n * reuse the KeyObject on hot paths.\n */\n\nexport function generateEd25519KeyPair(): {\n\tprivateKeyPem: string;\n\tpublicKeyPem: string;\n} {\n\tconst { privateKey, publicKey } = generateKeyPairSync(\"ed25519\");\n\treturn {\n\t\tprivateKeyPem: privateKey\n\t\t\t.export({ format: \"pem\", type: \"pkcs8\" })\n\t\t\t.toString(),\n\t\tpublicKeyPem: publicKey.export({ format: \"pem\", type: \"spki\" }).toString(),\n\t};\n}\n\nexport function loadEd25519PrivateKey(pem: string): KeyObject {\n\treturn createPrivateKey(pem);\n}\n\nexport function loadEd25519PublicKey(pem: string): KeyObject {\n\treturn createPublicKey(pem);\n}\n\nexport function publicKeyPemFromPrivate(privateKeyPem: string): string {\n\treturn createPublicKey(createPrivateKey(privateKeyPem))\n\t\t.export({ format: \"pem\", type: \"spki\" })\n\t\t.toString();\n}\n\n/** Stable short id for a public key (rotation hint via X-Signature-KeyId). */\nexport function ed25519KeyId(publicKeyPem: string): string {\n\tconst der = createPublicKey(publicKeyPem).export({\n\t\tformat: \"der\",\n\t\ttype: \"spki\",\n\t});\n\treturn createHash(\"sha256\").update(der).digest(\"base64url\").slice(0, 16);\n}\n\nexport function signEd25519(payload: string, privateKey: KeyObject): string {\n\treturn nodeSign(null, Buffer.from(payload, \"utf8\"), privateKey).toString(\n\t\t\"base64\",\n\t);\n}\n\nexport function verifyEd25519(\n\tpayload: string,\n\tsignatureBase64: string,\n\tpublicKey: KeyObject,\n): boolean {\n\ttry {\n\t\treturn nodeVerify(\n\t\t\tnull,\n\t\t\tBuffer.from(payload, \"utf8\"),\n\t\t\tpublicKey,\n\t\t\tBuffer.from(signatureBase64, \"base64\"),\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMC;AAAA,YACA;AAAA;AAaM,SAAS,sBAAsB,GAGpC;AAAA,EACD,QAAQ,YAAY,cAAc,oBAAoB,SAAS;AAAA,EAC/D,OAAO;AAAA,IACN,eAAe,WACb,OAAO,EAAE,QAAQ,OAAO,MAAM,QAAQ,CAAC,EACvC,SAAS;AAAA,IACX,cAAc,UAAU,OAAO,EAAE,QAAQ,OAAO,MAAM,OAAO,CAAC,EAAE,SAAS;AAAA,EAC1E;AAAA;AAGM,SAAS,qBAAqB,CAAC,KAAwB;AAAA,EAC7D,OAAO,iBAAiB,GAAG;AAAA;AAGrB,SAAS,oBAAoB,CAAC,KAAwB;AAAA,EAC5D,OAAO,gBAAgB,GAAG;AAAA;AAGpB,SAAS,uBAAuB,CAAC,eAA+B;AAAA,EACtE,OAAO,gBAAgB,iBAAiB,aAAa,CAAC,EACpD,OAAO,EAAE,QAAQ,OAAO,MAAM,OAAO,CAAC,EACtC,SAAS;AAAA;AAIL,SAAS,YAAY,CAAC,cAA8B;AAAA,EAC1D,MAAM,MAAM,gBAAgB,YAAY,EAAE,OAAO;AAAA,IAChD,QAAQ;AAAA,IACR,MAAM;AAAA,EACP,CAAC;AAAA,EACD,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,WAAW,EAAE,MAAM,GAAG,EAAE;AAAA;AAGjE,SAAS,WAAW,CAAC,SAAiB,YAA+B;AAAA,EAC3E,OAAO,SAAS,MAAM,OAAO,KAAK,SAAS,MAAM,GAAG,UAAU,EAAE,SAC/D,QACD;AAAA;AAGM,SAAS,aAAa,CAC5B,SACA,iBACA,WACU;AAAA,EACV,IAAI;AAAA,IACH,OAAO,WACN,MACA,OAAO,KAAK,SAAS,MAAM,GAC3B,WACA,OAAO,KAAK,iBAAiB,QAAQ,CACtC;AAAA,IACC,MAAM;AAAA,IACP,OAAO;AAAA;AAAA;",
|
|
8
|
+
"debugId": "B4FC95F24211B0D064756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Secondlayer webhook authenticity — an ed25519 signature attached to
|
|
3
|
+
* EVERY delivery regardless of body format.
|
|
4
|
+
*
|
|
5
|
+
* Only the `standard-webhooks` format carries an HMAC; `raw`/`cloudevents`/etc.
|
|
6
|
+
* carried no Secondlayer proof, so a receiver had no way to know a payload came
|
|
7
|
+
* from us. This signs each delivery with a single platform ed25519 key so any
|
|
8
|
+
* receiver verifies with the published public key — no per-subscription secret,
|
|
9
|
+
* and the body shape stays format-specific.
|
|
10
|
+
*
|
|
11
|
+
* Header names are lowercase to match the format builders' header maps (HTTP
|
|
12
|
+
* header names are case-insensitive on the wire).
|
|
13
|
+
*/
|
|
14
|
+
declare const WEBHOOK_ID_HEADER = "webhook-id";
|
|
15
|
+
declare const SECONDLAYER_SIGNATURE_HEADER = "x-secondlayer-signature";
|
|
16
|
+
declare const SECONDLAYER_KEY_ID_HEADER = "x-secondlayer-signature-keyid";
|
|
17
|
+
type SecondlayerWebhookSigner = {
|
|
18
|
+
keyId: string
|
|
19
|
+
publicKeyPem: string
|
|
20
|
+
sign(payload: string): string
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Memoized webhook signer, or null when no key is configured (signing is then a
|
|
24
|
+
* no-op, so the universal header is safe to ship before a key is provisioned).
|
|
25
|
+
*/
|
|
26
|
+
declare function getSecondlayerWebhookSigner(): SecondlayerWebhookSigner | null;
|
|
27
|
+
/** Reset the memoized signer. Tests only. */
|
|
28
|
+
declare function resetSecondlayerWebhookSignerForTest(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Build the universal authenticity headers for a delivery. Returns null when no
|
|
31
|
+
* signing key is configured (caller leaves the delivery unsigned).
|
|
32
|
+
*/
|
|
33
|
+
declare function signSecondlayerWebhook(webhookId: string, body: string): Record<string, string> | null;
|
|
34
|
+
/**
|
|
35
|
+
* Verify a delivery's ed25519 signature over `${webhookId}.${rawBody}` against
|
|
36
|
+
* the published public key. Low-level (raw values); receivers use the SDK's
|
|
37
|
+
* `verifySecondlayerSignature`, which extracts the headers ergonomically.
|
|
38
|
+
*/
|
|
39
|
+
declare function verifySecondlayerSignatureValues(rawBody: string, webhookId: string | undefined, signatureBase64: string | undefined, publicKeyPem: string): boolean;
|
|
40
|
+
export { verifySecondlayerSignatureValues, signSecondlayerWebhook, resetSecondlayerWebhookSignerForTest, getSecondlayerWebhookSigner, WEBHOOK_ID_HEADER, SecondlayerWebhookSigner, SECONDLAYER_SIGNATURE_HEADER, SECONDLAYER_KEY_ID_HEADER };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/crypto/ed25519.ts
|
|
18
|
+
var exports_ed25519 = {};
|
|
19
|
+
__export(exports_ed25519, {
|
|
20
|
+
verifyEd25519: () => verifyEd25519,
|
|
21
|
+
signEd25519: () => signEd25519,
|
|
22
|
+
publicKeyPemFromPrivate: () => publicKeyPemFromPrivate,
|
|
23
|
+
loadEd25519PublicKey: () => loadEd25519PublicKey,
|
|
24
|
+
loadEd25519PrivateKey: () => loadEd25519PrivateKey,
|
|
25
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
26
|
+
ed25519KeyId: () => ed25519KeyId
|
|
27
|
+
});
|
|
28
|
+
import {
|
|
29
|
+
createHash,
|
|
30
|
+
createPrivateKey,
|
|
31
|
+
createPublicKey,
|
|
32
|
+
generateKeyPairSync,
|
|
33
|
+
sign as nodeSign,
|
|
34
|
+
verify as nodeVerify
|
|
35
|
+
} from "node:crypto";
|
|
36
|
+
function generateEd25519KeyPair() {
|
|
37
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
38
|
+
return {
|
|
39
|
+
privateKeyPem: privateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
|
40
|
+
publicKeyPem: publicKey.export({ format: "pem", type: "spki" }).toString()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function loadEd25519PrivateKey(pem) {
|
|
44
|
+
return createPrivateKey(pem);
|
|
45
|
+
}
|
|
46
|
+
function loadEd25519PublicKey(pem) {
|
|
47
|
+
return createPublicKey(pem);
|
|
48
|
+
}
|
|
49
|
+
function publicKeyPemFromPrivate(privateKeyPem) {
|
|
50
|
+
return createPublicKey(createPrivateKey(privateKeyPem)).export({ format: "pem", type: "spki" }).toString();
|
|
51
|
+
}
|
|
52
|
+
function ed25519KeyId(publicKeyPem) {
|
|
53
|
+
const der = createPublicKey(publicKeyPem).export({
|
|
54
|
+
format: "der",
|
|
55
|
+
type: "spki"
|
|
56
|
+
});
|
|
57
|
+
return createHash("sha256").update(der).digest("base64url").slice(0, 16);
|
|
58
|
+
}
|
|
59
|
+
function signEd25519(payload, privateKey) {
|
|
60
|
+
return nodeSign(null, Buffer.from(payload, "utf8"), privateKey).toString("base64");
|
|
61
|
+
}
|
|
62
|
+
function verifyEd25519(payload, signatureBase64, publicKey) {
|
|
63
|
+
try {
|
|
64
|
+
return nodeVerify(null, Buffer.from(payload, "utf8"), publicKey, Buffer.from(signatureBase64, "base64"));
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/crypto/secondlayer-webhook.ts
|
|
71
|
+
var WEBHOOK_ID_HEADER = "webhook-id";
|
|
72
|
+
var SECONDLAYER_SIGNATURE_HEADER = "x-secondlayer-signature";
|
|
73
|
+
var SECONDLAYER_KEY_ID_HEADER = "x-secondlayer-signature-keyid";
|
|
74
|
+
var cached;
|
|
75
|
+
function signingKeyFromEnv() {
|
|
76
|
+
return process.env.SECONDLAYER_WEBHOOK_SIGNING_PRIVATE_KEY || process.env.STREAMS_SIGNING_PRIVATE_KEY || undefined;
|
|
77
|
+
}
|
|
78
|
+
function getSecondlayerWebhookSigner() {
|
|
79
|
+
if (cached !== undefined)
|
|
80
|
+
return cached;
|
|
81
|
+
const raw = signingKeyFromEnv();
|
|
82
|
+
if (!raw) {
|
|
83
|
+
cached = null;
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const pem = raw.includes("\\n") ? raw.replace(/\\n/g, `
|
|
87
|
+
`) : raw;
|
|
88
|
+
const privateKey = loadEd25519PrivateKey(pem);
|
|
89
|
+
const publicKeyPem = publicKeyPemFromPrivate(pem);
|
|
90
|
+
cached = {
|
|
91
|
+
keyId: ed25519KeyId(publicKeyPem),
|
|
92
|
+
publicKeyPem,
|
|
93
|
+
sign: (payload) => signEd25519(payload, privateKey)
|
|
94
|
+
};
|
|
95
|
+
return cached;
|
|
96
|
+
}
|
|
97
|
+
function resetSecondlayerWebhookSignerForTest() {
|
|
98
|
+
cached = undefined;
|
|
99
|
+
}
|
|
100
|
+
function signedContent(webhookId, body) {
|
|
101
|
+
return `${webhookId}.${body}`;
|
|
102
|
+
}
|
|
103
|
+
function signSecondlayerWebhook(webhookId, body) {
|
|
104
|
+
const signer = getSecondlayerWebhookSigner();
|
|
105
|
+
if (!signer)
|
|
106
|
+
return null;
|
|
107
|
+
return {
|
|
108
|
+
[WEBHOOK_ID_HEADER]: webhookId,
|
|
109
|
+
[SECONDLAYER_SIGNATURE_HEADER]: signer.sign(signedContent(webhookId, body)),
|
|
110
|
+
[SECONDLAYER_KEY_ID_HEADER]: signer.keyId
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function verifySecondlayerSignatureValues(rawBody, webhookId, signatureBase64, publicKeyPem) {
|
|
114
|
+
if (!webhookId || !signatureBase64)
|
|
115
|
+
return false;
|
|
116
|
+
const publicKey = loadEd25519PublicKey(publicKeyPem);
|
|
117
|
+
return verifyEd25519(signedContent(webhookId, rawBody), signatureBase64, publicKey);
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
verifySecondlayerSignatureValues,
|
|
121
|
+
signSecondlayerWebhook,
|
|
122
|
+
resetSecondlayerWebhookSignerForTest,
|
|
123
|
+
getSecondlayerWebhookSigner,
|
|
124
|
+
WEBHOOK_ID_HEADER,
|
|
125
|
+
SECONDLAYER_SIGNATURE_HEADER,
|
|
126
|
+
SECONDLAYER_KEY_ID_HEADER
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
//# debugId=ECECE08A1A6DA84764756E2164756E21
|
|
130
|
+
//# sourceMappingURL=secondlayer-webhook.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/crypto/ed25519.ts", "../src/crypto/secondlayer-webhook.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n\ttype KeyObject,\n\tcreateHash,\n\tcreatePrivateKey,\n\tcreatePublicKey,\n\tgenerateKeyPairSync,\n\tsign as nodeSign,\n\tverify as nodeVerify,\n} from \"node:crypto\";\n\n/**\n * Asymmetric ed25519 signing for Streams response proofs.\n *\n * Asymmetric (not HMAC) so the proof is real: only the server holds the private\n * key, and any consumer verifies with the published public key — no shared\n * secret to leak. ed25519 uses node's `sign`/`verify` with a `null` algorithm.\n * Keys are PEM (PKCS8 private / SPKI public) for env transport; load once and\n * reuse the KeyObject on hot paths.\n */\n\nexport function generateEd25519KeyPair(): {\n\tprivateKeyPem: string;\n\tpublicKeyPem: string;\n} {\n\tconst { privateKey, publicKey } = generateKeyPairSync(\"ed25519\");\n\treturn {\n\t\tprivateKeyPem: privateKey\n\t\t\t.export({ format: \"pem\", type: \"pkcs8\" })\n\t\t\t.toString(),\n\t\tpublicKeyPem: publicKey.export({ format: \"pem\", type: \"spki\" }).toString(),\n\t};\n}\n\nexport function loadEd25519PrivateKey(pem: string): KeyObject {\n\treturn createPrivateKey(pem);\n}\n\nexport function loadEd25519PublicKey(pem: string): KeyObject {\n\treturn createPublicKey(pem);\n}\n\nexport function publicKeyPemFromPrivate(privateKeyPem: string): string {\n\treturn createPublicKey(createPrivateKey(privateKeyPem))\n\t\t.export({ format: \"pem\", type: \"spki\" })\n\t\t.toString();\n}\n\n/** Stable short id for a public key (rotation hint via X-Signature-KeyId). */\nexport function ed25519KeyId(publicKeyPem: string): string {\n\tconst der = createPublicKey(publicKeyPem).export({\n\t\tformat: \"der\",\n\t\ttype: \"spki\",\n\t});\n\treturn createHash(\"sha256\").update(der).digest(\"base64url\").slice(0, 16);\n}\n\nexport function signEd25519(payload: string, privateKey: KeyObject): string {\n\treturn nodeSign(null, Buffer.from(payload, \"utf8\"), privateKey).toString(\n\t\t\"base64\",\n\t);\n}\n\nexport function verifyEd25519(\n\tpayload: string,\n\tsignatureBase64: string,\n\tpublicKey: KeyObject,\n): boolean {\n\ttry {\n\t\treturn nodeVerify(\n\t\t\tnull,\n\t\t\tBuffer.from(payload, \"utf8\"),\n\t\t\tpublicKey,\n\t\t\tBuffer.from(signatureBase64, \"base64\"),\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n",
|
|
6
|
+
"import {\n\ted25519KeyId,\n\tloadEd25519PrivateKey,\n\tloadEd25519PublicKey,\n\tpublicKeyPemFromPrivate,\n\tsignEd25519,\n\tverifyEd25519,\n} from \"./ed25519.ts\";\n\n/**\n * Universal Secondlayer webhook authenticity — an ed25519 signature attached to\n * EVERY delivery regardless of body format.\n *\n * Only the `standard-webhooks` format carries an HMAC; `raw`/`cloudevents`/etc.\n * carried no Secondlayer proof, so a receiver had no way to know a payload came\n * from us. This signs each delivery with a single platform ed25519 key so any\n * receiver verifies with the published public key — no per-subscription secret,\n * and the body shape stays format-specific.\n *\n * Header names are lowercase to match the format builders' header maps (HTTP\n * header names are case-insensitive on the wire).\n */\nexport const WEBHOOK_ID_HEADER = \"webhook-id\";\nexport const SECONDLAYER_SIGNATURE_HEADER = \"x-secondlayer-signature\";\nexport const SECONDLAYER_KEY_ID_HEADER = \"x-secondlayer-signature-keyid\";\n\nexport type SecondlayerWebhookSigner = {\n\tkeyId: string;\n\tpublicKeyPem: string;\n\tsign(payload: string): string;\n};\n\nlet cached: SecondlayerWebhookSigner | null | undefined;\n\nfunction signingKeyFromEnv(): string | undefined {\n\t// A dedicated webhook key if provided, else the platform Streams key — both\n\t// are the same ed25519 \"single platform identity\", so reusing it keeps key\n\t// distribution to one published public key.\n\treturn (\n\t\tprocess.env.SECONDLAYER_WEBHOOK_SIGNING_PRIVATE_KEY ||\n\t\tprocess.env.STREAMS_SIGNING_PRIVATE_KEY ||\n\t\tundefined\n\t);\n}\n\n/**\n * Memoized webhook signer, or null when no key is configured (signing is then a\n * no-op, so the universal header is safe to ship before a key is provisioned).\n */\nexport function getSecondlayerWebhookSigner(): SecondlayerWebhookSigner | null {\n\tif (cached !== undefined) return cached;\n\tconst raw = signingKeyFromEnv();\n\tif (!raw) {\n\t\tcached = null;\n\t\treturn null;\n\t}\n\t// Env transport often escapes newlines; restore real PEM line breaks.\n\tconst pem = raw.includes(\"\\\\n\") ? raw.replace(/\\\\n/g, \"\\n\") : raw;\n\tconst privateKey = loadEd25519PrivateKey(pem);\n\tconst publicKeyPem = publicKeyPemFromPrivate(pem);\n\tcached = {\n\t\tkeyId: ed25519KeyId(publicKeyPem),\n\t\tpublicKeyPem,\n\t\tsign: (payload) => signEd25519(payload, privateKey),\n\t};\n\treturn cached;\n}\n\n/** Reset the memoized signer. Tests only. */\nexport function resetSecondlayerWebhookSignerForTest(): void {\n\tcached = undefined;\n}\n\n/**\n * The exact bytes the signature covers: `${webhookId}.${body}`. Binding the id\n * into the signed content stops a captured body from being replayed under a\n * different delivery id.\n */\nfunction signedContent(webhookId: string, body: string): string {\n\treturn `${webhookId}.${body}`;\n}\n\n/**\n * Build the universal authenticity headers for a delivery. Returns null when no\n * signing key is configured (caller leaves the delivery unsigned).\n */\nexport function signSecondlayerWebhook(\n\twebhookId: string,\n\tbody: string,\n): Record<string, string> | null {\n\tconst signer = getSecondlayerWebhookSigner();\n\tif (!signer) return null;\n\treturn {\n\t\t[WEBHOOK_ID_HEADER]: webhookId,\n\t\t[SECONDLAYER_SIGNATURE_HEADER]: signer.sign(signedContent(webhookId, body)),\n\t\t[SECONDLAYER_KEY_ID_HEADER]: signer.keyId,\n\t};\n}\n\n/**\n * Verify a delivery's ed25519 signature over `${webhookId}.${rawBody}` against\n * the published public key. Low-level (raw values); receivers use the SDK's\n * `verifySecondlayerSignature`, which extracts the headers ergonomically.\n */\nexport function verifySecondlayerSignatureValues(\n\trawBody: string,\n\twebhookId: string | undefined,\n\tsignatureBase64: string | undefined,\n\tpublicKeyPem: string,\n): boolean {\n\tif (!webhookId || !signatureBase64) return false;\n\tconst publicKey = loadEd25519PublicKey(publicKeyPem);\n\treturn verifyEd25519(\n\t\tsignedContent(webhookId, rawBody),\n\t\tsignatureBase64,\n\t\tpublicKey,\n\t);\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "ECECE08A1A6DA84764756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1767,6 +1767,30 @@ declare function createSignatureHeader(payload: string, secret: string, timestam
|
|
|
1767
1767
|
* Returns true if valid, false otherwise
|
|
1768
1768
|
*/
|
|
1769
1769
|
declare function verifySignatureHeader(payload: string, header: string, secret: string, toleranceSeconds?: number): boolean;
|
|
1770
|
+
declare namespace exports_ed25519 {
|
|
1771
|
+
export { verifyEd25519, signEd25519, publicKeyPemFromPrivate, loadEd25519PublicKey, loadEd25519PrivateKey, generateEd25519KeyPair, ed25519KeyId };
|
|
1772
|
+
}
|
|
1773
|
+
import { KeyObject } from "node:crypto";
|
|
1774
|
+
/**
|
|
1775
|
+
* Asymmetric ed25519 signing for Streams response proofs.
|
|
1776
|
+
*
|
|
1777
|
+
* Asymmetric (not HMAC) so the proof is real: only the server holds the private
|
|
1778
|
+
* key, and any consumer verifies with the published public key — no shared
|
|
1779
|
+
* secret to leak. ed25519 uses node's `sign`/`verify` with a `null` algorithm.
|
|
1780
|
+
* Keys are PEM (PKCS8 private / SPKI public) for env transport; load once and
|
|
1781
|
+
* reuse the KeyObject on hot paths.
|
|
1782
|
+
*/
|
|
1783
|
+
declare function generateEd25519KeyPair(): {
|
|
1784
|
+
privateKeyPem: string
|
|
1785
|
+
publicKeyPem: string
|
|
1786
|
+
};
|
|
1787
|
+
declare function loadEd25519PrivateKey(pem: string): KeyObject;
|
|
1788
|
+
declare function loadEd25519PublicKey(pem: string): KeyObject;
|
|
1789
|
+
declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
|
|
1790
|
+
/** Stable short id for a public key (rotation hint via X-Signature-KeyId). */
|
|
1791
|
+
declare function ed25519KeyId(publicKeyPem: string): string;
|
|
1792
|
+
declare function signEd25519(payload: string, privateKey: KeyObject): string;
|
|
1793
|
+
declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
|
|
1770
1794
|
declare const DECODED_EVENT_TYPES: readonly ["stx_transfer", "stx_mint", "stx_burn", "stx_lock", "ft_transfer", "ft_mint", "ft_burn", "nft_transfer", "nft_mint", "nft_burn", "print"];
|
|
1771
1795
|
type DecodedEventType = (typeof DECODED_EVENT_TYPES)[number];
|
|
1772
1796
|
/** Alias kept for the Streams surface (identical to {@link DECODED_EVENT_TYPES}).
|
|
@@ -1826,28 +1850,4 @@ type StreamsCursor = {
|
|
|
1826
1850
|
declare const EMPTY_RANGE_EVENT_INDEX_SENTINEL = 2147483647;
|
|
1827
1851
|
declare function encodeStreamsCursor(cursor: StreamsCursor): string;
|
|
1828
1852
|
declare function decodeStreamsCursor(cursor: string): StreamsCursor;
|
|
1829
|
-
declare namespace exports_ed25519 {
|
|
1830
|
-
export { verifyEd25519, signEd25519, publicKeyPemFromPrivate, loadEd25519PublicKey, loadEd25519PrivateKey, generateEd25519KeyPair, ed25519KeyId };
|
|
1831
|
-
}
|
|
1832
|
-
import { KeyObject } from "node:crypto";
|
|
1833
|
-
/**
|
|
1834
|
-
* Asymmetric ed25519 signing for Streams response proofs.
|
|
1835
|
-
*
|
|
1836
|
-
* Asymmetric (not HMAC) so the proof is real: only the server holds the private
|
|
1837
|
-
* key, and any consumer verifies with the published public key — no shared
|
|
1838
|
-
* secret to leak. ed25519 uses node's `sign`/`verify` with a `null` algorithm.
|
|
1839
|
-
* Keys are PEM (PKCS8 private / SPKI public) for env transport; load once and
|
|
1840
|
-
* reuse the KeyObject on hot paths.
|
|
1841
|
-
*/
|
|
1842
|
-
declare function generateEd25519KeyPair(): {
|
|
1843
|
-
privateKeyPem: string
|
|
1844
|
-
publicKeyPem: string
|
|
1845
|
-
};
|
|
1846
|
-
declare function loadEd25519PrivateKey(pem: string): KeyObject;
|
|
1847
|
-
declare function loadEd25519PublicKey(pem: string): KeyObject;
|
|
1848
|
-
declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
|
|
1849
|
-
/** Stable short id for a public key (rotation hint via X-Signature-KeyId). */
|
|
1850
|
-
declare function ed25519KeyId(publicKeyPem: string): string;
|
|
1851
|
-
declare function signEd25519(payload: string, privateKey: KeyObject): string;
|
|
1852
|
-
declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
|
|
1853
1853
|
export { validateSubscriptionFilterForTable, sql, setMigrationRole, parseJsonb, onControlPlane, onChainPlane, logger, jsonb, isPox4DecoderEnabled, getTargetDb, getSourceDb, getRawClientFor, getRawClient, getMigrationRole, getErrorMessage, getEnv, getDbSplitStatus, getDb, generateSubgraphSpec, generateSubgraphOpenApi, generateSubgraphMarkdown, generateSubgraphAgentSchema, formatSubscriptionSchemaErrors, finalizedBurnHeight, encodeStreamsCursor, exports_ed25519 as ed25519, decodeStreamsCursor, exports_hmac as crypto, closeDb, assertDbSplit, VersionConflictError, ValidationError, UsageSnapshotsTable, UsageSnapshot, UsageDailyTable, UsageDaily, UpdateTransaction, UpdateTenantUsageMonthly, UpdateTenantComputeAddon, UpdateTenant, UpdateSubscriptionRequestSchema, UpdateSubscriptionRequest, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateProject, UpdateIndexProgress, UpdateEvent, UpdateContract, UpdateChatSession, UpdateBlock, UpdateApiKey, UpdateAccountSpendCap, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, TenantsTable, TenantUsageMonthlyTable, TenantUsageMonthly, TenantSuspendedError, TenantStatus, TenantComputeAddonsTable, TenantComputeAddon, Tenant, TeamMembersTable, TeamMember, TeamInvitationsTable, TeamInvitation, TABLE_TO_DB, SubscriptionsTable, SubscriptionSummary, SubscriptionStatusSchema, SubscriptionStatus, SubscriptionSchemaTables, SubscriptionSchemaTable, SubscriptionSchemaColumn, SubscriptionRuntimeSchema, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionKind, SubscriptionFormatSchema, SubscriptionFormat, SubscriptionFilterSchema, SubscriptionFilterPrimitiveSchema, SubscriptionFilterPrimitive, SubscriptionFilterOperatorSchema, SubscriptionFilterOperator, SubscriptionFilterClauseSchema, SubscriptionFilterClause, SubscriptionFilter, SubscriptionDetail, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphUsageDailyTable, SubgraphUsageDaily, SubgraphTableSnapshotsTable, SubgraphSyncInfo, SubgraphSummary, SubgraphSpecOptions, SubgraphSpecFormat, SubgraphResourceWarning, SubgraphQueryParams, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGapsResponse, SubgraphGapRange, SubgraphGapEntry, SubgraphGap, SubgraphDetail, SubgraphAgentSchema, Subgraph, StxTransferFilterSchema, StxTransferFilter, StxMintFilterSchema, StxMintFilter, StxLockFilterSchema, StxLockFilter, StxBurnFilterSchema, StxBurnFilter, StreamsEventType, StreamsDbEventType, StreamsCursor, SessionsTable, Session, ServiceHeartbeatsTable, SecondLayerError, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcEventsTable, SbtcEventTopic, SUBSCRIPTION_STATUSES, SUBSCRIPTION_RUNTIMES, SUBSCRIPTION_FORMATS, SUBSCRIPTION_FILTER_OPERATORS, STREAMS_TO_DB_EVENT_TYPES, STREAMS_EVENT_TYPES, STREAMS_DB_EVENT_TYPES, SOURCE_READ_COLUMNS, RotateSecretResponse, ReplaySubscriptionRequestSchema, ReplaySubscriptionRequest, ReplayResult, ReindexResponse, RateLimitError, ProvisioningAuditStatus, ProvisioningAuditLogTable, ProvisioningAuditLog, ProvisioningAuditEvent, ProjectsTable, Project, ProcessedStripeEventsTable, PrintEventFilterSchema, PrintEventFilter, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, ParsedUpdateSubscriptionRequest, ParsedReplaySubscriptionRequest, ParsedCreateSubscriptionRequest, OutboxStatus, NumericAsText, NotFoundError, NftTransferFilterSchema, NftTransferFilter, NftMintFilterSchema, NftMintFilter, NftBurnFilterSchema, NftBurnFilter, MigrationRole, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, L2DecoderCheckpointsTable, KeyRotatedError, InsertTransaction, InsertTenantUsageMonthly, InsertTenantComputeAddon, InsertTenant, InsertTeamMember, InsertTeamInvitation, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphUsageDaily, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertProvisioningAuditLog, InsertProject, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertContract, InsertChatSession, InsertChatMessage, InsertBlock, InsertApiKey, InsertAccountSpendCap, InsertAccountInsight, InsertAccountAgentRun, InsertAccount, IndexProgressTable, IndexProgress, FtTransferFilterSchema, FtTransferFilter, FtMintFilterSchema, FtMintFilter, FtBurnFilterSchema, FtBurnFilter, ForbiddenError, EventsTable, EventsArchiveTable, EventFilterSchema, EventFilter, Event, ErrorCodes, ErrorCode, Env, EMPTY_RANGE_EVENT_INDEX_SENTINEL, DeploySubgraphResponse, DeploySubgraphRequestSchema, DeploySubgraphRequest, DeliveryRow, DecodedEventsTable, DecodedEventType, DeadRow, DeadLetterEventsTable, DbSplitStatus, DbReadRow, DbPlane, DatabaseError, Database, DEFAULT_BTC_CONFIRMATIONS, DECODED_EVENT_TYPES, DB_TO_STREAMS_EVENT_TYPE, CreateSubscriptionResponse, CreateSubscriptionRequestSchema, CreateSubscriptionRequest, ContractsTable, ContractDeployFilterSchema, ContractDeployFilter, ContractCallFilterSchema, ContractCallFilter, Contract, ChatSessionsTable, ChatSession, ChatMessagesTable, ChatMessage, ChainReorgsTable, CODE_TO_STATUS, CHAIN_TRIGGER_TYPES, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, AuthorizationError, AuthenticationError, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountInsightsTable, AccountInsight, AccountAgentRunsTable, AccountAgentRun, Account };
|
package/dist/src/index.js
CHANGED
|
@@ -1549,6 +1549,59 @@ function verifySignatureHeader(payload, header, secret, toleranceSeconds = 300)
|
|
|
1549
1549
|
const signedPayload = `${ts}.${payload}`;
|
|
1550
1550
|
return verifySignature(signedPayload, signature, secret);
|
|
1551
1551
|
}
|
|
1552
|
+
|
|
1553
|
+
// src/crypto/ed25519.ts
|
|
1554
|
+
var exports_ed25519 = {};
|
|
1555
|
+
__export(exports_ed25519, {
|
|
1556
|
+
verifyEd25519: () => verifyEd25519,
|
|
1557
|
+
signEd25519: () => signEd25519,
|
|
1558
|
+
publicKeyPemFromPrivate: () => publicKeyPemFromPrivate,
|
|
1559
|
+
loadEd25519PublicKey: () => loadEd25519PublicKey,
|
|
1560
|
+
loadEd25519PrivateKey: () => loadEd25519PrivateKey,
|
|
1561
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
1562
|
+
ed25519KeyId: () => ed25519KeyId
|
|
1563
|
+
});
|
|
1564
|
+
import {
|
|
1565
|
+
createHash,
|
|
1566
|
+
createPrivateKey,
|
|
1567
|
+
createPublicKey,
|
|
1568
|
+
generateKeyPairSync,
|
|
1569
|
+
sign as nodeSign,
|
|
1570
|
+
verify as nodeVerify
|
|
1571
|
+
} from "node:crypto";
|
|
1572
|
+
function generateEd25519KeyPair() {
|
|
1573
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
1574
|
+
return {
|
|
1575
|
+
privateKeyPem: privateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
|
1576
|
+
publicKeyPem: publicKey.export({ format: "pem", type: "spki" }).toString()
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
function loadEd25519PrivateKey(pem) {
|
|
1580
|
+
return createPrivateKey(pem);
|
|
1581
|
+
}
|
|
1582
|
+
function loadEd25519PublicKey(pem) {
|
|
1583
|
+
return createPublicKey(pem);
|
|
1584
|
+
}
|
|
1585
|
+
function publicKeyPemFromPrivate(privateKeyPem) {
|
|
1586
|
+
return createPublicKey(createPrivateKey(privateKeyPem)).export({ format: "pem", type: "spki" }).toString();
|
|
1587
|
+
}
|
|
1588
|
+
function ed25519KeyId(publicKeyPem) {
|
|
1589
|
+
const der = createPublicKey(publicKeyPem).export({
|
|
1590
|
+
format: "der",
|
|
1591
|
+
type: "spki"
|
|
1592
|
+
});
|
|
1593
|
+
return createHash("sha256").update(der).digest("base64url").slice(0, 16);
|
|
1594
|
+
}
|
|
1595
|
+
function signEd25519(payload, privateKey) {
|
|
1596
|
+
return nodeSign(null, Buffer.from(payload, "utf8"), privateKey).toString("base64");
|
|
1597
|
+
}
|
|
1598
|
+
function verifyEd25519(payload, signatureBase64, publicKey) {
|
|
1599
|
+
try {
|
|
1600
|
+
return nodeVerify(null, Buffer.from(payload, "utf8"), publicKey, Buffer.from(signatureBase64, "base64"));
|
|
1601
|
+
} catch {
|
|
1602
|
+
return false;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1552
1605
|
// src/event-types.ts
|
|
1553
1606
|
var DECODED_EVENT_TYPES = [
|
|
1554
1607
|
"stx_transfer",
|
|
@@ -1636,58 +1689,6 @@ function decodeStreamsCursor(cursor) {
|
|
|
1636
1689
|
}
|
|
1637
1690
|
return decoded;
|
|
1638
1691
|
}
|
|
1639
|
-
// src/crypto/ed25519.ts
|
|
1640
|
-
var exports_ed25519 = {};
|
|
1641
|
-
__export(exports_ed25519, {
|
|
1642
|
-
verifyEd25519: () => verifyEd25519,
|
|
1643
|
-
signEd25519: () => signEd25519,
|
|
1644
|
-
publicKeyPemFromPrivate: () => publicKeyPemFromPrivate,
|
|
1645
|
-
loadEd25519PublicKey: () => loadEd25519PublicKey,
|
|
1646
|
-
loadEd25519PrivateKey: () => loadEd25519PrivateKey,
|
|
1647
|
-
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
1648
|
-
ed25519KeyId: () => ed25519KeyId
|
|
1649
|
-
});
|
|
1650
|
-
import {
|
|
1651
|
-
createHash,
|
|
1652
|
-
createPrivateKey,
|
|
1653
|
-
createPublicKey,
|
|
1654
|
-
generateKeyPairSync,
|
|
1655
|
-
sign as nodeSign,
|
|
1656
|
-
verify as nodeVerify
|
|
1657
|
-
} from "node:crypto";
|
|
1658
|
-
function generateEd25519KeyPair() {
|
|
1659
|
-
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
1660
|
-
return {
|
|
1661
|
-
privateKeyPem: privateKey.export({ format: "pem", type: "pkcs8" }).toString(),
|
|
1662
|
-
publicKeyPem: publicKey.export({ format: "pem", type: "spki" }).toString()
|
|
1663
|
-
};
|
|
1664
|
-
}
|
|
1665
|
-
function loadEd25519PrivateKey(pem) {
|
|
1666
|
-
return createPrivateKey(pem);
|
|
1667
|
-
}
|
|
1668
|
-
function loadEd25519PublicKey(pem) {
|
|
1669
|
-
return createPublicKey(pem);
|
|
1670
|
-
}
|
|
1671
|
-
function publicKeyPemFromPrivate(privateKeyPem) {
|
|
1672
|
-
return createPublicKey(createPrivateKey(privateKeyPem)).export({ format: "pem", type: "spki" }).toString();
|
|
1673
|
-
}
|
|
1674
|
-
function ed25519KeyId(publicKeyPem) {
|
|
1675
|
-
const der = createPublicKey(publicKeyPem).export({
|
|
1676
|
-
format: "der",
|
|
1677
|
-
type: "spki"
|
|
1678
|
-
});
|
|
1679
|
-
return createHash("sha256").update(der).digest("base64url").slice(0, 16);
|
|
1680
|
-
}
|
|
1681
|
-
function signEd25519(payload, privateKey) {
|
|
1682
|
-
return nodeSign(null, Buffer.from(payload, "utf8"), privateKey).toString("base64");
|
|
1683
|
-
}
|
|
1684
|
-
function verifyEd25519(payload, signatureBase64, publicKey) {
|
|
1685
|
-
try {
|
|
1686
|
-
return nodeVerify(null, Buffer.from(payload, "utf8"), publicKey, Buffer.from(signatureBase64, "base64"));
|
|
1687
|
-
} catch {
|
|
1688
|
-
return false;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
1692
|
export {
|
|
1692
1693
|
validateSubscriptionFilterForTable,
|
|
1693
1694
|
sql2 as sql,
|
|
@@ -1773,5 +1774,5 @@ export {
|
|
|
1773
1774
|
AuthenticationError
|
|
1774
1775
|
};
|
|
1775
1776
|
|
|
1776
|
-
//# debugId=
|
|
1777
|
+
//# debugId=E26BA28FDF632B7E64756E2164756E21
|
|
1777
1778
|
//# sourceMappingURL=index.js.map
|