@t4h.framework/oidc 0.0.0-experimental-858514c-40d427e3f546ef29ce9e
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/README.md +62 -0
- package/dist/helpers/client-credentials.d.ts +3 -0
- package/dist/helpers/client-credentials.d.ts.map +1 -0
- package/dist/helpers/client-credentials.js +18 -0
- package/dist/helpers/client-credentials.js.map +1 -0
- package/dist/models/OIDCAuthorization.d.ts +15 -0
- package/dist/models/OIDCAuthorization.d.ts.map +1 -0
- package/dist/models/OIDCAuthorization.js +20 -0
- package/dist/models/OIDCAuthorization.js.map +1 -0
- package/dist/oidc-authorize.d.ts +3 -0
- package/dist/oidc-authorize.d.ts.map +1 -0
- package/dist/oidc-authorize.js +18 -0
- package/dist/oidc-authorize.js.map +1 -0
- package/dist/oidc.d.ts +3 -0
- package/dist/oidc.d.ts.map +1 -0
- package/dist/oidc.js +3 -0
- package/dist/oidc.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @t4h.framework/jwks
|
|
2
|
+
|
|
3
|
+
JWT authorization module backed by a JWKS endpoint.
|
|
4
|
+
|
|
5
|
+
## Behavior
|
|
6
|
+
|
|
7
|
+
The authorization handler validates a JWT using a JWKS endpoint and returns:
|
|
8
|
+
|
|
9
|
+
- `undefined` when the token is valid
|
|
10
|
+
- `401 Unauthorized` when the token is missing or invalid
|
|
11
|
+
- `500 JWKS authorization failed` when infrastructure/configuration fails
|
|
12
|
+
|
|
13
|
+
## JWKS configuration
|
|
14
|
+
|
|
15
|
+
Set one of:
|
|
16
|
+
|
|
17
|
+
- `JWKS_URI`: direct JWKS endpoint URL
|
|
18
|
+
- `JWKS_ISSUER`: OIDC issuer URL (the module discovers metadata and resolves `jwks_uri`)
|
|
19
|
+
|
|
20
|
+
Optional:
|
|
21
|
+
|
|
22
|
+
- `JWKS_CLIENT_ID`: client id used during issuer discovery when `JWKS_ISSUER` is used (default: `jwks-resource-server`)
|
|
23
|
+
|
|
24
|
+
You can also define these values in `JWKSAuthorization` options (`jwksUri`, `jwksIssuer`, `clientId`) instead of environment variables.
|
|
25
|
+
|
|
26
|
+
## Credential source (customizable)
|
|
27
|
+
|
|
28
|
+
The token source is configured in `JWKSAuthorization` through `credentialSource`.
|
|
29
|
+
|
|
30
|
+
- default: `Authorization: Bearer <token>`
|
|
31
|
+
- custom header: e.g. `x-webhook-jwt`
|
|
32
|
+
- query string: e.g. `?token=<jwt>`
|
|
33
|
+
|
|
34
|
+
### Examples
|
|
35
|
+
|
|
36
|
+
Default bearer:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { JWKSAuthorization } from '@t4h.framework/jwks'
|
|
40
|
+
|
|
41
|
+
const authorization = new JWKSAuthorization()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Webhook header (raw token, no Bearer prefix):
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { JWKSAuthorization } from '@t4h.framework/jwks'
|
|
48
|
+
|
|
49
|
+
const authorization = new JWKSAuthorization({
|
|
50
|
+
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
|
|
51
|
+
credentialSource: {
|
|
52
|
+
type: 'header',
|
|
53
|
+
name: 'x-webhook-jwt',
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Validation currently enforced
|
|
59
|
+
|
|
60
|
+
- Token extraction from configured source
|
|
61
|
+
- JWT signature using a key from JWKS
|
|
62
|
+
- Required `exp` claim (must be in the future)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials.d.ts","sourceRoot":"","sources":["../../src/helpers/client-credentials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE1D,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,oBA0BxE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as client from 'openid-client';
|
|
2
|
+
export async function clientCredentials(options) {
|
|
3
|
+
const discovery = await client.discovery(new URL(options.url), options.clientId, options.clientSecret);
|
|
4
|
+
const scope = Array.isArray(options.scope)
|
|
5
|
+
? options.scope.join(' ')
|
|
6
|
+
: options.scope;
|
|
7
|
+
const params = new URLSearchParams();
|
|
8
|
+
if (scope)
|
|
9
|
+
params.set('scope', scope);
|
|
10
|
+
if (options.resource)
|
|
11
|
+
params.set('resource', options.resource);
|
|
12
|
+
const { access_token } = await client.clientCredentialsGrant(discovery, params);
|
|
13
|
+
const token = await client.tokenIntrospection(discovery, access_token);
|
|
14
|
+
if (!token.active)
|
|
15
|
+
return false;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=client-credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-credentials.js","sourceRoot":"","sources":["../../src/helpers/client-credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAiC;IACvE,MAAM,SAAS,GAAyB,MAAM,MAAM,CAAC,SAAS,CAC5D,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EACpB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,YAAY,CACrB,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAA;IAEjB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IAEpC,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACrC,IAAI,OAAO,CAAC,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9D,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAC1D,SAAS,EACT,MAAM,CACP,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAEtE,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAE/B,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Authorization, type AuthenticationManifest } from '@t4h.framework/core';
|
|
2
|
+
export type OIDCAuthorizationContext = {
|
|
3
|
+
url: string;
|
|
4
|
+
clientId: string;
|
|
5
|
+
clientSecret: string;
|
|
6
|
+
scope?: string[];
|
|
7
|
+
resource?: string;
|
|
8
|
+
};
|
|
9
|
+
export type OIDCAuthorizationManifest = AuthenticationManifest<OIDCAuthorizationContext>;
|
|
10
|
+
export declare class OIDCAuthorization extends Authorization<OIDCAuthorizationContext> {
|
|
11
|
+
private readonly context;
|
|
12
|
+
constructor(context: OIDCAuthorizationContext);
|
|
13
|
+
toManifest(): OIDCAuthorizationManifest;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=OIDCAuthorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OIDCAuthorization.d.ts","sourceRoot":"","sources":["../../src/models/OIDCAuthorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEhF,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,yBAAyB,GACnC,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;AAElD,qBAAa,iBAAkB,SAAQ,aAAa,CAAC,wBAAwB,CAAC;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,wBAAwB;IAIvD,UAAU,IAAI,yBAAyB;CAW/C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Authorization } from '@t4h.framework/core';
|
|
2
|
+
export class OIDCAuthorization extends Authorization {
|
|
3
|
+
context;
|
|
4
|
+
constructor(context) {
|
|
5
|
+
super();
|
|
6
|
+
this.context = context;
|
|
7
|
+
}
|
|
8
|
+
toManifest() {
|
|
9
|
+
return {
|
|
10
|
+
context: {
|
|
11
|
+
url: this.context.url,
|
|
12
|
+
clientId: this.context.clientId,
|
|
13
|
+
clientSecret: this.context.clientSecret,
|
|
14
|
+
scope: this.context.scope,
|
|
15
|
+
},
|
|
16
|
+
pathToModule: '@t4h.framework/oidc/authorize',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=OIDCAuthorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OIDCAuthorization.js","sourceRoot":"","sources":["../../src/models/OIDCAuthorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA+B,MAAM,qBAAqB,CAAA;AAahF,MAAM,OAAO,iBAAkB,SAAQ,aAAuC;IAC/C;IAA7B,YAA6B,OAAiC;QAC5D,KAAK,EAAE,CAAA;QADoB,YAAO,GAAP,OAAO,CAA0B;IAE9D,CAAC;IAEM,UAAU;QACf,OAAO;YACL,OAAO,EAAE;gBACP,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;gBACrB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;gBAC/B,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;gBACvC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;aAC1B;YACD,YAAY,EAAE,+BAA+B;SAC9C,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-authorize.d.ts","sourceRoot":"","sources":["../src/oidc-authorize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAA;AAEzD,wBAA8B,IAAI,CAChC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CA0BlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as client from 'openid-client';
|
|
2
|
+
export default async function oidc(context) {
|
|
3
|
+
const discovery = await client.discovery(new URL(context.url), context.clientId, context.clientSecret);
|
|
4
|
+
const scope = Array.isArray(context.scope)
|
|
5
|
+
? context.scope.join(' ')
|
|
6
|
+
: context.scope;
|
|
7
|
+
const params = new URLSearchParams();
|
|
8
|
+
if (scope)
|
|
9
|
+
params.set('scope', scope);
|
|
10
|
+
if (context.resource)
|
|
11
|
+
params.set('resource', context.resource);
|
|
12
|
+
const { access_token } = await client.clientCredentialsGrant(discovery, params);
|
|
13
|
+
const token = await client.tokenIntrospection(discovery, access_token);
|
|
14
|
+
if (!token.active)
|
|
15
|
+
return false;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=oidc-authorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-authorize.js","sourceRoot":"","sources":["../src/oidc-authorize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,IAAI,CAChC,OAAiC;IAEjC,MAAM,SAAS,GAAyB,MAAM,MAAM,CAAC,SAAS,CAC5D,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EACpB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,YAAY,CACrB,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACzB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAA;IAEjB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IAEpC,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACrC,IAAI,OAAO,CAAC,QAAQ;QAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9D,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAC1D,SAAS,EACT,MAAM,CACP,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAEtE,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAE/B,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/oidc.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,+BAA+B,CAAA"}
|
package/dist/oidc.js
ADDED
package/dist/oidc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.js","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,+BAA+B,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@t4h.framework/oidc",
|
|
3
|
+
"version": "0.0.0-experimental-858514c-40d427e3f546ef29ce9e",
|
|
4
|
+
"description": "OIDC module for the T4H Framework authorization",
|
|
5
|
+
"homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/oidc",
|
|
6
|
+
"bugs": "https://github.com/tech4humans-brasil/framework/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/tech4humans-brasil/framework.git",
|
|
10
|
+
"directory": "packages/oidc"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Tech4Humans <contact@tech4h.com.br> (https://tech4h.com.br)",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/oidc.d.ts",
|
|
18
|
+
"import": "./dist/oidc.js"
|
|
19
|
+
},
|
|
20
|
+
"./authorize": {
|
|
21
|
+
"types": "./dist/oidc-authorize.d.ts",
|
|
22
|
+
"import": "./dist/oidc-authorize.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"module": "./dist/oidc.js",
|
|
26
|
+
"types": "./dist/oidc.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc --project tsconfig.build.json",
|
|
33
|
+
"check-types": "tsc --noEmit",
|
|
34
|
+
"prepublishOnly": "yarn build",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@t4h.framework/core": "^0.0.0-experimental-858514c-40d427e3f546ef29ce9e",
|
|
40
|
+
"@types/jsonwebtoken": "^9",
|
|
41
|
+
"typescript": "^5.9.3",
|
|
42
|
+
"vitest": "^4.0.18"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@t4h.framework/core": "^0.0.0-experimental-858514c-40d427e3f546ef29ce9e"
|
|
46
|
+
},
|
|
47
|
+
"packageManager": "yarn@4.12.0",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=22"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"jsonwebtoken": "^9.0.3",
|
|
53
|
+
"jwks-rsa": "^4.0.1",
|
|
54
|
+
"openid-client": "^6.8.2"
|
|
55
|
+
},
|
|
56
|
+
"stableVersion": "0.0.0"
|
|
57
|
+
}
|