@infoxchange/make-it-so 2.10.0 → 2.11.0-internal-testing-vdt-199-add-auth-token-verify-function.1
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/lib/auth/oidc.d.ts +26 -0
- package/dist/lib/auth/oidc.d.ts.map +1 -0
- package/dist/lib/auth/oidc.js +48 -0
- package/package.json +1 -1
- package/src/lib/auth/oidc.ts +73 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { JWTPayload } from "jose";
|
|
2
|
+
type VerifyAccessTokenParams<SafeVerify extends boolean = false> = {
|
|
3
|
+
token: string;
|
|
4
|
+
issuerUrl: string;
|
|
5
|
+
audience: string;
|
|
6
|
+
safeVerify?: SafeVerify;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Checks an OIDC access token against the issuer's details to determine if it's valid.
|
|
10
|
+
*
|
|
11
|
+
* @param params - The parameters for verifying the access token.
|
|
12
|
+
* @param params.token - The JWT access token to verify.
|
|
13
|
+
* @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
|
|
14
|
+
* @param params.audience - The expected audience value to match against the token's claims.
|
|
15
|
+
* @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
|
|
16
|
+
* @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
|
|
17
|
+
*/
|
|
18
|
+
export declare function verifyAccessToken<SafeVerify extends boolean = false>({ token, issuerUrl, audience, safeVerify, }: VerifyAccessTokenParams<SafeVerify>): Promise<SafeVerify extends true ? {
|
|
19
|
+
error: Error | unknown;
|
|
20
|
+
payload: null;
|
|
21
|
+
} | {
|
|
22
|
+
error: null;
|
|
23
|
+
payload: JWTPayload;
|
|
24
|
+
} : JWTPayload>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=oidc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oidc.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,UAAU,EAAa,MAAM,MAAM,CAAC;AAEjE,KAAK,uBAAuB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,IAAI;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,EAAE,EAC1E,KAAK,EACL,SAAS,EACT,QAAQ,EACR,UAAU,GACX,EAAE,uBAAuB,CAAC,UAAU,CAAC,GAAG,OAAO,CAC9C,UAAU,SAAS,IAAI,GAEf;IAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GACxC,UAAU,CACf,CAyCA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Issuer } from "openid-client";
|
|
2
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3
|
+
/**
|
|
4
|
+
* Checks an OIDC access token against the issuer's details to determine if it's valid.
|
|
5
|
+
*
|
|
6
|
+
* @param params - The parameters for verifying the access token.
|
|
7
|
+
* @param params.token - The JWT access token to verify.
|
|
8
|
+
* @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
|
|
9
|
+
* @param params.audience - The expected audience value to match against the token's claims.
|
|
10
|
+
* @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
|
|
11
|
+
* @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
|
|
12
|
+
*/
|
|
13
|
+
export async function verifyAccessToken({ token, issuerUrl, audience, safeVerify, }) {
|
|
14
|
+
try {
|
|
15
|
+
const issuer = await Issuer.discover(issuerUrl);
|
|
16
|
+
const jwksUri = issuer.metadata.jwks_uri;
|
|
17
|
+
if (!jwksUri) {
|
|
18
|
+
throw new Error("JWKS URI not found in issuer metadata");
|
|
19
|
+
}
|
|
20
|
+
const JWKS = createRemoteJWKSet(new URL(jwksUri));
|
|
21
|
+
// Verify the signature and basic claims
|
|
22
|
+
const { payload } = await jwtVerify(token, JWKS, {
|
|
23
|
+
issuer: issuer.metadata.issuer,
|
|
24
|
+
});
|
|
25
|
+
const tokenAud = payload.aud ?? payload.client_id;
|
|
26
|
+
let audienceMatches = false;
|
|
27
|
+
for (const aud of Array.isArray(tokenAud) ? tokenAud : [tokenAud]) {
|
|
28
|
+
if (aud === audience) {
|
|
29
|
+
audienceMatches = true;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!audienceMatches) {
|
|
34
|
+
console.info("Token data:", payload);
|
|
35
|
+
throw new Error(`Token audience does not match expected audience ${audience}`);
|
|
36
|
+
}
|
|
37
|
+
if (safeVerify) {
|
|
38
|
+
return { payload, error: null };
|
|
39
|
+
}
|
|
40
|
+
return payload;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (safeVerify) {
|
|
44
|
+
return { error: err, payload: null };
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infoxchange/make-it-so",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0-internal-testing-vdt-199-add-auth-token-verify-function.1",
|
|
4
4
|
"description": "Makes deploying services to IX infra easy",
|
|
5
5
|
"repository": "github:infoxchange/make-it-so",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Issuer } from "openid-client";
|
|
2
|
+
import { createRemoteJWKSet, JWTPayload, jwtVerify } from "jose";
|
|
3
|
+
|
|
4
|
+
type VerifyAccessTokenParams<SafeVerify extends boolean = false> = {
|
|
5
|
+
token: string;
|
|
6
|
+
issuerUrl: string;
|
|
7
|
+
audience: string;
|
|
8
|
+
safeVerify?: SafeVerify;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Checks an OIDC access token against the issuer's details to determine if it's valid.
|
|
13
|
+
*
|
|
14
|
+
* @param params - The parameters for verifying the access token.
|
|
15
|
+
* @param params.token - The JWT access token to verify.
|
|
16
|
+
* @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
|
|
17
|
+
* @param params.audience - The expected audience value to match against the token's claims.
|
|
18
|
+
* @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
|
|
19
|
+
* @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
|
|
20
|
+
*/
|
|
21
|
+
export async function verifyAccessToken<SafeVerify extends boolean = false>({
|
|
22
|
+
token,
|
|
23
|
+
issuerUrl,
|
|
24
|
+
audience,
|
|
25
|
+
safeVerify,
|
|
26
|
+
}: VerifyAccessTokenParams<SafeVerify>): Promise<
|
|
27
|
+
SafeVerify extends true
|
|
28
|
+
?
|
|
29
|
+
| { error: Error | unknown; payload: null }
|
|
30
|
+
| { error: null; payload: JWTPayload }
|
|
31
|
+
: JWTPayload
|
|
32
|
+
> {
|
|
33
|
+
try {
|
|
34
|
+
const issuer = await Issuer.discover(issuerUrl);
|
|
35
|
+
const jwksUri = issuer.metadata.jwks_uri;
|
|
36
|
+
if (!jwksUri) {
|
|
37
|
+
throw new Error("JWKS URI not found in issuer metadata");
|
|
38
|
+
}
|
|
39
|
+
const JWKS = createRemoteJWKSet(new URL(jwksUri));
|
|
40
|
+
|
|
41
|
+
// Verify the signature and basic claims
|
|
42
|
+
const { payload } = await jwtVerify(token, JWKS, {
|
|
43
|
+
issuer: issuer.metadata.issuer,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const tokenAud = payload.aud ?? payload.client_id;
|
|
47
|
+
let audienceMatches = false;
|
|
48
|
+
for (const aud of Array.isArray(tokenAud) ? tokenAud : [tokenAud]) {
|
|
49
|
+
if (aud === audience) {
|
|
50
|
+
audienceMatches = true;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!audienceMatches) {
|
|
55
|
+
console.info("Token data:", payload);
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Token audience does not match expected audience ${audience}`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (safeVerify) {
|
|
62
|
+
return { payload, error: null };
|
|
63
|
+
}
|
|
64
|
+
return payload as SafeVerify extends true
|
|
65
|
+
? { error: null; payload: JWTPayload }
|
|
66
|
+
: JWTPayload;
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (safeVerify) {
|
|
69
|
+
return { error: err, payload: null };
|
|
70
|
+
}
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
}
|