@devorash/core 0.1.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/LICENSE +21 -0
- package/README.md +187 -0
- package/dist/constants/api-url.gen.d.ts +4 -0
- package/dist/constants/api-url.gen.d.ts.map +1 -0
- package/dist/constants/api-url.gen.example.d.ts +7 -0
- package/dist/constants/api-url.gen.example.d.ts.map +1 -0
- package/dist/constants/api-url.gen.example.js +7 -0
- package/dist/constants/api-url.gen.example.js.map +1 -0
- package/dist/constants/api-url.gen.js +4 -0
- package/dist/constants/api-url.gen.js.map +1 -0
- package/dist/constants/index.d.ts +203 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +236 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/sessionLifecycle.d.ts +22 -0
- package/dist/constants/sessionLifecycle.d.ts.map +1 -0
- package/dist/constants/sessionLifecycle.js +21 -0
- package/dist/constants/sessionLifecycle.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/security/index.d.ts +118 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +345 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/request-body.d.ts +16 -0
- package/dist/security/request-body.d.ts.map +1 -0
- package/dist/security/request-body.js +84 -0
- package/dist/security/request-body.js.map +1 -0
- package/dist/security/signing.d.ts +127 -0
- package/dist/security/signing.d.ts.map +1 -0
- package/dist/security/signing.js +297 -0
- package/dist/security/signing.js.map +1 -0
- package/dist/types/index.d.ts +487 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +211 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +600 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Devora request signing, version 3.
|
|
3
|
+
*
|
|
4
|
+
* The signature covers the exact bytes on the wire: raw path, raw query and a
|
|
5
|
+
* SHA-256 of the raw body, plus the direction the request travels in. Every
|
|
6
|
+
* header has one accepted spelling. The canonical string joins fields with
|
|
7
|
+
* `\n`; each field's grammar excludes `\n`, so the encoding is injective.
|
|
8
|
+
*
|
|
9
|
+
* This module is pure (no hashing): runtimes supply SHA-256 and HMAC.
|
|
10
|
+
* Conformance vectors: packages/sdks/test/signing-v3-vectors.json.
|
|
11
|
+
*
|
|
12
|
+
* @module @devorash/core/security/signing
|
|
13
|
+
*/
|
|
14
|
+
import { SECURITY_HEADERS } from "../constants/index.js";
|
|
15
|
+
export const SIGNING = {
|
|
16
|
+
VERSION: "3",
|
|
17
|
+
ALGORITHM: "DEVORA-HMAC-SHA256",
|
|
18
|
+
/** Devora backend -> customer backend (the SDK verifies). */
|
|
19
|
+
DEVORA_TO_CUSTOMER: "devora-to-customer",
|
|
20
|
+
/** Customer backend SDK -> Devora backend (Devora verifies). */
|
|
21
|
+
CUSTOMER_TO_DEVORA: "customer-to-devora",
|
|
22
|
+
/** SHA-256 of an empty body. */
|
|
23
|
+
EMPTY_BODY_SHA256: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
24
|
+
};
|
|
25
|
+
/** Exact header grammars. (?![\s\S]) requires the actual end of input;
|
|
26
|
+
* JavaScript's $ also accepts a position before a final newline. */
|
|
27
|
+
export const SIGNED_HEADER_PATTERNS = {
|
|
28
|
+
signatureVersion: /^3(?![\s\S])/,
|
|
29
|
+
keyId: /^pk_server_live_[A-Za-z0-9_-]{32}(?![\s\S])/,
|
|
30
|
+
orgId: /^[A-Za-z0-9_-]{1,128}(?![\s\S])/,
|
|
31
|
+
sentAt: /^[1-9][0-9]{9}(?![\s\S])/,
|
|
32
|
+
requestId: /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}(?![\s\S])/,
|
|
33
|
+
signature: /^[0-9a-f]{64}(?![\s\S])/,
|
|
34
|
+
method: /^[A-Z]{3,7}(?![\s\S])/,
|
|
35
|
+
bodySha256: /^[0-9a-f]{64}(?![\s\S])/,
|
|
36
|
+
/** The full secret string; its ASCII bytes are the HMAC key. */
|
|
37
|
+
secretKey: /^sk_server_live_[A-Za-z0-9_-]{64}(?![\s\S])/,
|
|
38
|
+
};
|
|
39
|
+
const UNRESERVED = /[A-Za-z0-9\-_.~]/;
|
|
40
|
+
const encoder = new TextEncoder();
|
|
41
|
+
/** UTF-8 percent-encode every byte outside `A-Z a-z 0-9 - _ . ~`, with uppercase hex. */
|
|
42
|
+
export function strictEncode(value) {
|
|
43
|
+
// TextEncoder silently replaces lone surrogates; Python rejects them. Never
|
|
44
|
+
// sign a different identifier from the string the caller supplied.
|
|
45
|
+
encodeURIComponent(value);
|
|
46
|
+
let out = "";
|
|
47
|
+
for (const byte of encoder.encode(value)) {
|
|
48
|
+
const char = String.fromCharCode(byte);
|
|
49
|
+
out += UNRESERVED.test(char) ? char : `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Encode one path parameter. `""`, `.` and `..` are refused: URL parsers
|
|
55
|
+
* remove dot segments (even `%2E%2E`), so they cannot be sent as signed.
|
|
56
|
+
*/
|
|
57
|
+
export function encodePathParam(value) {
|
|
58
|
+
if (value === "" || value === "." || value === "..")
|
|
59
|
+
throw new Error("Devora signing: unroutable path parameter");
|
|
60
|
+
return strictEncode(value);
|
|
61
|
+
}
|
|
62
|
+
/** Strict-encoded `key=value` pairs, in the given order (the order is signed). */
|
|
63
|
+
export function buildStrictQuery(pairs) {
|
|
64
|
+
return pairs.map(([key, value]) => `${strictEncode(key)}=${strictEncode(value)}`).join("&");
|
|
65
|
+
}
|
|
66
|
+
/** Printable ASCII where every `%` starts an uppercase two-digit escape. */
|
|
67
|
+
function isStrictAscii(value) {
|
|
68
|
+
return !/[^\x21-\x7E]/.test(value) && !/%(?![0-9A-F]{2})/.test(value);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A raw request path as signed: absolute, printable ASCII, uppercase escapes,
|
|
72
|
+
* and no empty or dot segments.
|
|
73
|
+
*/
|
|
74
|
+
export function isValidSignedPath(path) {
|
|
75
|
+
if (!path.startsWith("/") || !isStrictAscii(path) || path.length > 8192 || /[?#\\]/.test(path))
|
|
76
|
+
return false;
|
|
77
|
+
try {
|
|
78
|
+
decodeURIComponent(path);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (path === "/")
|
|
84
|
+
return true;
|
|
85
|
+
return path
|
|
86
|
+
.slice(1)
|
|
87
|
+
.split("/")
|
|
88
|
+
.every((segment) => {
|
|
89
|
+
const dots = segment.replace(/%2E/g, ".");
|
|
90
|
+
return dots !== "" && dots !== "." && dots !== "..";
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** A raw query as signed: printable ASCII, no fragment, uppercase escapes. */
|
|
94
|
+
export function isValidSignedQuery(query) {
|
|
95
|
+
if (query.includes("#") || !isStrictAscii(query) || query.length > 8192)
|
|
96
|
+
return false;
|
|
97
|
+
try {
|
|
98
|
+
decodeURIComponent(query);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Build the canonical string. Throws if any field is outside its grammar. */
|
|
106
|
+
export function buildCanonicalString(fields) {
|
|
107
|
+
const checks = [
|
|
108
|
+
[
|
|
109
|
+
fields.direction === SIGNING.DEVORA_TO_CUSTOMER ||
|
|
110
|
+
fields.direction === SIGNING.CUSTOMER_TO_DEVORA,
|
|
111
|
+
"direction",
|
|
112
|
+
],
|
|
113
|
+
[SIGNED_HEADER_PATTERNS.keyId.test(fields.keyId), "key id"],
|
|
114
|
+
[SIGNED_HEADER_PATTERNS.orgId.test(fields.orgId), "org id"],
|
|
115
|
+
[SIGNED_HEADER_PATTERNS.sentAt.test(fields.sentAt), "sent-at"],
|
|
116
|
+
[SIGNED_HEADER_PATTERNS.requestId.test(fields.requestId), "request id"],
|
|
117
|
+
[SIGNED_HEADER_PATTERNS.method.test(fields.method), "method"],
|
|
118
|
+
[isValidSignedPath(fields.path), "path"],
|
|
119
|
+
[isValidSignedQuery(fields.query), "query"],
|
|
120
|
+
[SIGNED_HEADER_PATTERNS.bodySha256.test(fields.bodySha256), "body digest"],
|
|
121
|
+
];
|
|
122
|
+
const invalid = checks.find(([ok]) => !ok);
|
|
123
|
+
if (invalid)
|
|
124
|
+
throw new Error(`Devora signing: invalid ${invalid[1]}`);
|
|
125
|
+
return [
|
|
126
|
+
SIGNING.ALGORITHM,
|
|
127
|
+
SIGNING.VERSION,
|
|
128
|
+
fields.direction,
|
|
129
|
+
fields.keyId,
|
|
130
|
+
fields.orgId,
|
|
131
|
+
fields.sentAt,
|
|
132
|
+
fields.requestId,
|
|
133
|
+
fields.method,
|
|
134
|
+
fields.path,
|
|
135
|
+
fields.query,
|
|
136
|
+
fields.bodySha256,
|
|
137
|
+
].join("\n");
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The single value of a header, or `null` when it is present more than once
|
|
141
|
+
* (an array, or a comma-joined value that the grammar then rejects).
|
|
142
|
+
*/
|
|
143
|
+
export function getSingleHeader(headers, name) {
|
|
144
|
+
const values = [];
|
|
145
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
146
|
+
if (key.toLowerCase() !== name || value === undefined)
|
|
147
|
+
continue;
|
|
148
|
+
values.push(...(Array.isArray(value) ? value : [value]));
|
|
149
|
+
}
|
|
150
|
+
if (values.length > 1)
|
|
151
|
+
return null;
|
|
152
|
+
return values[0];
|
|
153
|
+
}
|
|
154
|
+
/** Parse and validate the signature headers. Never first-wins, never trims. */
|
|
155
|
+
export function parseSignatureHeaders(headers) {
|
|
156
|
+
const read = (name) => getSingleHeader(headers, name);
|
|
157
|
+
const version = read(SECURITY_HEADERS.SIGNATURE_VERSION);
|
|
158
|
+
const values = {
|
|
159
|
+
keyId: read(SECURITY_HEADERS.KEY_ID),
|
|
160
|
+
orgId: read(SECURITY_HEADERS.ORG_ID),
|
|
161
|
+
sentAt: read(SECURITY_HEADERS.SENT_AT),
|
|
162
|
+
requestId: read(SECURITY_HEADERS.REQUEST_ID),
|
|
163
|
+
signature: read(SECURITY_HEADERS.SIGNATURE),
|
|
164
|
+
};
|
|
165
|
+
if (typeof version === "string" && version !== SIGNING.VERSION && /^\d+(?![\s\S])/.test(version))
|
|
166
|
+
return {
|
|
167
|
+
valid: false,
|
|
168
|
+
errorCode: "UNSUPPORTED_SIGNATURE_VERSION",
|
|
169
|
+
error: "Unsupported signature version",
|
|
170
|
+
};
|
|
171
|
+
const ok = typeof version === "string" &&
|
|
172
|
+
SIGNED_HEADER_PATTERNS.signatureVersion.test(version) &&
|
|
173
|
+
Object.keys(values).every((key) => {
|
|
174
|
+
const value = values[key];
|
|
175
|
+
return typeof value === "string" && SIGNED_HEADER_PATTERNS[key].test(value);
|
|
176
|
+
});
|
|
177
|
+
if (!ok)
|
|
178
|
+
return {
|
|
179
|
+
valid: false,
|
|
180
|
+
errorCode: "INVALID_SIGNATURE_HEADERS",
|
|
181
|
+
error: "Missing, duplicate or malformed signature headers",
|
|
182
|
+
};
|
|
183
|
+
return { valid: true, headers: values };
|
|
184
|
+
}
|
|
185
|
+
/** Accept only an absent or `identity` Content-Encoding (the body digest is over wire bytes). */
|
|
186
|
+
export function hasIdentityContentEncoding(headers) {
|
|
187
|
+
const value = getSingleHeader(headers, "content-encoding");
|
|
188
|
+
return value === undefined || value === "identity";
|
|
189
|
+
}
|
|
190
|
+
/** Replay-store namespace: version, direction and key. */
|
|
191
|
+
export function replayNamespace(direction, keyId) {
|
|
192
|
+
return `v${SIGNING.VERSION}:${direction}:${keyId}`;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Nonce lifetime covering the whole acceptance window: the floor second of the
|
|
196
|
+
* timestamp check plus one second of clock jitter.
|
|
197
|
+
*/
|
|
198
|
+
export function replayExpiresAtMs(sentAt, nowSeconds, toleranceSeconds) {
|
|
199
|
+
return (Math.max(nowSeconds, sentAt) + toleranceSeconds + 2) * 1000;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Parse a verified raw query into a null-prototype map. Repeated keys become
|
|
203
|
+
* arrays in wire order; `__proto__` and `constructor` are ordinary keys.
|
|
204
|
+
*/
|
|
205
|
+
export function parseVerifiedQuery(query) {
|
|
206
|
+
const result = Object.create(null);
|
|
207
|
+
for (const [key, value] of new URLSearchParams(query)) {
|
|
208
|
+
const existing = result[key];
|
|
209
|
+
if (existing === undefined)
|
|
210
|
+
result[key] = value;
|
|
211
|
+
else if (Array.isArray(existing))
|
|
212
|
+
existing.push(value);
|
|
213
|
+
else
|
|
214
|
+
result[key] = [existing, value];
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Decode a verified body: empty means `undefined`; otherwise it must be JSON
|
|
220
|
+
* (declared `application/json`) and strictly valid UTF-8.
|
|
221
|
+
*/
|
|
222
|
+
export function parseVerifiedJsonBody(bytes, contentType) {
|
|
223
|
+
if (bytes.byteLength === 0)
|
|
224
|
+
return { ok: true, value: undefined };
|
|
225
|
+
if (!contentType || !/^application\/json(\s*;.*)?(?![\s\S])/i.test(contentType.trim()))
|
|
226
|
+
return { ok: false, error: "Signed request bodies must be application/json" };
|
|
227
|
+
try {
|
|
228
|
+
const text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
|
|
229
|
+
const value = JSON.parse(text, (_key, item) => {
|
|
230
|
+
if (typeof item === "number" && !Number.isFinite(item))
|
|
231
|
+
throw new Error("Non-finite number");
|
|
232
|
+
if (item !== null && typeof item === "object" && !Array.isArray(item))
|
|
233
|
+
Object.setPrototypeOf(item, null);
|
|
234
|
+
return item;
|
|
235
|
+
});
|
|
236
|
+
if (hasDuplicateJsonKeys(text))
|
|
237
|
+
return { ok: false, error: "Duplicate JSON key" };
|
|
238
|
+
return { ok: true, value };
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return { ok: false, error: "Invalid JSON body" };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** Scan valid JSON, comparing decoded keys separately in each object. */
|
|
245
|
+
function hasDuplicateJsonKeys(text) {
|
|
246
|
+
const stack = [];
|
|
247
|
+
let expectKey = false;
|
|
248
|
+
for (let index = 0; index < text.length; index++) {
|
|
249
|
+
const char = text[index];
|
|
250
|
+
if (char === "{") {
|
|
251
|
+
stack.push(new Set());
|
|
252
|
+
expectKey = true;
|
|
253
|
+
}
|
|
254
|
+
else if (char === "[") {
|
|
255
|
+
stack.push(null);
|
|
256
|
+
expectKey = false;
|
|
257
|
+
}
|
|
258
|
+
else if (char === "}" || char === "]") {
|
|
259
|
+
stack.pop();
|
|
260
|
+
expectKey = false;
|
|
261
|
+
}
|
|
262
|
+
else if (char === ",")
|
|
263
|
+
expectKey = stack[stack.length - 1] != null;
|
|
264
|
+
else if (char === ":")
|
|
265
|
+
expectKey = false;
|
|
266
|
+
else if (char === '"') {
|
|
267
|
+
let end = index + 1;
|
|
268
|
+
while (text[end] !== '"')
|
|
269
|
+
end += text[end] === "\\" ? 2 : 1;
|
|
270
|
+
if (expectKey) {
|
|
271
|
+
const keys = stack[stack.length - 1];
|
|
272
|
+
const key = JSON.parse(text.slice(index, end + 1));
|
|
273
|
+
if (keys.has(key))
|
|
274
|
+
return true;
|
|
275
|
+
keys.add(key);
|
|
276
|
+
expectKey = false;
|
|
277
|
+
}
|
|
278
|
+
index = end;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Last `count` segments of a raw path, i.e. the path relative to a mount whose
|
|
285
|
+
* route template has `count` segments. `null` when the path is shorter.
|
|
286
|
+
*/
|
|
287
|
+
export function routeRelativePath(rawPath, routeTemplate) {
|
|
288
|
+
const count = routeTemplate.split("/").filter(Boolean).length;
|
|
289
|
+
if (count === 0)
|
|
290
|
+
return "/";
|
|
291
|
+
const segments = rawPath.split("/");
|
|
292
|
+
// segments[0] is "" for an absolute path; the tail must be `count` segments.
|
|
293
|
+
if (segments.length - 1 < count)
|
|
294
|
+
return null;
|
|
295
|
+
return `/${segments.slice(segments.length - count).join("/")}`;
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/security/signing.ts"],"names":[],"mappings":"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"}
|