@webpieces/http-routing 0.3.352 → 0.3.353
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/http-routing",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.353",
|
|
4
4
|
"description": "Decorator-based routing with auto-wiring for WebPieces",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@inversifyjs/binding-decorators": "1.1.5",
|
|
25
|
-
"@webpieces/core-context": "0.3.
|
|
26
|
-
"@webpieces/core-util": "0.3.
|
|
27
|
-
"@webpieces/gcp-identity": "0.3.
|
|
25
|
+
"@webpieces/core-context": "0.3.353",
|
|
26
|
+
"@webpieces/core-util": "0.3.353",
|
|
27
|
+
"@webpieces/gcp-identity": "0.3.353",
|
|
28
28
|
"inversify": "7.10.4",
|
|
29
29
|
"jsonwebtoken": "9.0.2",
|
|
30
30
|
"minimatch": "10.0.1"
|
package/src/AuthHooks.d.ts
CHANGED
|
@@ -27,8 +27,9 @@ export declare abstract class JwtHook {
|
|
|
27
27
|
* by type; rebindable in tests) ONLY to customize the caller policy — e.g. an app that reads an
|
|
28
28
|
* `ALLOWED_OIDC_CALLERS` env var at its composition root and enforces that allow-list. When NO
|
|
29
29
|
* OidcHook is bound, the framework {@link AuthFilter} runs the built-in {@link DefaultOidcVerifier}
|
|
30
|
-
* directly, so a server that wires nothing still verifies Google OIDC
|
|
31
|
-
* (else
|
|
30
|
+
* directly, so a server that wires nothing still verifies Google OIDC against its `@AuthOidc(...callers)`
|
|
31
|
+
* (else trusts the edge — any Google-signed caller). `verifyOidc` verifies the token against `callers`;
|
|
32
|
+
* throw on failure.
|
|
32
33
|
*/
|
|
33
34
|
export declare abstract class OidcHook {
|
|
34
35
|
abstract verifyOidc(token: string, callers: string[]): Promise<void>;
|
package/src/AuthHooks.js
CHANGED
|
@@ -33,8 +33,9 @@ exports.JwtHook = JwtHook;
|
|
|
33
33
|
* by type; rebindable in tests) ONLY to customize the caller policy — e.g. an app that reads an
|
|
34
34
|
* `ALLOWED_OIDC_CALLERS` env var at its composition root and enforces that allow-list. When NO
|
|
35
35
|
* OidcHook is bound, the framework {@link AuthFilter} runs the built-in {@link DefaultOidcVerifier}
|
|
36
|
-
* directly, so a server that wires nothing still verifies Google OIDC
|
|
37
|
-
* (else
|
|
36
|
+
* directly, so a server that wires nothing still verifies Google OIDC against its `@AuthOidc(...callers)`
|
|
37
|
+
* (else trusts the edge — any Google-signed caller). `verifyOidc` verifies the token against `callers`;
|
|
38
|
+
* throw on failure.
|
|
38
39
|
*/
|
|
39
40
|
class OidcHook {
|
|
40
41
|
}
|
package/src/AuthHooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthHooks.js","sourceRoot":"","sources":["../../../../../packages/http/http-routing/src/AuthHooks.ts"],"names":[],"mappings":";;;AAAA,oDAA0E;AAG1E;;;;;;;;;;;;GAYG;AACH,MAAsB,OAAO;IAIzB;;;OAGG;IACH,YAAY,CAAC,MAAkB,EAAE,WAA2B;QACxD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACjF,MAAM,IAAI,8BAAkB,CAAC,mCAAmC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;CACJ;AAdD,0BAcC;AAED
|
|
1
|
+
{"version":3,"file":"AuthHooks.js","sourceRoot":"","sources":["../../../../../packages/http/http-routing/src/AuthHooks.ts"],"names":[],"mappings":";;;AAAA,oDAA0E;AAG1E;;;;;;;;;;;;GAYG;AACH,MAAsB,OAAO;IAIzB;;;OAGG;IACH,YAAY,CAAC,MAAkB,EAAE,WAA2B;QACxD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACjF,MAAM,IAAI,8BAAkB,CAAC,mCAAmC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACL,CAAC;CACJ;AAdD,0BAcC;AAED;;;;;;;;GAQG;AACH,MAAsB,QAAQ;CAE7B;AAFD,4BAEC","sourcesContent":["import { JwtRequirement, HttpForbiddenError } from '@webpieces/core-util';\nimport { AuthValues } from './AuthConfig';\n\n/**\n * JwtHook - the OPTIONAL user-JWT mechanism. Bind one (inject by type, per no-symbol-di-tokens;\n * rebindable in tests) to turn on `@AuthJwt(...)` endpoints. When NO JwtHook is bound, the framework\n * {@link AuthFilter} treats every jwt endpoint as \"not enabled\" and fails fast (401) — there is no\n * default JWT verification because it needs an app secret + payload shape the framework can't guess.\n *\n * - `parseJwt` — AUTHENTICATION: decode/verify a user JWT into {@link AuthValues}, or throw. The\n * app owns the strategy (HS256 secret, RS256 + JWKS, a provider SDK, ...).\n * - `authorizeJwt` — AUTHORIZATION: check the authenticated user against the endpoint's\n * {@link JwtRequirement}. The DEFAULT enforces `roles` (any-of; empty = any\n * authenticated user); override for app-defined requirements carried by\n * `@Auth({...})` — e.g. `if (requirement['inOrg'] && !values.claims['orgId']) ...`.\n */\nexport abstract class JwtHook {\n /** Parse a user JWT (kind:'jwt') — AUTHENTICATION only. Return who the user is, or throw. */\n abstract parseJwt(token: string): AuthValues;\n\n /**\n * DEFAULT authorization: enforce `roles` (any-of; empty = any authenticated user). Override to\n * enforce app-defined requirements. Throw HttpForbiddenError to deny; return to allow.\n */\n authorizeJwt(values: AuthValues, requirement: JwtRequirement): void {\n const roles = requirement.roles ?? [];\n if (roles.length > 0 && !roles.some((role: string) => values.roles.includes(role))) {\n throw new HttpForbiddenError(`Endpoint requires one of roles: ${roles.join(', ')}`);\n }\n }\n}\n\n/**\n * OidcHook - the OPTIONAL override for Google OIDC service-to-service verification. Bind one (inject\n * by type; rebindable in tests) ONLY to customize the caller policy — e.g. an app that reads an\n * `ALLOWED_OIDC_CALLERS` env var at its composition root and enforces that allow-list. When NO\n * OidcHook is bound, the framework {@link AuthFilter} runs the built-in {@link DefaultOidcVerifier}\n * directly, so a server that wires nothing still verifies Google OIDC against its `@AuthOidc(...callers)`\n * (else trusts the edge — any Google-signed caller). `verifyOidc` verifies the token against `callers`;\n * throw on failure.\n */\nexport abstract class OidcHook {\n abstract verifyOidc(token: string, callers: string[]): Promise<void>;\n}\n"]}
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
* OIDC "just work" with ZERO wiring: http-routing depends on @webpieces/gcp-identity ON PURPOSE so a
|
|
5
5
|
* server that binds nothing still verifies service-to-service OIDC.
|
|
6
6
|
*
|
|
7
|
-
* `verify`
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* `verify` honors the endpoint's `@AuthOidc(...callers)` contract exactly: EMPTY (a bare `@AuthOidc()`)
|
|
8
|
+
* = TRUST THE EDGE — verify the token is genuinely Google-signed and let the deployment's `run.invoker`
|
|
9
|
+
* IAM restrict WHO (gcp-identity warns loudly, once, if the service is actually public and thus the
|
|
10
|
+
* edge is NOT the gate). A non-empty list (`@AuthOidc('svc-a')`) enforces that explicit app-level
|
|
11
|
+
* allow-list as defense-in-depth. Off-GCP, gcp-identity mints + accepts a dev token so local dev needs
|
|
12
|
+
* no GCP. Framework code reads NO process.env — an app that wants an env-driven allow-list binds an
|
|
13
|
+
* {@link OidcHook} instead (env read at its composition root), keeping this default env-free and tests
|
|
14
|
+
* parallel-safe.
|
|
12
15
|
*/
|
|
13
16
|
export declare class DefaultOidcVerifier {
|
|
14
17
|
verify(token: string, callers: string[]): Promise<void>;
|
|
@@ -12,16 +12,21 @@ const gcp_identity_1 = require("@webpieces/gcp-identity");
|
|
|
12
12
|
* OIDC "just work" with ZERO wiring: http-routing depends on @webpieces/gcp-identity ON PURPOSE so a
|
|
13
13
|
* server that binds nothing still verifies service-to-service OIDC.
|
|
14
14
|
*
|
|
15
|
-
* `verify`
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* `verify` honors the endpoint's `@AuthOidc(...callers)` contract exactly: EMPTY (a bare `@AuthOidc()`)
|
|
16
|
+
* = TRUST THE EDGE — verify the token is genuinely Google-signed and let the deployment's `run.invoker`
|
|
17
|
+
* IAM restrict WHO (gcp-identity warns loudly, once, if the service is actually public and thus the
|
|
18
|
+
* edge is NOT the gate). A non-empty list (`@AuthOidc('svc-a')`) enforces that explicit app-level
|
|
19
|
+
* allow-list as defense-in-depth. Off-GCP, gcp-identity mints + accepts a dev token so local dev needs
|
|
20
|
+
* no GCP. Framework code reads NO process.env — an app that wants an env-driven allow-list binds an
|
|
21
|
+
* {@link OidcHook} instead (env read at its composition root), keeping this default env-free and tests
|
|
22
|
+
* parallel-safe.
|
|
20
23
|
*/
|
|
21
24
|
let DefaultOidcVerifier = class DefaultOidcVerifier {
|
|
22
25
|
async verify(token, callers) {
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
// callers pass straight through: EMPTY (@AuthOidc() with no callers) = TRUST THE EDGE, a
|
|
27
|
+
// non-empty list enforces the explicit allow-list. Do NOT inject a ['self'] default — that
|
|
28
|
+
// would reject a legitimate cross-SA caller the edge already admitted.
|
|
29
|
+
const result = await (0, gcp_identity_1.verifyOidcFromCallers)(token, callers);
|
|
25
30
|
if (!result.ok) {
|
|
26
31
|
throw new core_util_1.HttpUnauthorizedError(`OIDC rejected: ${result.reason ?? 'not an allowed caller'}`);
|
|
27
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultOidcVerifier.js","sourceRoot":"","sources":["../../../../../packages/http/http-routing/src/DefaultOidcVerifier.ts"],"names":[],"mappings":";;;;AAAA,yCAAuC;AACvC,0DAAoE;AACpE,oDAA6D;AAC7D,0DAAgE;AAEhE
|
|
1
|
+
{"version":3,"file":"DefaultOidcVerifier.js","sourceRoot":"","sources":["../../../../../packages/http/http-routing/src/DefaultOidcVerifier.ts"],"names":[],"mappings":";;;;AAAA,yCAAuC;AACvC,0DAAoE;AACpE,oDAA6D;AAC7D,0DAAgE;AAEhE;;;;;;;;;;;;;;GAcG;AAGI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC5B,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAiB;QACzC,yFAAyF;QACzF,2FAA2F;QAC3F,uEAAuE;QACvE,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAqB,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,iCAAqB,CAAC,kBAAkB,MAAM,CAAC,MAAM,IAAI,uBAAuB,EAAE,CAAC,CAAC;QAClG,CAAC;IACL,CAAC;CACJ,CAAA;AAVY,kDAAmB;8BAAnB,mBAAmB;IAF/B,IAAA,wCAAyB,GAAE;IAC3B,IAAA,sBAAU,GAAE;GACA,mBAAmB,CAU/B","sourcesContent":["import { injectable } from 'inversify';\nimport { provideFrameworkSingleton } from '@webpieces/core-context';\nimport { HttpUnauthorizedError } from '@webpieces/core-util';\nimport { verifyOidcFromCallers } from '@webpieces/gcp-identity';\n\n/**\n * DefaultOidcVerifier - the framework's built-in Google OIDC verifier, injected into\n * {@link AuthFilter} and run directly whenever no app {@link OidcHook} is bound. It is what makes\n * OIDC \"just work\" with ZERO wiring: http-routing depends on @webpieces/gcp-identity ON PURPOSE so a\n * server that binds nothing still verifies service-to-service OIDC.\n *\n * `verify` honors the endpoint's `@AuthOidc(...callers)` contract exactly: EMPTY (a bare `@AuthOidc()`)\n * = TRUST THE EDGE — verify the token is genuinely Google-signed and let the deployment's `run.invoker`\n * IAM restrict WHO (gcp-identity warns loudly, once, if the service is actually public and thus the\n * edge is NOT the gate). A non-empty list (`@AuthOidc('svc-a')`) enforces that explicit app-level\n * allow-list as defense-in-depth. Off-GCP, gcp-identity mints + accepts a dev token so local dev needs\n * no GCP. Framework code reads NO process.env — an app that wants an env-driven allow-list binds an\n * {@link OidcHook} instead (env read at its composition root), keeping this default env-free and tests\n * parallel-safe.\n */\n@provideFrameworkSingleton()\n@injectable()\nexport class DefaultOidcVerifier {\n async verify(token: string, callers: string[]): Promise<void> {\n // callers pass straight through: EMPTY (@AuthOidc() with no callers) = TRUST THE EDGE, a\n // non-empty list enforces the explicit allow-list. Do NOT inject a ['self'] default — that\n // would reject a legitimate cross-SA caller the edge already admitted.\n const result = await verifyOidcFromCallers(token, callers);\n if (!result.ok) {\n throw new HttpUnauthorizedError(`OIDC rejected: ${result.reason ?? 'not an allowed caller'}`);\n }\n }\n}\n"]}
|