@korala/auth 1.0.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/hmac.d.ts ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Maximum age of a request signature in seconds (5 minutes)
3
+ */
4
+ export declare const MAX_TIMESTAMP_AGE_SECONDS = 300;
5
+ /**
6
+ * Request data needed for signature generation/verification
7
+ */
8
+ export interface SignatureRequest {
9
+ method: string;
10
+ path: string;
11
+ body?: string;
12
+ }
13
+ /**
14
+ * Build the payload string used for HMAC signing
15
+ */
16
+ export declare function buildSignaturePayload(request: SignatureRequest, timestamp: string): string;
17
+ /**
18
+ * Compute HMAC-SHA256 signature for a payload
19
+ */
20
+ export declare function computeSignature(payload: string, secret: string): string;
21
+ /**
22
+ * Verify a signature using timing-safe comparison
23
+ */
24
+ export declare function verifySignature(provided: string, expected: string): boolean;
25
+ /**
26
+ * Check if a timestamp is within the allowed age window
27
+ */
28
+ export declare function isTimestampValid(timestamp: number, maxAgeSeconds?: number): boolean;
29
+ /**
30
+ * Generate current Unix timestamp in seconds
31
+ */
32
+ export declare function getTimestamp(): string;
33
+ /**
34
+ * Hash a secret for storage using SHA-256
35
+ */
36
+ export declare function hashSecret(secret: string): string;
37
+ /**
38
+ * Sign a request and return the headers needed for authentication
39
+ */
40
+ export declare function signRequest(request: SignatureRequest, keyId: string, secret: string): {
41
+ 'x-api-key': string;
42
+ 'x-timestamp': string;
43
+ 'x-signature': string;
44
+ };
45
+ /**
46
+ * Webhook signature headers
47
+ */
48
+ export interface WebhookSignatureHeaders {
49
+ 'x-webhook-signature': string;
50
+ 'x-webhook-timestamp': string;
51
+ 'x-webhook-event': string;
52
+ }
53
+ /**
54
+ * Sign a webhook payload and return the headers
55
+ */
56
+ export declare function signWebhookPayload(payload: string, secret: string, eventType: string): WebhookSignatureHeaders;
57
+ /**
58
+ * Verify a webhook signature
59
+ */
60
+ export declare function verifyWebhookSignature(payload: string, timestamp: string, signature: string, secret: string, maxAgeSeconds?: number): boolean;
61
+ //# sourceMappingURL=hmac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAa3E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,MAAkC,GAChD,OAAO,CAGT;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAUvE;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,uBAAuB,CAUzB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAkC,GAChD,OAAO,CAgBT"}
package/dist/hmac.js ADDED
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_TIMESTAMP_AGE_SECONDS = void 0;
4
+ exports.buildSignaturePayload = buildSignaturePayload;
5
+ exports.computeSignature = computeSignature;
6
+ exports.verifySignature = verifySignature;
7
+ exports.isTimestampValid = isTimestampValid;
8
+ exports.getTimestamp = getTimestamp;
9
+ exports.hashSecret = hashSecret;
10
+ exports.signRequest = signRequest;
11
+ exports.signWebhookPayload = signWebhookPayload;
12
+ exports.verifyWebhookSignature = verifyWebhookSignature;
13
+ const crypto_1 = require("crypto");
14
+ /**
15
+ * Maximum age of a request signature in seconds (5 minutes)
16
+ */
17
+ exports.MAX_TIMESTAMP_AGE_SECONDS = 300;
18
+ /**
19
+ * Build the payload string used for HMAC signing
20
+ */
21
+ function buildSignaturePayload(request, timestamp) {
22
+ const method = request.method.toUpperCase();
23
+ const path = request.path;
24
+ const body = request.body ?? '';
25
+ return `${timestamp}.${method}.${path}.${body}`;
26
+ }
27
+ /**
28
+ * Compute HMAC-SHA256 signature for a payload
29
+ */
30
+ function computeSignature(payload, secret) {
31
+ return (0, crypto_1.createHmac)('sha256', secret).update(payload).digest('hex');
32
+ }
33
+ /**
34
+ * Verify a signature using timing-safe comparison
35
+ */
36
+ function verifySignature(provided, expected) {
37
+ try {
38
+ const providedBuffer = Buffer.from(provided, 'hex');
39
+ const expectedBuffer = Buffer.from(expected, 'hex');
40
+ if (providedBuffer.length !== expectedBuffer.length) {
41
+ return false;
42
+ }
43
+ return (0, crypto_1.timingSafeEqual)(providedBuffer, expectedBuffer);
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ }
49
+ /**
50
+ * Check if a timestamp is within the allowed age window
51
+ */
52
+ function isTimestampValid(timestamp, maxAgeSeconds = exports.MAX_TIMESTAMP_AGE_SECONDS) {
53
+ const now = Math.floor(Date.now() / 1000);
54
+ return Math.abs(now - timestamp) <= maxAgeSeconds;
55
+ }
56
+ /**
57
+ * Generate current Unix timestamp in seconds
58
+ */
59
+ function getTimestamp() {
60
+ return Math.floor(Date.now() / 1000).toString();
61
+ }
62
+ /**
63
+ * Hash a secret for storage using SHA-256
64
+ */
65
+ function hashSecret(secret) {
66
+ return (0, crypto_1.createHash)('sha256').update(secret).digest('hex');
67
+ }
68
+ /**
69
+ * Sign a request and return the headers needed for authentication
70
+ */
71
+ function signRequest(request, keyId, secret) {
72
+ const timestamp = getTimestamp();
73
+ const payload = buildSignaturePayload(request, timestamp);
74
+ const signature = computeSignature(payload, secret);
75
+ return {
76
+ 'x-api-key': keyId,
77
+ 'x-timestamp': timestamp,
78
+ 'x-signature': signature,
79
+ };
80
+ }
81
+ /**
82
+ * Sign a webhook payload and return the headers
83
+ */
84
+ function signWebhookPayload(payload, secret, eventType) {
85
+ const timestamp = getTimestamp();
86
+ const signaturePayload = `${timestamp}.${payload}`;
87
+ const signature = computeSignature(signaturePayload, secret);
88
+ return {
89
+ 'x-webhook-signature': signature,
90
+ 'x-webhook-timestamp': timestamp,
91
+ 'x-webhook-event': eventType,
92
+ };
93
+ }
94
+ /**
95
+ * Verify a webhook signature
96
+ */
97
+ function verifyWebhookSignature(payload, timestamp, signature, secret, maxAgeSeconds = exports.MAX_TIMESTAMP_AGE_SECONDS) {
98
+ // Check timestamp is valid
99
+ const timestampNum = Number.parseInt(timestamp, 10);
100
+ if (Number.isNaN(timestampNum) ||
101
+ !isTimestampValid(timestampNum, maxAgeSeconds)) {
102
+ return false;
103
+ }
104
+ // Compute expected signature
105
+ const signaturePayload = `${timestamp}.${payload}`;
106
+ const expectedSignature = computeSignature(signaturePayload, secret);
107
+ // Timing-safe comparison
108
+ return verifySignature(signature, expectedSignature);
109
+ }
@@ -0,0 +1,2 @@
1
+ export { buildSignaturePayload, computeSignature, getTimestamp, isTimestampValid, MAX_TIMESTAMP_AGE_SECONDS, type SignatureRequest, signRequest, signWebhookPayload, verifySignature, verifyWebhookSignature, type WebhookSignatureHeaders, } from './hmac.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyWebhookSignature = exports.verifySignature = exports.signWebhookPayload = exports.signRequest = exports.MAX_TIMESTAMP_AGE_SECONDS = exports.isTimestampValid = exports.getTimestamp = exports.computeSignature = exports.buildSignaturePayload = void 0;
4
+ var hmac_js_1 = require("./hmac.js");
5
+ Object.defineProperty(exports, "buildSignaturePayload", { enumerable: true, get: function () { return hmac_js_1.buildSignaturePayload; } });
6
+ Object.defineProperty(exports, "computeSignature", { enumerable: true, get: function () { return hmac_js_1.computeSignature; } });
7
+ Object.defineProperty(exports, "getTimestamp", { enumerable: true, get: function () { return hmac_js_1.getTimestamp; } });
8
+ Object.defineProperty(exports, "isTimestampValid", { enumerable: true, get: function () { return hmac_js_1.isTimestampValid; } });
9
+ Object.defineProperty(exports, "MAX_TIMESTAMP_AGE_SECONDS", { enumerable: true, get: function () { return hmac_js_1.MAX_TIMESTAMP_AGE_SECONDS; } });
10
+ Object.defineProperty(exports, "signRequest", { enumerable: true, get: function () { return hmac_js_1.signRequest; } });
11
+ Object.defineProperty(exports, "signWebhookPayload", { enumerable: true, get: function () { return hmac_js_1.signWebhookPayload; } });
12
+ Object.defineProperty(exports, "verifySignature", { enumerable: true, get: function () { return hmac_js_1.verifySignature; } });
13
+ Object.defineProperty(exports, "verifyWebhookSignature", { enumerable: true, get: function () { return hmac_js_1.verifyWebhookSignature; } });
@@ -0,0 +1,2 @@
1
+ export { hashSecret } from './hmac.js';
2
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashSecret = void 0;
4
+ var hmac_js_1 = require("./hmac.js");
5
+ Object.defineProperty(exports, "hashSecret", { enumerable: true, get: function () { return hmac_js_1.hashSecret; } });
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@korala/auth",
3
+ "version": "1.0.0",
4
+ "description": "HMAC authentication utilities for the Korala document signing API",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/korala-ai/korala.git",
9
+ "directory": "packages/auth"
10
+ },
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./internal": {
20
+ "types": "./dist/internal.d.ts",
21
+ "import": "./dist/internal.js",
22
+ "default": "./dist/internal.js"
23
+ }
24
+ },
25
+ "typesVersions": {
26
+ "*": {
27
+ "internal": [
28
+ "./dist/internal.d.ts"
29
+ ]
30
+ }
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "engines": {
39
+ "node": ">=20.0"
40
+ },
41
+ "keywords": [
42
+ "korala",
43
+ "hmac",
44
+ "authentication",
45
+ "api-signing",
46
+ "webhook-verification"
47
+ ],
48
+ "devDependencies": {
49
+ "typescript": "^5.9.3",
50
+ "vitest": "^4.0.17"
51
+ },
52
+ "scripts": {
53
+ "build": "tsc",
54
+ "dev": "tsc --watch",
55
+ "typecheck": "tsc --noEmit",
56
+ "check": "biome check --write .",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest"
59
+ }
60
+ }