@jini-ai/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 +201 -0
- package/dist/api-token-auth.d.ts +28 -0
- package/dist/api-token-auth.d.ts.map +1 -0
- package/dist/api-token-auth.js +30 -0
- package/dist/api-token-auth.js.map +1 -0
- package/dist/bindings.d.ts +18 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +41 -0
- package/dist/bindings.js.map +1 -0
- package/dist/compose.typecheck.d.ts +2 -0
- package/dist/compose.typecheck.d.ts.map +1 -0
- package/dist/compose.typecheck.js +29 -0
- package/dist/compose.typecheck.js.map +1 -0
- package/dist/daemon.d.ts +40 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +37 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +36 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +35 -0
- package/dist/internal.js.map +1 -0
- package/dist/origin-validation.d.ts +63 -0
- package/dist/origin-validation.d.ts.map +1 -0
- package/dist/origin-validation.js +198 -0
- package/dist/origin-validation.js.map +1 -0
- package/dist/pack.d.ts +26 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +4 -0
- package/dist/pack.js.map +1 -0
- package/dist/principal.d.ts +16 -0
- package/dist/principal.d.ts.map +1 -0
- package/dist/principal.js +2 -0
- package/dist/principal.js.map +1 -0
- package/dist/redact.d.ts +48 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +190 -0
- package/dist/redact.js.map +1 -0
- package/dist/token.d.ts +22 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +7 -0
- package/dist/token.js.map +1 -0
- package/dist/tool-registry.d.ts +114 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +43 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tool-tokens.d.ts +3 -0
- package/dist/tool-tokens.d.ts.map +1 -0
- package/dist/tool-tokens.js +10 -0
- package/dist/tool-tokens.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module origin-validation
|
|
3
|
+
*
|
|
4
|
+
* Same-origin / allow-listed-origin validation for a locally-bound HTTP
|
|
5
|
+
* daemon: is this browser request actually coming from a page the daemon
|
|
6
|
+
* itself served (or an operator-configured allow-listed origin), as
|
|
7
|
+
* opposed to an arbitrary third-party site making a cross-site request to
|
|
8
|
+
* the daemon's loopback/private-LAN port.
|
|
9
|
+
*
|
|
10
|
+
* Generalized from an upstream flat daemon module: the origin hardcoded its
|
|
11
|
+
* host product's env-var names, now fields on
|
|
12
|
+
* {@link OriginValidationEnvConfig} — see `source-map.md` for the exact
|
|
13
|
+
* mapping. One function, a bypass for a specific product's own
|
|
14
|
+
* browser-extension-driven ingest route, was deliberately **not** ported —
|
|
15
|
+
* it names a specific product route and product feature with no generic
|
|
16
|
+
* equivalent; see `source-map.md`.
|
|
17
|
+
*/
|
|
18
|
+
export interface ParsedHostHeader {
|
|
19
|
+
hostname: string;
|
|
20
|
+
host: string;
|
|
21
|
+
port: string;
|
|
22
|
+
}
|
|
23
|
+
export interface RequestWithOriginHeaders {
|
|
24
|
+
headers?: {
|
|
25
|
+
host?: unknown;
|
|
26
|
+
origin?: unknown;
|
|
27
|
+
'sec-fetch-site'?: unknown;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Names the env vars this port reads. */
|
|
31
|
+
export interface OriginValidationEnvConfig {
|
|
32
|
+
/** Env var carrying a comma-separated list of extra allow-listed origins. */
|
|
33
|
+
allowedOriginsEnvVar: string;
|
|
34
|
+
/** Env var carrying an additional browser-facing port to treat as local (e.g. a separate web dev server). */
|
|
35
|
+
webPortEnvVar: string;
|
|
36
|
+
/** Env var carrying the host the daemon itself is bound to (default `'127.0.0.1'`). */
|
|
37
|
+
bindHostEnvVar: string;
|
|
38
|
+
}
|
|
39
|
+
/** Parses and validates {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins. */
|
|
40
|
+
export declare function configuredAllowedOrigins(config: OriginValidationEnvConfig, env?: NodeJS.ProcessEnv): string[];
|
|
41
|
+
/** The `host` (hostname:port) component of each configured allowed origin. */
|
|
42
|
+
export declare function configuredAllowedHosts(origins: string[]): string[];
|
|
43
|
+
/** The set of browser-facing ports considered "local": the daemon's own port plus an optional configured web port. */
|
|
44
|
+
export declare function allowedBrowserPorts(config: OriginValidationEnvConfig, port: number | string | null | undefined, env?: NodeJS.ProcessEnv): number[];
|
|
45
|
+
/** Parses a raw `Host` header value into hostname/host/port, or `null` when unparseable. */
|
|
46
|
+
export declare function parseHostHeader(value: unknown): ParsedHostHeader | null;
|
|
47
|
+
/** Whether `hostname` is an RFC 1918 private IPv4 address (10/8, 172.16/12, 192.168/16) or link-local (169.254/16). */
|
|
48
|
+
export declare function isPrivateIpv4(hostname: unknown): boolean;
|
|
49
|
+
/** Whether `hostname` is a literal IPv4 address or bracketed IPv6 literal (as opposed to a DNS name). */
|
|
50
|
+
export declare function isIpLiteralHostname(hostname: unknown): boolean;
|
|
51
|
+
/** Whether `hostname` is loopback, unspecified, or a private-LAN address. */
|
|
52
|
+
export declare function isLoopbackOrPrivateLanHost(hostname: unknown): boolean;
|
|
53
|
+
/** Whether a request's `Host` header names a locally-served or explicitly allow-listed host. */
|
|
54
|
+
export declare function isAllowedBrowserHost(config: OriginValidationEnvConfig, hostHeader: unknown, ports: number[], bindHost: string, extraAllowedOrigins: string[]): boolean;
|
|
55
|
+
/** Whether an `Origin` header value names a locally-served or explicitly allow-listed origin. */
|
|
56
|
+
export declare function isAllowedBrowserOrigin(config: OriginValidationEnvConfig, origin: unknown, hostHeader: unknown, ports: number[], bindHost: string, extraAllowedOrigins: string[]): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The top-level same-origin gate: is `req` a request the daemon should treat
|
|
59
|
+
* as coming from one of its own locally-served (or explicitly allow-listed)
|
|
60
|
+
* pages.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isLocalSameOrigin(config: OriginValidationEnvConfig, req: RequestWithOriginHeaders, port: number | string | null | undefined, env?: NodeJS.ProcessEnv): boolean;
|
|
63
|
+
//# sourceMappingURL=origin-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-validation.d.ts","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,6GAA6G;IAC7G,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,2GAA2G;AAC3G,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,yBAAyB,EACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAcV;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAElE;AAED,sHAAsH;AACtH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAOV;AAUD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CASvE;AAED,uHAAuH;AACvH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQ9D;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAWrE;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,yBAAyB,EACjC,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CAaT;AAED,iGAAiG;AACjG,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CA4BT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,yBAAyB,EACjC,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAmCT"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module origin-validation
|
|
3
|
+
*
|
|
4
|
+
* Same-origin / allow-listed-origin validation for a locally-bound HTTP
|
|
5
|
+
* daemon: is this browser request actually coming from a page the daemon
|
|
6
|
+
* itself served (or an operator-configured allow-listed origin), as
|
|
7
|
+
* opposed to an arbitrary third-party site making a cross-site request to
|
|
8
|
+
* the daemon's loopback/private-LAN port.
|
|
9
|
+
*
|
|
10
|
+
* Generalized from an upstream flat daemon module: the origin hardcoded its
|
|
11
|
+
* host product's env-var names, now fields on
|
|
12
|
+
* {@link OriginValidationEnvConfig} — see `source-map.md` for the exact
|
|
13
|
+
* mapping. One function, a bypass for a specific product's own
|
|
14
|
+
* browser-extension-driven ingest route, was deliberately **not** ported —
|
|
15
|
+
* it names a specific product route and product feature with no generic
|
|
16
|
+
* equivalent; see `source-map.md`.
|
|
17
|
+
*/
|
|
18
|
+
/** Parses and validates {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins. */
|
|
19
|
+
export function configuredAllowedOrigins(config, env = process.env) {
|
|
20
|
+
const raw = env[config.allowedOriginsEnvVar] || '';
|
|
21
|
+
if (!raw.trim())
|
|
22
|
+
return [];
|
|
23
|
+
return raw
|
|
24
|
+
.split(',')
|
|
25
|
+
.map((origin) => origin.trim())
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.map((origin) => {
|
|
28
|
+
const parsed = new URL(origin);
|
|
29
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
30
|
+
throw new Error(`${config.allowedOriginsEnvVar} only supports http:// and https:// origins`);
|
|
31
|
+
}
|
|
32
|
+
return parsed.origin;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** The `host` (hostname:port) component of each configured allowed origin. */
|
|
36
|
+
export function configuredAllowedHosts(origins) {
|
|
37
|
+
return origins.map((origin) => new URL(origin).host);
|
|
38
|
+
}
|
|
39
|
+
/** The set of browser-facing ports considered "local": the daemon's own port plus an optional configured web port. */
|
|
40
|
+
export function allowedBrowserPorts(config, port, env = process.env) {
|
|
41
|
+
const ports = [];
|
|
42
|
+
const primary = Number(port);
|
|
43
|
+
if (primary)
|
|
44
|
+
ports.push(primary);
|
|
45
|
+
const webPort = Number(env[config.webPortEnvVar]);
|
|
46
|
+
if (webPort && webPort !== primary)
|
|
47
|
+
ports.push(webPort);
|
|
48
|
+
return ports;
|
|
49
|
+
}
|
|
50
|
+
function headerValue(value) {
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
const first = value[0];
|
|
53
|
+
return first == null ? undefined : String(first);
|
|
54
|
+
}
|
|
55
|
+
return value == null ? undefined : String(value);
|
|
56
|
+
}
|
|
57
|
+
/** Parses a raw `Host` header value into hostname/host/port, or `null` when unparseable. */
|
|
58
|
+
export function parseHostHeader(value) {
|
|
59
|
+
const raw = String(headerValue(value) || '').trim();
|
|
60
|
+
if (!raw)
|
|
61
|
+
return null;
|
|
62
|
+
try {
|
|
63
|
+
const parsed = new URL(`http://${raw}`);
|
|
64
|
+
return { hostname: parsed.hostname, host: parsed.host, port: parsed.port || '80' };
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Whether `hostname` is an RFC 1918 private IPv4 address (10/8, 172.16/12, 192.168/16) or link-local (169.254/16). */
|
|
71
|
+
export function isPrivateIpv4(hostname) {
|
|
72
|
+
const parts = String(hostname || '').split('.');
|
|
73
|
+
if (parts.length !== 4)
|
|
74
|
+
return false;
|
|
75
|
+
if (!parts.every((part) => /^\d+$/.test(part)))
|
|
76
|
+
return false;
|
|
77
|
+
const octets = parts.map((part) => Number(part));
|
|
78
|
+
if (!octets.every((n) => Number.isInteger(n) && n >= 0 && n <= 255))
|
|
79
|
+
return false;
|
|
80
|
+
const [a, b] = octets;
|
|
81
|
+
return a === 10 || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 169 && b === 254);
|
|
82
|
+
}
|
|
83
|
+
/** Whether `hostname` is a literal IPv4 address or bracketed IPv6 literal (as opposed to a DNS name). */
|
|
84
|
+
export function isIpLiteralHostname(hostname) {
|
|
85
|
+
const host = String(hostname || '').trim();
|
|
86
|
+
if (!host)
|
|
87
|
+
return false;
|
|
88
|
+
if (host.startsWith('[') && host.endsWith(']'))
|
|
89
|
+
return true;
|
|
90
|
+
const parts = host.split('.');
|
|
91
|
+
if (parts.length !== 4)
|
|
92
|
+
return false;
|
|
93
|
+
if (!parts.every((part) => /^\d+$/.test(part)))
|
|
94
|
+
return false;
|
|
95
|
+
return parts.map(Number).every((n) => Number.isInteger(n) && n >= 0 && n <= 255);
|
|
96
|
+
}
|
|
97
|
+
/** Whether `hostname` is loopback, unspecified, or a private-LAN address. */
|
|
98
|
+
export function isLoopbackOrPrivateLanHost(hostname) {
|
|
99
|
+
const host = String(hostname || '').toLowerCase();
|
|
100
|
+
return (host === 'localhost' ||
|
|
101
|
+
host === '127.0.0.1' ||
|
|
102
|
+
host === '::1' ||
|
|
103
|
+
host === '[::1]' ||
|
|
104
|
+
host === '0.0.0.0' ||
|
|
105
|
+
host === '::' ||
|
|
106
|
+
isPrivateIpv4(host));
|
|
107
|
+
}
|
|
108
|
+
/** Whether a request's `Host` header names a locally-served or explicitly allow-listed host. */
|
|
109
|
+
export function isAllowedBrowserHost(config, hostHeader, ports, bindHost, extraAllowedOrigins) {
|
|
110
|
+
const requestHost = parseHostHeader(hostHeader);
|
|
111
|
+
if (!requestHost)
|
|
112
|
+
return false;
|
|
113
|
+
const loopbackHosts = ['127.0.0.1', 'localhost', '[::1]'];
|
|
114
|
+
const explicitHosts = new Set([
|
|
115
|
+
...ports.flatMap((p) => [...loopbackHosts.map((h) => `${h}:${p}`), `${bindHost}:${p}`]),
|
|
116
|
+
...configuredAllowedHosts(extraAllowedOrigins),
|
|
117
|
+
]);
|
|
118
|
+
if (explicitHosts.has(requestHost.host))
|
|
119
|
+
return true;
|
|
120
|
+
if (!ports.map(String).includes(requestHost.port))
|
|
121
|
+
return false;
|
|
122
|
+
return isLoopbackOrPrivateLanHost(requestHost.hostname);
|
|
123
|
+
}
|
|
124
|
+
/** Whether an `Origin` header value names a locally-served or explicitly allow-listed origin. */
|
|
125
|
+
export function isAllowedBrowserOrigin(config, origin, hostHeader, ports, bindHost, extraAllowedOrigins) {
|
|
126
|
+
if (extraAllowedOrigins.includes(String(origin)))
|
|
127
|
+
return true;
|
|
128
|
+
let parsedOrigin;
|
|
129
|
+
try {
|
|
130
|
+
parsedOrigin = new URL(String(origin));
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (parsedOrigin.protocol !== 'http:' && parsedOrigin.protocol !== 'https:')
|
|
136
|
+
return false;
|
|
137
|
+
const requestHost = parseHostHeader(hostHeader);
|
|
138
|
+
if (!requestHost)
|
|
139
|
+
return false;
|
|
140
|
+
const schemes = ['http', 'https'];
|
|
141
|
+
const loopbackHosts = ['127.0.0.1', 'localhost', '[::1]'];
|
|
142
|
+
const explicitOrigins = new Set(ports.flatMap((p) => [
|
|
143
|
+
...schemes.flatMap((s) => loopbackHosts.map((h) => `${s}://${h}:${p}`)),
|
|
144
|
+
...schemes.map((s) => `${s}://${bindHost}:${p}`),
|
|
145
|
+
]));
|
|
146
|
+
if (explicitOrigins.has(String(origin)))
|
|
147
|
+
return true;
|
|
148
|
+
const originPort = parsedOrigin.port || (parsedOrigin.protocol === 'https:' ? '443' : '80');
|
|
149
|
+
if (!ports.map(String).includes(originPort))
|
|
150
|
+
return false;
|
|
151
|
+
if (parsedOrigin.hostname !== requestHost.hostname)
|
|
152
|
+
return false;
|
|
153
|
+
return isLoopbackOrPrivateLanHost(parsedOrigin.hostname);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The top-level same-origin gate: is `req` a request the daemon should treat
|
|
157
|
+
* as coming from one of its own locally-served (or explicitly allow-listed)
|
|
158
|
+
* pages.
|
|
159
|
+
*/
|
|
160
|
+
export function isLocalSameOrigin(config, req, port, env = process.env) {
|
|
161
|
+
const host = String(headerValue(req.headers?.host) || '');
|
|
162
|
+
const origin = headerValue(req.headers?.origin);
|
|
163
|
+
const ports = allowedBrowserPorts(config, port, env);
|
|
164
|
+
const bindHost = env[config.bindHostEnvVar] || '127.0.0.1';
|
|
165
|
+
const extraAllowedOrigins = configuredAllowedOrigins(config, env);
|
|
166
|
+
const ipOnlyExtraOrigins = extraAllowedOrigins.filter((o) => isIpLiteralHostname(new URL(o).hostname));
|
|
167
|
+
const localHostAllowed = isAllowedBrowserHost(config, host, ports, bindHost, ipOnlyExtraOrigins);
|
|
168
|
+
if (origin == null || origin === '') {
|
|
169
|
+
if (localHostAllowed)
|
|
170
|
+
return true;
|
|
171
|
+
// Browsers (Firefox, Chrome) omit Origin on same-origin GET subresource
|
|
172
|
+
// requests per the Fetch spec, which makes hostname entries in the
|
|
173
|
+
// allow-list unreachable for legitimate same-origin GETs through a
|
|
174
|
+
// reverse proxy. Sec-Fetch-Site is set by the user agent and cannot be
|
|
175
|
+
// modified by JavaScript, so a value of "same-origin" attests that the
|
|
176
|
+
// request originated from the same origin as the target — a cross-site
|
|
177
|
+
// `<img>`/`<script>` exploit would carry "cross-site" instead. Only
|
|
178
|
+
// consult the broader allow-list once that signal is present.
|
|
179
|
+
const fetchSite = headerValue(req.headers?.['sec-fetch-site']);
|
|
180
|
+
if (fetchSite === 'same-origin') {
|
|
181
|
+
return isAllowedBrowserHost(config, host, ports, bindHost, extraAllowedOrigins);
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
// Reverse-proxy deployments terminate the browser connection at the proxy
|
|
186
|
+
// and open a fresh upstream connection to the daemon. The Host header the
|
|
187
|
+
// daemon sees is the proxy upstream's address, not the browser-visible
|
|
188
|
+
// origin, so the host check below fails even when the user explicitly
|
|
189
|
+
// listed their proxy origin in the allow-list. Trust the Origin header in
|
|
190
|
+
// that case: a client-supplied origin that exactly matches an explicitly
|
|
191
|
+
// allow-listed entry is the documented escape hatch for these deployments.
|
|
192
|
+
if (extraAllowedOrigins.includes(origin))
|
|
193
|
+
return true;
|
|
194
|
+
if (!isAllowedBrowserHost(config, host, ports, bindHost, extraAllowedOrigins))
|
|
195
|
+
return false;
|
|
196
|
+
return isAllowedBrowserOrigin(config, origin, host, ports, bindHost, extraAllowedOrigins);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=origin-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-validation.js","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/pack.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AnyToken, ManyToken, Token } from './token.js';
|
|
2
|
+
/**
|
|
3
|
+
* The only resolver a pack's `services` factory ever sees. Scoped to that
|
|
4
|
+
* pack's own declared `deps` — resolving a token the pack didn't declare is a
|
|
5
|
+
* bug (kernel escape hatch), not a convenience, so it throws rather than
|
|
6
|
+
* silently falling through to a global container.
|
|
7
|
+
*/
|
|
8
|
+
export interface PackContainer {
|
|
9
|
+
get<T>(t: Token<T, string>): T;
|
|
10
|
+
getMany<T>(t: ManyToken<T, string>): T[];
|
|
11
|
+
}
|
|
12
|
+
export interface Pack<Deps extends readonly AnyToken<unknown, string>[] = readonly AnyToken<unknown, string>[], Services = unknown, Name extends string = string> {
|
|
13
|
+
readonly name: Name;
|
|
14
|
+
readonly deps: Deps;
|
|
15
|
+
readonly services: (c: PackContainer) => Services;
|
|
16
|
+
readonly http?: (app: unknown, services: Services) => void;
|
|
17
|
+
readonly cli?: (reg: unknown, services: Services) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function definePack<const Name extends string, const Deps extends readonly AnyToken<unknown, string>[], Services>(def: {
|
|
20
|
+
name: Name;
|
|
21
|
+
deps: Deps;
|
|
22
|
+
services: (c: PackContainer) => Services;
|
|
23
|
+
http?: (app: unknown, services: Services) => void;
|
|
24
|
+
cli?: (reg: unknown, services: Services) => void;
|
|
25
|
+
}): Pack<Deps, Services, Name>;
|
|
26
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,IAAI,CACnB,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACxF,QAAQ,GAAG,OAAO,EAClB,IAAI,SAAS,MAAM,GAAG,MAAM;IAE5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,UAAU,CACxB,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACvD,QAAQ,EACR,GAAG,EAAE;IACL,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAClD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAClD,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAE7B"}
|
package/dist/pack.js
ADDED
package/dist/pack.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,UAAU,CAIxB,GAMD;IACC,OAAO,GAA4C,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Principal` — the authenticated/authorized identity a kernel operation
|
|
3
|
+
* (a tool call, a run) is performed on behalf of. Deliberately minimal per
|
|
4
|
+
* extraction-plan.md §3 ("Principal/Authorizer, pure interfaces"): the
|
|
5
|
+
* kernel only needs an opaque, stable identity plus an optional coarse
|
|
6
|
+
* role/capability hint a `ToolPolicy` can branch on — anything richer
|
|
7
|
+
* (session, auth provider, user profile) is a consumer concern layered on
|
|
8
|
+
* top, never a kernel noun.
|
|
9
|
+
*/
|
|
10
|
+
export interface Principal {
|
|
11
|
+
/** Opaque, stable identity — never assumed to be a product user id. */
|
|
12
|
+
readonly id: string;
|
|
13
|
+
/** Optional coarse role/capability hints a policy may consult. */
|
|
14
|
+
readonly roles?: readonly string[];
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../src/principal.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.js","sourceRoot":"","sources":["../src/principal.ts"],"names":[],"mappings":""}
|
package/dist/redact.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module redact
|
|
3
|
+
*
|
|
4
|
+
* Lexical secret / PII scrubber for telemetry payloads. Verbatim port of
|
|
5
|
+
* OD's `apps/daemon/src/redact.ts` — no product-identity strings or
|
|
6
|
+
* hardcoded env vars in the original, so no genericization was needed.
|
|
7
|
+
*
|
|
8
|
+
* Runs before any prompt or assistant text is sent to an external
|
|
9
|
+
* observability sink. The patterns here are intentionally conservative:
|
|
10
|
+
* each one matches a well-defined token shape with extremely low
|
|
11
|
+
* false-positive rate (API keys have a fixed prefix, JWTs have the
|
|
12
|
+
* "header.payload.signature" triple, credit-card matches go through a Luhn
|
|
13
|
+
* check). What this file does NOT do — and any caller-facing copy must
|
|
14
|
+
* reflect that — is detect names, addresses, business secrets, or anything
|
|
15
|
+
* that requires understanding the meaning of the surrounding text. That's
|
|
16
|
+
* an ML / LLM problem this module doesn't take on.
|
|
17
|
+
*
|
|
18
|
+
* Output format: every match is replaced by `[REDACTED:<kind>]` so a
|
|
19
|
+
* reviewer reading a trace can see exactly which category fired without
|
|
20
|
+
* recovering the original value.
|
|
21
|
+
*
|
|
22
|
+
* References:
|
|
23
|
+
* - Langfuse client-side masking guidance:
|
|
24
|
+
* https://langfuse.com/docs/observability/features/masking
|
|
25
|
+
* - GitHub token format:
|
|
26
|
+
* https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github
|
|
27
|
+
* - AWS access key shape: 'AKIA' + 16 uppercase alphanumerics.
|
|
28
|
+
* - Luhn algorithm (credit cards): https://en.wikipedia.org/wiki/Luhn_algorithm
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Returns `input` with every recognised secret / PII pattern replaced by a
|
|
32
|
+
* `[REDACTED:<kind>]` marker. Idempotent — re-running on already redacted
|
|
33
|
+
* text only matches new tokens.
|
|
34
|
+
*
|
|
35
|
+
* Empty / non-string input passes through unchanged so the caller can use
|
|
36
|
+
* this as a no-op on optional fields.
|
|
37
|
+
*/
|
|
38
|
+
export declare function redactSecrets(input: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Same as {@link redactSecrets} but also returns per-category counts so the
|
|
41
|
+
* caller can attach an audit summary to the trace metadata ('we stripped 2
|
|
42
|
+
* keys + 1 email before send').
|
|
43
|
+
*/
|
|
44
|
+
export declare function redactSecretsWithCounts(input: string): {
|
|
45
|
+
redacted: string;
|
|
46
|
+
counts: Record<string, number>;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAiHH;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBnD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAmCA"}
|
package/dist/redact.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module redact
|
|
3
|
+
*
|
|
4
|
+
* Lexical secret / PII scrubber for telemetry payloads. Verbatim port of
|
|
5
|
+
* OD's `apps/daemon/src/redact.ts` — no product-identity strings or
|
|
6
|
+
* hardcoded env vars in the original, so no genericization was needed.
|
|
7
|
+
*
|
|
8
|
+
* Runs before any prompt or assistant text is sent to an external
|
|
9
|
+
* observability sink. The patterns here are intentionally conservative:
|
|
10
|
+
* each one matches a well-defined token shape with extremely low
|
|
11
|
+
* false-positive rate (API keys have a fixed prefix, JWTs have the
|
|
12
|
+
* "header.payload.signature" triple, credit-card matches go through a Luhn
|
|
13
|
+
* check). What this file does NOT do — and any caller-facing copy must
|
|
14
|
+
* reflect that — is detect names, addresses, business secrets, or anything
|
|
15
|
+
* that requires understanding the meaning of the surrounding text. That's
|
|
16
|
+
* an ML / LLM problem this module doesn't take on.
|
|
17
|
+
*
|
|
18
|
+
* Output format: every match is replaced by `[REDACTED:<kind>]` so a
|
|
19
|
+
* reviewer reading a trace can see exactly which category fired without
|
|
20
|
+
* recovering the original value.
|
|
21
|
+
*
|
|
22
|
+
* References:
|
|
23
|
+
* - Langfuse client-side masking guidance:
|
|
24
|
+
* https://langfuse.com/docs/observability/features/masking
|
|
25
|
+
* - GitHub token format:
|
|
26
|
+
* https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github
|
|
27
|
+
* - AWS access key shape: 'AKIA' + 16 uppercase alphanumerics.
|
|
28
|
+
* - Luhn algorithm (credit cards): https://en.wikipedia.org/wiki/Luhn_algorithm
|
|
29
|
+
*/
|
|
30
|
+
// Order matters: list specific rules before more general ones. Langfuse
|
|
31
|
+
// keys (`sk-lf-...`) would otherwise be eaten by the generic `sk-...`
|
|
32
|
+
// rule and labeled as a generic OpenAI-style key.
|
|
33
|
+
const PATTERNS = [
|
|
34
|
+
// Langfuse public/secret keys (pk-lf- / sk-lf-). Must run before the
|
|
35
|
+
// generic sk- rule so the more specific label wins.
|
|
36
|
+
{ name: 'langfuse_key', regex: /\b(?:pk|sk)-lf-[A-Za-z0-9-]{16,}\b/g },
|
|
37
|
+
// Anthropic / OpenAI-style keys: 'sk-' + optional sub-prefix + base64-ish.
|
|
38
|
+
// Both vendors plus a long tail of OpenAI-compatible providers (DeepSeek,
|
|
39
|
+
// MiniMax, Together, etc.) ship keys in this shape, so a single rule
|
|
40
|
+
// covers most "sk-..." secrets a user might paste into a prompt.
|
|
41
|
+
{ name: 'sk_key', regex: /\bsk-(?:proj-|live-|test-|ant-)?[A-Za-z0-9_-]{20,}\b/g },
|
|
42
|
+
// GitHub personal / OAuth / server / user-server / refresh tokens.
|
|
43
|
+
{ name: 'github_token', regex: /\bgh[opsur]_[A-Za-z0-9]{36,251}\b/g },
|
|
44
|
+
// GitHub legacy 40-hex personal access tokens that ship with no prefix
|
|
45
|
+
// are indistinguishable from a sha1 hash, so we don't try to match them
|
|
46
|
+
// here — false positives would be brutal in commit logs / artifact slugs.
|
|
47
|
+
// AWS access key id. The matching secret access key is just 40 base64
|
|
48
|
+
// chars with no fixed shape, so we cannot reliably redact it without
|
|
49
|
+
// huge collateral damage; flagging the access key id at least
|
|
50
|
+
// signals a paste happened.
|
|
51
|
+
{ name: 'aws_access_key', regex: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
52
|
+
// Google API keys — legacy AIza… (Maps / AI Studio) and service-account-
|
|
53
|
+
// bound AQ.… keys AI Studio now issues. AQ. must run before the generic
|
|
54
|
+
// sk_ rule would mis-label unrelated tokens.
|
|
55
|
+
{ name: 'google_api_key', regex: /\bAQ\.[A-Za-z0-9_-]{20,}\b/g },
|
|
56
|
+
{ name: 'google_api_key', regex: /\bAIza[0-9A-Za-z_-]{35}\b/g },
|
|
57
|
+
// Slack tokens.
|
|
58
|
+
{ name: 'slack_token', regex: /\bxox[abprs]-[0-9A-Za-z-]{10,}\b/g },
|
|
59
|
+
// Stripe keys.
|
|
60
|
+
{ name: 'stripe_key', regex: /\b(?:sk|pk|rk)_(?:live|test)_[0-9a-zA-Z]{16,}\b/g },
|
|
61
|
+
// JSON Web Tokens. The "header.payload.signature" triple is distinctive
|
|
62
|
+
// enough that false positives are rare (the literal "eyJ" prefix is the
|
|
63
|
+
// base64 encoding of '{"' which is how every JOSE header starts).
|
|
64
|
+
{ name: 'jwt', regex: /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g },
|
|
65
|
+
// Bearer tokens in HTTP Authorization header copy/paste. We only match
|
|
66
|
+
// the value, not the literal 'Bearer ', so the marker stays readable in
|
|
67
|
+
// the redacted output ("Authorization: Bearer [REDACTED:bearer_token]").
|
|
68
|
+
{ name: 'bearer_token', regex: /(?<=\bBearer\s+)[A-Za-z0-9._~+/-]{16,}={0,2}/g },
|
|
69
|
+
// Email addresses. Conservative enough to require a TLD-like trailer.
|
|
70
|
+
{ name: 'email', regex: /\b[\w.+-]+@[\w-]+\.[\w.-]+\b/g },
|
|
71
|
+
// IPv4. Reject all-zero / 255.255.255.255-ish junk shapes by gating on
|
|
72
|
+
// each octet being 0-255.
|
|
73
|
+
{
|
|
74
|
+
name: 'ipv4',
|
|
75
|
+
regex: /\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\b/g,
|
|
76
|
+
},
|
|
77
|
+
// Phone numbers. Tight US-leaning shape; a global PII detector would
|
|
78
|
+
// need a real lib. We keep this so US-based test prompts ('call me at
|
|
79
|
+
// (415) 555-...') don't ship. Note: no leading \b — '(' isn't a word
|
|
80
|
+
// char, so a starting boundary would refuse to match `(415)`. We
|
|
81
|
+
// require a non-digit (or start of string) before the run instead.
|
|
82
|
+
{
|
|
83
|
+
name: 'phone',
|
|
84
|
+
regex: /(?<!\d)(?:\+?\d{1,3}[\s.-]?)?(?:\(\d{3}\)|\d{3})[\s.-]?\d{3}[\s.-]?\d{4}(?!\d)/g,
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
// Credit card sweep is special: a naive 13-19 digit run matches a lot of
|
|
88
|
+
// non-card numbers (timestamps, IDs, hashes). We isolate the candidate
|
|
89
|
+
// then run a Luhn check before redacting.
|
|
90
|
+
const CARD_CANDIDATE = /\b(?:\d[ -]?){12,18}\d\b/g;
|
|
91
|
+
const API_KEY_HEADER = /(^|[^?&\w-])("?)(x-api-key|api-key|x-goog-api-key)\2(\s*[:=]\s*)("[^"]*"|[^\s,;"'#}]+)/gi;
|
|
92
|
+
const API_KEY_QUERY = /([?&](?:key|api_key|api-key)=)[^&#\s,;"']+/gi;
|
|
93
|
+
// The length guard and the per-digit `d < 0 || d > 9` guard from the origin
|
|
94
|
+
// were both dropped here (a documented deviation from the otherwise-verbatim
|
|
95
|
+
// port — see source-map.md): `isLuhnValid` is private with exactly one call
|
|
96
|
+
// site (the `CARD_CANDIDATE.replace` callbacks below), and `CARD_CANDIDATE`'s
|
|
97
|
+
// own regex (`\b(?:\d[ -]?){12,18}\d\b`) already guarantees any string
|
|
98
|
+
// reaching here is 13-19 characters, and the preceding `match.replace(/\D/g,
|
|
99
|
+
// '')` strip guarantees every character is an ASCII digit — so both guards
|
|
100
|
+
// were provably unreachable, not speculative.
|
|
101
|
+
function isLuhnValid(digits) {
|
|
102
|
+
let sum = 0;
|
|
103
|
+
let alt = false;
|
|
104
|
+
for (let i = digits.length - 1; i >= 0; i -= 1) {
|
|
105
|
+
let d = digits.charCodeAt(i) - 48;
|
|
106
|
+
if (alt) {
|
|
107
|
+
d *= 2;
|
|
108
|
+
if (d > 9)
|
|
109
|
+
d -= 9;
|
|
110
|
+
}
|
|
111
|
+
sum += d;
|
|
112
|
+
alt = !alt;
|
|
113
|
+
}
|
|
114
|
+
return sum % 10 === 0;
|
|
115
|
+
}
|
|
116
|
+
function redactApiKeyHeaderValue(prefix, quote, name, separator, value) {
|
|
117
|
+
const redactedValue = value.startsWith('"') ? '"[REDACTED:api_key_header]"' : '[REDACTED:api_key_header]';
|
|
118
|
+
return `${prefix}${quote}${name}${quote}${separator}${redactedValue}`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns `input` with every recognised secret / PII pattern replaced by a
|
|
122
|
+
* `[REDACTED:<kind>]` marker. Idempotent — re-running on already redacted
|
|
123
|
+
* text only matches new tokens.
|
|
124
|
+
*
|
|
125
|
+
* Empty / non-string input passes through unchanged so the caller can use
|
|
126
|
+
* this as a no-op on optional fields.
|
|
127
|
+
*/
|
|
128
|
+
export function redactSecrets(input) {
|
|
129
|
+
if (!input)
|
|
130
|
+
return input;
|
|
131
|
+
let out = input;
|
|
132
|
+
for (const { name, regex } of PATTERNS) {
|
|
133
|
+
out = out.replace(regex, `[REDACTED:${name}]`);
|
|
134
|
+
}
|
|
135
|
+
out = out
|
|
136
|
+
.replace(API_KEY_HEADER, (_match, prefix, quote, name, separator, value) => redactApiKeyHeaderValue(prefix, quote, name, separator, value))
|
|
137
|
+
.replace(API_KEY_QUERY, '$1[REDACTED:api_key_query]');
|
|
138
|
+
out = out.replace(CARD_CANDIDATE, (match) => {
|
|
139
|
+
const digits = match.replace(/\D/g, '');
|
|
140
|
+
return isLuhnValid(digits) ? '[REDACTED:credit_card]' : match;
|
|
141
|
+
});
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Same as {@link redactSecrets} but also returns per-category counts so the
|
|
146
|
+
* caller can attach an audit summary to the trace metadata ('we stripped 2
|
|
147
|
+
* keys + 1 email before send').
|
|
148
|
+
*/
|
|
149
|
+
export function redactSecretsWithCounts(input) {
|
|
150
|
+
const counts = {};
|
|
151
|
+
if (!input)
|
|
152
|
+
return { redacted: input, counts };
|
|
153
|
+
let out = input;
|
|
154
|
+
for (const { name, regex } of PATTERNS) {
|
|
155
|
+
let matched = 0;
|
|
156
|
+
out = out.replace(regex, () => {
|
|
157
|
+
matched += 1;
|
|
158
|
+
return `[REDACTED:${name}]`;
|
|
159
|
+
});
|
|
160
|
+
if (matched > 0)
|
|
161
|
+
counts[name] = matched;
|
|
162
|
+
}
|
|
163
|
+
let apiKeyHeaderCount = 0;
|
|
164
|
+
out = out.replace(API_KEY_HEADER, (_match, prefix, quote, name, separator, value) => {
|
|
165
|
+
apiKeyHeaderCount += 1;
|
|
166
|
+
return redactApiKeyHeaderValue(prefix, quote, name, separator, value);
|
|
167
|
+
});
|
|
168
|
+
if (apiKeyHeaderCount > 0)
|
|
169
|
+
counts.api_key_header = apiKeyHeaderCount;
|
|
170
|
+
let apiKeyQueryCount = 0;
|
|
171
|
+
out = out.replace(API_KEY_QUERY, (_match, prefix) => {
|
|
172
|
+
apiKeyQueryCount += 1;
|
|
173
|
+
return `${prefix}[REDACTED:api_key_query]`;
|
|
174
|
+
});
|
|
175
|
+
if (apiKeyQueryCount > 0)
|
|
176
|
+
counts.api_key_query = apiKeyQueryCount;
|
|
177
|
+
let cardCount = 0;
|
|
178
|
+
out = out.replace(CARD_CANDIDATE, (match) => {
|
|
179
|
+
const digits = match.replace(/\D/g, '');
|
|
180
|
+
if (isLuhnValid(digits)) {
|
|
181
|
+
cardCount += 1;
|
|
182
|
+
return '[REDACTED:credit_card]';
|
|
183
|
+
}
|
|
184
|
+
return match;
|
|
185
|
+
});
|
|
186
|
+
if (cardCount > 0)
|
|
187
|
+
counts.credit_card = cardCount;
|
|
188
|
+
return { redacted: out, counts };
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
|
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Token<T, Id extends string = string> {
|
|
2
|
+
readonly id: Id;
|
|
3
|
+
readonly version: number;
|
|
4
|
+
readonly cardinality: 'one';
|
|
5
|
+
/** Phantom — never assigned; carries T for inference only. */
|
|
6
|
+
readonly __type?: T;
|
|
7
|
+
}
|
|
8
|
+
export interface ManyToken<T, Id extends string = string> {
|
|
9
|
+
readonly id: Id;
|
|
10
|
+
readonly version: number;
|
|
11
|
+
readonly cardinality: 'many';
|
|
12
|
+
/** Phantom — never assigned; carries T for inference only. */
|
|
13
|
+
readonly __type?: T;
|
|
14
|
+
}
|
|
15
|
+
export type AnyToken<T = unknown, Id extends string = string> = Token<T, Id> | ManyToken<T, Id>;
|
|
16
|
+
export declare function token<T, const Id extends string = string>(id: Id, opts?: {
|
|
17
|
+
version?: number;
|
|
18
|
+
}): Token<T, Id>;
|
|
19
|
+
export declare function manyToken<T, const Id extends string = string>(id: Id, opts?: {
|
|
20
|
+
version?: number;
|
|
21
|
+
}): ManyToken<T, Id>;
|
|
22
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK,CAAC,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG,MAAM;IAClD,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,EAAE,SAAS,MAAM,GAAG,MAAM;IACtD,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACrB;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAEhG,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAEhH;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAC3D,EAAE,EAAE,EAAE,EACN,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAElB"}
|
package/dist/token.js
ADDED