@authrim/server 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/README.md +610 -0
- package/dist/adapters/express.cjs +3 -0
- package/dist/adapters/express.cjs.map +1 -0
- package/dist/adapters/express.d.cts +75 -0
- package/dist/adapters/express.d.ts +75 -0
- package/dist/adapters/express.js +3 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/fastify.cjs +3 -0
- package/dist/adapters/fastify.cjs.map +1 -0
- package/dist/adapters/fastify.d.cts +101 -0
- package/dist/adapters/fastify.d.ts +101 -0
- package/dist/adapters/fastify.js +3 -0
- package/dist/adapters/fastify.js.map +1 -0
- package/dist/adapters/hono.cjs +2 -0
- package/dist/adapters/hono.cjs.map +1 -0
- package/dist/adapters/hono.d.cts +85 -0
- package/dist/adapters/hono.d.ts +85 -0
- package/dist/adapters/hono.js +2 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/koa.cjs +3 -0
- package/dist/adapters/koa.cjs.map +1 -0
- package/dist/adapters/koa.d.cts +75 -0
- package/dist/adapters/koa.d.ts +75 -0
- package/dist/adapters/koa.js +3 -0
- package/dist/adapters/koa.js.map +1 -0
- package/dist/adapters/nestjs.cjs +3 -0
- package/dist/adapters/nestjs.cjs.map +1 -0
- package/dist/adapters/nestjs.d.cts +126 -0
- package/dist/adapters/nestjs.d.ts +126 -0
- package/dist/adapters/nestjs.js +3 -0
- package/dist/adapters/nestjs.js.map +1 -0
- package/dist/chunk-7POGA5LZ.cjs +3 -0
- package/dist/chunk-7POGA5LZ.cjs.map +1 -0
- package/dist/chunk-N3ONRO35.js +2 -0
- package/dist/chunk-N3ONRO35.js.map +1 -0
- package/dist/chunk-O2ALCNXB.cjs +2 -0
- package/dist/chunk-O2ALCNXB.cjs.map +1 -0
- package/dist/chunk-OS567YCE.js +3 -0
- package/dist/chunk-OS567YCE.js.map +1 -0
- package/dist/chunk-TPROSFE7.cjs +2 -0
- package/dist/chunk-TPROSFE7.cjs.map +1 -0
- package/dist/chunk-XOFM2JHF.js +2 -0
- package/dist/chunk-XOFM2JHF.js.map +1 -0
- package/dist/config-I0GIVJA_.d.cts +364 -0
- package/dist/config-I0GIVJA_.d.ts +364 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +791 -0
- package/dist/index.d.ts +791 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/index.cjs +2 -0
- package/dist/providers/index.cjs.map +1 -0
- package/dist/providers/index.d.cts +79 -0
- package/dist/providers/index.d.ts +79 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/types-CzpMdWFR.d.cts +435 -0
- package/dist/types-D7gjcvs9.d.ts +435 -0
- package/package.json +119 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { V as ValidatedToken, A as AuthrimServer, M as MiddlewareOptions } from '../types-CzpMdWFR.cjs';
|
|
2
|
+
import '../config-I0GIVJA_.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Koa Adapter
|
|
6
|
+
*
|
|
7
|
+
* Thin wrapper around authenticateRequest for Koa framework.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Koa state with auth
|
|
12
|
+
*/
|
|
13
|
+
interface AuthrimKoaState {
|
|
14
|
+
auth?: ValidatedToken;
|
|
15
|
+
authTokenType?: 'Bearer' | 'DPoP';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Koa context type (minimal interface)
|
|
19
|
+
*/
|
|
20
|
+
interface KoaContext {
|
|
21
|
+
request: {
|
|
22
|
+
headers: Record<string, string | string[] | undefined>;
|
|
23
|
+
method: string;
|
|
24
|
+
protocol: string;
|
|
25
|
+
host: string;
|
|
26
|
+
url: string;
|
|
27
|
+
};
|
|
28
|
+
response: {
|
|
29
|
+
status: number;
|
|
30
|
+
set(headers: Record<string, string>): void;
|
|
31
|
+
body: unknown;
|
|
32
|
+
};
|
|
33
|
+
state: AuthrimKoaState;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Koa next function
|
|
37
|
+
*/
|
|
38
|
+
type KoaNext = () => Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Create Koa middleware for token validation
|
|
41
|
+
*
|
|
42
|
+
* @param server - AuthrimServer instance
|
|
43
|
+
* @param options - Middleware options
|
|
44
|
+
* @returns Koa middleware function
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import Koa from 'koa';
|
|
49
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
50
|
+
* import { authrimMiddleware } from '@authrim/server/adapters/koa';
|
|
51
|
+
*
|
|
52
|
+
* const app = new Koa();
|
|
53
|
+
* const server = createAuthrimServer({
|
|
54
|
+
* issuer: 'https://auth.example.com',
|
|
55
|
+
* audience: 'https://api.example.com',
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* app.use(authrimMiddleware(server));
|
|
59
|
+
*
|
|
60
|
+
* app.use((ctx) => {
|
|
61
|
+
* ctx.body = { user: ctx.state.auth?.claims.sub };
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function authrimMiddleware(server: AuthrimServer, options?: MiddlewareOptions): (ctx: KoaContext, next: KoaNext) => Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Create optional auth middleware (doesn't fail if no token)
|
|
68
|
+
*
|
|
69
|
+
* @param server - AuthrimServer instance
|
|
70
|
+
* @param _options - Middleware options (unused for optional middleware)
|
|
71
|
+
* @returns Koa middleware function
|
|
72
|
+
*/
|
|
73
|
+
declare function authrimOptionalMiddleware(server: AuthrimServer, _options?: MiddlewareOptions): (ctx: KoaContext, next: KoaNext) => Promise<void>;
|
|
74
|
+
|
|
75
|
+
export { type AuthrimKoaState, authrimMiddleware, authrimOptionalMiddleware };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { V as ValidatedToken, A as AuthrimServer, M as MiddlewareOptions } from '../types-D7gjcvs9.js';
|
|
2
|
+
import '../config-I0GIVJA_.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Koa Adapter
|
|
6
|
+
*
|
|
7
|
+
* Thin wrapper around authenticateRequest for Koa framework.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Koa state with auth
|
|
12
|
+
*/
|
|
13
|
+
interface AuthrimKoaState {
|
|
14
|
+
auth?: ValidatedToken;
|
|
15
|
+
authTokenType?: 'Bearer' | 'DPoP';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Koa context type (minimal interface)
|
|
19
|
+
*/
|
|
20
|
+
interface KoaContext {
|
|
21
|
+
request: {
|
|
22
|
+
headers: Record<string, string | string[] | undefined>;
|
|
23
|
+
method: string;
|
|
24
|
+
protocol: string;
|
|
25
|
+
host: string;
|
|
26
|
+
url: string;
|
|
27
|
+
};
|
|
28
|
+
response: {
|
|
29
|
+
status: number;
|
|
30
|
+
set(headers: Record<string, string>): void;
|
|
31
|
+
body: unknown;
|
|
32
|
+
};
|
|
33
|
+
state: AuthrimKoaState;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Koa next function
|
|
37
|
+
*/
|
|
38
|
+
type KoaNext = () => Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Create Koa middleware for token validation
|
|
41
|
+
*
|
|
42
|
+
* @param server - AuthrimServer instance
|
|
43
|
+
* @param options - Middleware options
|
|
44
|
+
* @returns Koa middleware function
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import Koa from 'koa';
|
|
49
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
50
|
+
* import { authrimMiddleware } from '@authrim/server/adapters/koa';
|
|
51
|
+
*
|
|
52
|
+
* const app = new Koa();
|
|
53
|
+
* const server = createAuthrimServer({
|
|
54
|
+
* issuer: 'https://auth.example.com',
|
|
55
|
+
* audience: 'https://api.example.com',
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* app.use(authrimMiddleware(server));
|
|
59
|
+
*
|
|
60
|
+
* app.use((ctx) => {
|
|
61
|
+
* ctx.body = { user: ctx.state.auth?.claims.sub };
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function authrimMiddleware(server: AuthrimServer, options?: MiddlewareOptions): (ctx: KoaContext, next: KoaNext) => Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Create optional auth middleware (doesn't fail if no token)
|
|
68
|
+
*
|
|
69
|
+
* @param server - AuthrimServer instance
|
|
70
|
+
* @param _options - Middleware options (unused for optional middleware)
|
|
71
|
+
* @returns Koa middleware function
|
|
72
|
+
*/
|
|
73
|
+
declare function authrimOptionalMiddleware(server: AuthrimServer, _options?: MiddlewareOptions): (ctx: KoaContext, next: KoaNext) => Promise<void>;
|
|
74
|
+
|
|
75
|
+
export { type AuthrimKoaState, authrimMiddleware, authrimOptionalMiddleware };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {c as c$1,a as a$1}from'../chunk-XOFM2JHF.js';import {c,a}from'../chunk-N3ONRO35.js';function g(a$2,o={}){return async(e,s)=>{let n=`${e.request.protocol}://${e.request.host}${e.request.url}`,r=await c(a$2,{headers:e.request.headers,method:e.request.method,url:n});if(r.error){let t=new a(r.error.code,r.error.message),h=c$1(t,{realm:o.realm,scheme:"Bearer"});o.onError&&o.onError(r.error),e.response.status=r.error.httpStatus,e.response.set(h),e.response.body=a$1(t);return}e.state.auth=r.data.claims,e.state.authTokenType=r.data.tokenType,await s();}}function y(a,o={}){return async(e,s)=>{if(!e.request.headers.authorization){await s();return}let r=`${e.request.protocol}://${e.request.host}${e.request.url}`,t=await c(a,{headers:e.request.headers,method:e.request.method,url:r});t.data&&(e.state.auth=t.data.claims,e.state.authTokenType=t.data.tokenType),await s();}}
|
|
2
|
+
export{g as authrimMiddleware,y as authrimOptionalMiddleware};//# sourceMappingURL=koa.js.map
|
|
3
|
+
//# sourceMappingURL=koa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/koa.ts"],"names":["authrimMiddleware","server","options","ctx","next","url","result","authenticateRequest","error","AuthrimServerError","headers","buildErrorHeaders","buildErrorResponse","authrimOptionalMiddleware","_options"],"mappings":"4FAuEO,SAASA,EACdC,GAAAA,CACAC,CAAAA,CAA6B,EAAC,CAC9B,CACA,OAAO,MAAOC,CAAAA,CAAiBC,IAAiC,CAE9D,IAAMC,EAAM,CAAA,EAAGF,CAAAA,CAAI,QAAQ,QAAQ,CAAA,GAAA,EAAMA,EAAI,OAAA,CAAQ,IAAI,GAAGA,CAAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAAA,CAGrEG,CAAAA,CAAS,MAAMC,CAAAA,CAAoBN,GAAAA,CAAQ,CAC/C,OAAA,CAASE,CAAAA,CAAI,QAAQ,OAAA,CACrB,MAAA,CAAQA,EAAI,OAAA,CAAQ,MAAA,CACpB,IAAAE,CACF,CAAC,EAED,GAAIC,CAAAA,CAAO,KAAA,CAAO,CAChB,IAAME,CAAAA,CAAQ,IAAIC,EAChBH,CAAAA,CAAO,KAAA,CAAM,KACbA,CAAAA,CAAO,KAAA,CAAM,OACf,CAAA,CAEMI,CAAAA,CAAUC,IAAkBH,CAAAA,CAAO,CACvC,MAAON,CAAAA,CAAQ,KAAA,CACf,OAAQ,QACV,CAAC,EAEGA,CAAAA,CAAQ,OAAA,EACVA,EAAQ,OAAA,CAAQI,CAAAA,CAAO,KAAK,CAAA,CAG9BH,CAAAA,CAAI,SAAS,MAAA,CAASG,CAAAA,CAAO,MAAM,UAAA,CACnCH,CAAAA,CAAI,SAAS,GAAA,CAAIO,CAAO,EACxBP,CAAAA,CAAI,QAAA,CAAS,KAAOS,GAAAA,CAAmBJ,CAAK,CAAA,CAC5C,MACF,CAGAL,CAAAA,CAAI,KAAA,CAAM,KAAOG,CAAAA,CAAO,IAAA,CAAK,OAC7BH,CAAAA,CAAI,KAAA,CAAM,cAAgBG,CAAAA,CAAO,IAAA,CAAK,UAEtC,MAAMF,CAAAA,GACR,CACF,CASO,SAASS,CAAAA,CACdZ,CAAAA,CACAa,EAA8B,EAAC,CAC/B,CACA,OAAO,MAAOX,EAAiBC,CAAAA,GAAiC,CAG9D,GAAI,CADeD,CAAAA,CAAI,QAAQ,OAAA,CAAQ,aAAA,CACtB,CACf,MAAMC,CAAAA,GACN,MACF,CAGA,IAAMC,CAAAA,CAAM,CAAA,EAAGF,EAAI,OAAA,CAAQ,QAAQ,MAAMA,CAAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,EAAGA,CAAAA,CAAI,QAAQ,GAAG,CAAA,CAAA,CAGrEG,EAAS,MAAMC,CAAAA,CAAoBN,EAAQ,CAC/C,OAAA,CAASE,EAAI,OAAA,CAAQ,OAAA,CACrB,OAAQA,CAAAA,CAAI,OAAA,CAAQ,OACpB,GAAA,CAAAE,CACF,CAAC,CAAA,CAEGC,CAAAA,CAAO,OACTH,CAAAA,CAAI,KAAA,CAAM,KAAOG,CAAAA,CAAO,IAAA,CAAK,OAC7BH,CAAAA,CAAI,KAAA,CAAM,cAAgBG,CAAAA,CAAO,IAAA,CAAK,WAGxC,MAAMF,CAAAA,GACR,CACF","file":"koa.js","sourcesContent":["/**\r\n * Koa Adapter\r\n *\r\n * Thin wrapper around authenticateRequest for Koa framework.\r\n */\r\n\r\nimport type { AuthrimServer } from '../core/client.js';\r\nimport type { MiddlewareOptions } from '../middleware/types.js';\r\nimport type { ValidatedToken } from '../types/claims.js';\r\nimport { authenticateRequest } from '../middleware/authenticate.js';\r\nimport { buildErrorResponse, buildErrorHeaders } from '../utils/error-response.js';\r\nimport { AuthrimServerError } from '../types/errors.js';\r\n\r\n/**\r\n * Koa state with auth\r\n */\r\nexport interface AuthrimKoaState {\r\n auth?: ValidatedToken;\r\n authTokenType?: 'Bearer' | 'DPoP';\r\n}\r\n\r\n/**\r\n * Koa context type (minimal interface)\r\n */\r\ninterface KoaContext {\r\n request: {\r\n headers: Record<string, string | string[] | undefined>;\r\n method: string;\r\n protocol: string;\r\n host: string;\r\n url: string;\r\n };\r\n response: {\r\n status: number;\r\n set(headers: Record<string, string>): void;\r\n body: unknown;\r\n };\r\n state: AuthrimKoaState;\r\n}\r\n\r\n/**\r\n * Koa next function\r\n */\r\ntype KoaNext = () => Promise<void>;\r\n\r\n/**\r\n * Create Koa middleware for token validation\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param options - Middleware options\r\n * @returns Koa middleware function\r\n *\r\n * @example\r\n * ```typescript\r\n * import Koa from 'koa';\r\n * import { createAuthrimServer } from '@authrim/server';\r\n * import { authrimMiddleware } from '@authrim/server/adapters/koa';\r\n *\r\n * const app = new Koa();\r\n * const server = createAuthrimServer({\r\n * issuer: 'https://auth.example.com',\r\n * audience: 'https://api.example.com',\r\n * });\r\n *\r\n * app.use(authrimMiddleware(server));\r\n *\r\n * app.use((ctx) => {\r\n * ctx.body = { user: ctx.state.auth?.claims.sub };\r\n * });\r\n * ```\r\n */\r\nexport function authrimMiddleware(\r\n server: AuthrimServer,\r\n options: MiddlewareOptions = {}\r\n) {\r\n return async (ctx: KoaContext, next: KoaNext): Promise<void> => {\r\n // Build URL\r\n const url = `${ctx.request.protocol}://${ctx.request.host}${ctx.request.url}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: ctx.request.headers as Record<string, string | string[] | undefined>,\r\n method: ctx.request.method,\r\n url,\r\n });\r\n\r\n if (result.error) {\r\n const error = new AuthrimServerError(\r\n result.error.code as any,\r\n result.error.message\r\n );\r\n\r\n const headers = buildErrorHeaders(error, {\r\n realm: options.realm,\r\n scheme: 'Bearer',\r\n });\r\n\r\n if (options.onError) {\r\n options.onError(result.error);\r\n }\r\n\r\n ctx.response.status = result.error.httpStatus;\r\n ctx.response.set(headers);\r\n ctx.response.body = buildErrorResponse(error);\r\n return;\r\n }\r\n\r\n // Attach auth to state\r\n ctx.state.auth = result.data.claims;\r\n ctx.state.authTokenType = result.data.tokenType;\r\n\r\n await next();\r\n };\r\n}\r\n\r\n/**\r\n * Create optional auth middleware (doesn't fail if no token)\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param _options - Middleware options (unused for optional middleware)\r\n * @returns Koa middleware function\r\n */\r\nexport function authrimOptionalMiddleware(\r\n server: AuthrimServer,\r\n _options: MiddlewareOptions = {}\r\n) {\r\n return async (ctx: KoaContext, next: KoaNext): Promise<void> => {\r\n // Check if Authorization header exists\r\n const authHeader = ctx.request.headers['authorization'];\r\n if (!authHeader) {\r\n await next();\r\n return;\r\n }\r\n\r\n // Build URL\r\n const url = `${ctx.request.protocol}://${ctx.request.host}${ctx.request.url}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: ctx.request.headers as Record<string, string | string[] | undefined>,\r\n method: ctx.request.method,\r\n url,\r\n });\r\n\r\n if (result.data) {\r\n ctx.state.auth = result.data.claims;\r\n ctx.state.authTokenType = result.data.tokenType;\r\n }\r\n\r\n await next();\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';var chunkTPROSFE7_cjs=require('../chunk-TPROSFE7.cjs');function x(o,n,a={}){return class{async canActivate(d){let r=d.switchToHttp().getRequest(),s=r.get("host")??"localhost",i=`${r.protocol}://${s}${r.originalUrl}`,t=await chunkTPROSFE7_cjs.c(o,{headers:r.headers,method:r.method,url:i});if(t.error){let p=new chunkTPROSFE7_cjs.a(t.error.code,t.error.message);throw a.onError&&a.onError(t.error),new n({statusCode:t.error.httpStatus,error:p.meta.wwwAuthenticateError??"Unauthorized",message:t.error.message},t.error.httpStatus)}return r.auth=t.data.claims,r.authTokenType=t.data.tokenType,true}}}function f(o){return o.switchToHttp().getRequest().auth}function w(o){return o.switchToHttp().getRequest().authTokenType}function A(o,n={}){return class{async canActivate(c){let e=c.switchToHttp().getRequest();if(!e.headers.authorization)return true;let s=e.get("host")??"localhost",i=`${e.protocol}://${s}${e.originalUrl}`,t=await chunkTPROSFE7_cjs.c(o,{headers:e.headers,method:e.method,url:i});return t.data&&(e.auth=t.data.claims,e.authTokenType=t.data.tokenType),true}}}
|
|
2
|
+
exports.createAuthrimGuard=x;exports.createAuthrimOptionalGuard=A;exports.getAuthFromRequest=f;exports.getAuthTokenTypeFromRequest=w;//# sourceMappingURL=nestjs.cjs.map
|
|
3
|
+
//# sourceMappingURL=nestjs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/nestjs.ts"],"names":["createAuthrimGuard","server","HttpException","options","context","request","host","url","result","authenticateRequest","error","AuthrimServerError","getAuthFromRequest","getAuthTokenTypeFromRequest","createAuthrimOptionalGuard","_options"],"mappings":"oEA2EO,SAASA,CAAAA,CACdC,EACAC,CAAAA,CACAC,CAAAA,CAA6B,EAAC,CACP,CACvB,OAAO,KAA0C,CAC/C,MAAM,YAAYC,CAAAA,CAA6C,CAE7D,IAAMC,CAAAA,CADcD,CAAAA,CAAQ,cAAa,CACb,UAAA,EAAW,CAGjCE,CAAAA,CAAOD,CAAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAK,WAAA,CAC9BE,EAAM,CAAA,EAAGF,CAAAA,CAAQ,QAAQ,CAAA,GAAA,EAAMC,CAAI,CAAA,EAAGD,CAAAA,CAAQ,WAAW,CAAA,CAAA,CAGzDG,EAAS,MAAMC,mBAAAA,CAAoBR,CAAAA,CAAQ,CAC/C,OAAA,CAASI,CAAAA,CAAQ,QACjB,MAAA,CAAQA,CAAAA,CAAQ,MAAA,CAChB,GAAA,CAAAE,CACF,CAAC,EAED,GAAIC,CAAAA,CAAO,MAAO,CAChB,IAAME,EAAQ,IAAIC,mBAAAA,CAChBH,CAAAA,CAAO,KAAA,CAAM,IAAA,CACbA,CAAAA,CAAO,MAAM,OACf,CAAA,CAEA,MAAIL,CAAAA,CAAQ,OAAA,EACVA,CAAAA,CAAQ,QAAQK,CAAAA,CAAO,KAAK,CAAA,CAGxB,IAAIN,CAAAA,CACR,CACE,WAAYM,CAAAA,CAAO,KAAA,CAAM,WACzB,KAAA,CAAOE,CAAAA,CAAM,KAAK,oBAAA,EAAwB,cAAA,CAC1C,OAAA,CAASF,CAAAA,CAAO,KAAA,CAAM,OACxB,EACAA,CAAAA,CAAO,KAAA,CAAM,UACf,CACF,CAGA,OAAAH,EAAQ,IAAA,CAAOG,CAAAA,CAAO,IAAA,CAAK,MAAA,CAC3BH,CAAAA,CAAQ,aAAA,CAAgBG,EAAO,IAAA,CAAK,SAAA,CAE7B,IACT,CACF,CACF,CAoBO,SAASI,CAAAA,CAAmBR,CAAAA,CAAuD,CAExF,OADgBA,CAAAA,CAAQ,cAAa,CAAE,UAAA,EAAW,CACnC,IACjB,CAKO,SAASS,EACdT,CAAAA,CAC+B,CAE/B,OADgBA,CAAAA,CAAQ,YAAA,EAAa,CAAE,YAAW,CACnC,aACjB,CAgCO,SAASU,CAAAA,CACdb,EACAc,CAAAA,CAA8B,EAAC,CACR,CACvB,OAAO,KAAkD,CACvD,MAAM,WAAA,CAAYX,CAAAA,CAA6C,CAE7D,IAAMC,CAAAA,CADcD,EAAQ,YAAA,EAAa,CACb,UAAA,EAAW,CAIvC,GAAI,CADeC,EAAQ,OAAA,CAAQ,aAAA,CAEjC,OAAO,KAAA,CAIT,IAAMC,EAAOD,CAAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAK,WAAA,CAC9BE,CAAAA,CAAM,GAAGF,CAAAA,CAAQ,QAAQ,CAAA,GAAA,EAAMC,CAAI,CAAA,EAAGD,CAAAA,CAAQ,WAAW,CAAA,CAAA,CAGzDG,CAAAA,CAAS,MAAMC,mBAAAA,CAAoBR,CAAAA,CAAQ,CAC/C,QAASI,CAAAA,CAAQ,OAAA,CACjB,OAAQA,CAAAA,CAAQ,MAAA,CAChB,IAAAE,CACF,CAAC,CAAA,CAED,OAAIC,CAAAA,CAAO,IAAA,GACTH,EAAQ,IAAA,CAAOG,CAAAA,CAAO,IAAA,CAAK,MAAA,CAC3BH,CAAAA,CAAQ,aAAA,CAAgBG,EAAO,IAAA,CAAK,SAAA,CAAA,CAI/B,IACT,CACF,CACF","file":"nestjs.cjs","sourcesContent":["/**\r\n * NestJS Adapter\r\n *\r\n * Guard and decorator for NestJS applications.\r\n */\r\n\r\nimport type { AuthrimServer } from '../core/client.js';\r\nimport type { MiddlewareOptions } from '../middleware/types.js';\r\nimport type { ValidatedToken } from '../types/claims.js';\r\nimport { authenticateRequest } from '../middleware/authenticate.js';\r\nimport { AuthrimServerError } from '../types/errors.js';\r\n\r\n/**\r\n * NestJS ExecutionContext type (minimal interface)\r\n */\r\ninterface ExecutionContext {\r\n switchToHttp(): {\r\n getRequest(): {\r\n headers: Record<string, string | string[] | undefined>;\r\n method: string;\r\n protocol: string;\r\n get(name: string): string | undefined;\r\n originalUrl: string;\r\n auth?: ValidatedToken;\r\n authTokenType?: 'Bearer' | 'DPoP';\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * NestJS CanActivate interface (minimal)\r\n */\r\ninterface CanActivate {\r\n canActivate(context: ExecutionContext): Promise<boolean>;\r\n}\r\n\r\n/**\r\n * NestJS HttpException (minimal interface)\r\n */\r\ninterface HttpExceptionConstructor {\r\n new (response: object, status: number): Error;\r\n}\r\n\r\n/**\r\n * Create NestJS guard factory for token validation\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param httpException - HttpException class from @nestjs/common\r\n * @param options - Middleware options\r\n * @returns NestJS Guard class\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Controller, Get, UseGuards } from '@nestjs/common';\r\n * import { HttpException } from '@nestjs/common';\r\n * import { createAuthrimServer } from '@authrim/server';\r\n * import { createAuthrimGuard, Auth } from '@authrim/server/adapters/nestjs';\r\n *\r\n * const server = createAuthrimServer({\r\n * issuer: 'https://auth.example.com',\r\n * audience: 'https://api.example.com',\r\n * });\r\n *\r\n * const AuthrimGuard = createAuthrimGuard(server, HttpException);\r\n *\r\n * @Controller('api')\r\n * export class AppController {\r\n * @Get('protected')\r\n * @UseGuards(AuthrimGuard)\r\n * getProtected(@Auth() auth: ValidatedToken) {\r\n * return { user: auth.claims.sub };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function createAuthrimGuard(\r\n server: AuthrimServer,\r\n HttpException: HttpExceptionConstructor,\r\n options: MiddlewareOptions = {}\r\n): new () => CanActivate {\r\n return class AuthrimGuard implements CanActivate {\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n const httpContext = context.switchToHttp();\r\n const request = httpContext.getRequest();\r\n\r\n // Build URL\r\n const host = request.get('host') ?? 'localhost';\r\n const url = `${request.protocol}://${host}${request.originalUrl}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: request.headers as Record<string, string | string[] | undefined>,\r\n method: request.method,\r\n url,\r\n });\r\n\r\n if (result.error) {\r\n const error = new AuthrimServerError(\r\n result.error.code as any,\r\n result.error.message\r\n );\r\n\r\n if (options.onError) {\r\n options.onError(result.error);\r\n }\r\n\r\n throw new HttpException(\r\n {\r\n statusCode: result.error.httpStatus,\r\n error: error.meta.wwwAuthenticateError ?? 'Unauthorized',\r\n message: result.error.message,\r\n },\r\n result.error.httpStatus\r\n );\r\n }\r\n\r\n // Attach auth to request\r\n request.auth = result.data.claims;\r\n request.authTokenType = result.data.tokenType;\r\n\r\n return true;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Parameter decorator factory for extracting auth from request\r\n *\r\n * Note: This is a minimal implementation. For full NestJS decorator support,\r\n * you'll need to use @nestjs/common's createParamDecorator.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { createParamDecorator, ExecutionContext } from '@nestjs/common';\r\n * import { getAuthFromRequest } from '@authrim/server/adapters/nestjs';\r\n *\r\n * export const Auth = createParamDecorator(\r\n * (data: unknown, ctx: ExecutionContext) => {\r\n * return getAuthFromRequest(ctx);\r\n * }\r\n * );\r\n * ```\r\n */\r\nexport function getAuthFromRequest(context: ExecutionContext): ValidatedToken | undefined {\r\n const request = context.switchToHttp().getRequest();\r\n return request.auth;\r\n}\r\n\r\n/**\r\n * Get auth token type from request\r\n */\r\nexport function getAuthTokenTypeFromRequest(\r\n context: ExecutionContext\r\n): 'Bearer' | 'DPoP' | undefined {\r\n const request = context.switchToHttp().getRequest();\r\n return request.authTokenType;\r\n}\r\n\r\n/**\r\n * Create optional NestJS guard factory (doesn't fail if no token)\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param _options - Middleware options (unused for optional guard)\r\n * @returns NestJS Guard class that always allows access\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Controller, Get, UseGuards } from '@nestjs/common';\r\n * import { createAuthrimServer } from '@authrim/server';\r\n * import { createAuthrimOptionalGuard, Auth } from '@authrim/server/adapters/nestjs';\r\n *\r\n * const server = createAuthrimServer({\r\n * issuer: 'https://auth.example.com',\r\n * audience: 'https://api.example.com',\r\n * });\r\n *\r\n * const AuthrimOptionalGuard = createAuthrimOptionalGuard(server);\r\n *\r\n * @Controller('api')\r\n * export class AppController {\r\n * @Get('public')\r\n * @UseGuards(AuthrimOptionalGuard)\r\n * getPublic(@Auth() auth: ValidatedToken | undefined) {\r\n * return { user: auth?.claims.sub ?? 'anonymous' };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function createAuthrimOptionalGuard(\r\n server: AuthrimServer,\r\n _options: MiddlewareOptions = {}\r\n): new () => CanActivate {\r\n return class AuthrimOptionalGuard implements CanActivate {\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n const httpContext = context.switchToHttp();\r\n const request = httpContext.getRequest();\r\n\r\n // Check if Authorization header exists\r\n const authHeader = request.headers['authorization'];\r\n if (!authHeader) {\r\n return true;\r\n }\r\n\r\n // Build URL\r\n const host = request.get('host') ?? 'localhost';\r\n const url = `${request.protocol}://${host}${request.originalUrl}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: request.headers as Record<string, string | string[] | undefined>,\r\n method: request.method,\r\n url,\r\n });\r\n\r\n if (result.data) {\r\n request.auth = result.data.claims;\r\n request.authTokenType = result.data.tokenType;\r\n }\r\n\r\n // Always allow access for optional guard\r\n return true;\r\n }\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { A as AuthrimServer, M as MiddlewareOptions, V as ValidatedToken } from '../types-CzpMdWFR.cjs';
|
|
2
|
+
import '../config-I0GIVJA_.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NestJS Adapter
|
|
6
|
+
*
|
|
7
|
+
* Guard and decorator for NestJS applications.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* NestJS ExecutionContext type (minimal interface)
|
|
12
|
+
*/
|
|
13
|
+
interface ExecutionContext {
|
|
14
|
+
switchToHttp(): {
|
|
15
|
+
getRequest(): {
|
|
16
|
+
headers: Record<string, string | string[] | undefined>;
|
|
17
|
+
method: string;
|
|
18
|
+
protocol: string;
|
|
19
|
+
get(name: string): string | undefined;
|
|
20
|
+
originalUrl: string;
|
|
21
|
+
auth?: ValidatedToken;
|
|
22
|
+
authTokenType?: 'Bearer' | 'DPoP';
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* NestJS CanActivate interface (minimal)
|
|
28
|
+
*/
|
|
29
|
+
interface CanActivate {
|
|
30
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* NestJS HttpException (minimal interface)
|
|
34
|
+
*/
|
|
35
|
+
interface HttpExceptionConstructor {
|
|
36
|
+
new (response: object, status: number): Error;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create NestJS guard factory for token validation
|
|
40
|
+
*
|
|
41
|
+
* @param server - AuthrimServer instance
|
|
42
|
+
* @param httpException - HttpException class from @nestjs/common
|
|
43
|
+
* @param options - Middleware options
|
|
44
|
+
* @returns NestJS Guard class
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { Controller, Get, UseGuards } from '@nestjs/common';
|
|
49
|
+
* import { HttpException } from '@nestjs/common';
|
|
50
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
51
|
+
* import { createAuthrimGuard, Auth } from '@authrim/server/adapters/nestjs';
|
|
52
|
+
*
|
|
53
|
+
* const server = createAuthrimServer({
|
|
54
|
+
* issuer: 'https://auth.example.com',
|
|
55
|
+
* audience: 'https://api.example.com',
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const AuthrimGuard = createAuthrimGuard(server, HttpException);
|
|
59
|
+
*
|
|
60
|
+
* @Controller('api')
|
|
61
|
+
* export class AppController {
|
|
62
|
+
* @Get('protected')
|
|
63
|
+
* @UseGuards(AuthrimGuard)
|
|
64
|
+
* getProtected(@Auth() auth: ValidatedToken) {
|
|
65
|
+
* return { user: auth.claims.sub };
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare function createAuthrimGuard(server: AuthrimServer, HttpException: HttpExceptionConstructor, options?: MiddlewareOptions): new () => CanActivate;
|
|
71
|
+
/**
|
|
72
|
+
* Parameter decorator factory for extracting auth from request
|
|
73
|
+
*
|
|
74
|
+
* Note: This is a minimal implementation. For full NestJS decorator support,
|
|
75
|
+
* you'll need to use @nestjs/common's createParamDecorator.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
|
80
|
+
* import { getAuthFromRequest } from '@authrim/server/adapters/nestjs';
|
|
81
|
+
*
|
|
82
|
+
* export const Auth = createParamDecorator(
|
|
83
|
+
* (data: unknown, ctx: ExecutionContext) => {
|
|
84
|
+
* return getAuthFromRequest(ctx);
|
|
85
|
+
* }
|
|
86
|
+
* );
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function getAuthFromRequest(context: ExecutionContext): ValidatedToken | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Get auth token type from request
|
|
92
|
+
*/
|
|
93
|
+
declare function getAuthTokenTypeFromRequest(context: ExecutionContext): 'Bearer' | 'DPoP' | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Create optional NestJS guard factory (doesn't fail if no token)
|
|
96
|
+
*
|
|
97
|
+
* @param server - AuthrimServer instance
|
|
98
|
+
* @param _options - Middleware options (unused for optional guard)
|
|
99
|
+
* @returns NestJS Guard class that always allows access
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { Controller, Get, UseGuards } from '@nestjs/common';
|
|
104
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
105
|
+
* import { createAuthrimOptionalGuard, Auth } from '@authrim/server/adapters/nestjs';
|
|
106
|
+
*
|
|
107
|
+
* const server = createAuthrimServer({
|
|
108
|
+
* issuer: 'https://auth.example.com',
|
|
109
|
+
* audience: 'https://api.example.com',
|
|
110
|
+
* });
|
|
111
|
+
*
|
|
112
|
+
* const AuthrimOptionalGuard = createAuthrimOptionalGuard(server);
|
|
113
|
+
*
|
|
114
|
+
* @Controller('api')
|
|
115
|
+
* export class AppController {
|
|
116
|
+
* @Get('public')
|
|
117
|
+
* @UseGuards(AuthrimOptionalGuard)
|
|
118
|
+
* getPublic(@Auth() auth: ValidatedToken | undefined) {
|
|
119
|
+
* return { user: auth?.claims.sub ?? 'anonymous' };
|
|
120
|
+
* }
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare function createAuthrimOptionalGuard(server: AuthrimServer, _options?: MiddlewareOptions): new () => CanActivate;
|
|
125
|
+
|
|
126
|
+
export { createAuthrimGuard, createAuthrimOptionalGuard, getAuthFromRequest, getAuthTokenTypeFromRequest };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { A as AuthrimServer, M as MiddlewareOptions, V as ValidatedToken } from '../types-D7gjcvs9.js';
|
|
2
|
+
import '../config-I0GIVJA_.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NestJS Adapter
|
|
6
|
+
*
|
|
7
|
+
* Guard and decorator for NestJS applications.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* NestJS ExecutionContext type (minimal interface)
|
|
12
|
+
*/
|
|
13
|
+
interface ExecutionContext {
|
|
14
|
+
switchToHttp(): {
|
|
15
|
+
getRequest(): {
|
|
16
|
+
headers: Record<string, string | string[] | undefined>;
|
|
17
|
+
method: string;
|
|
18
|
+
protocol: string;
|
|
19
|
+
get(name: string): string | undefined;
|
|
20
|
+
originalUrl: string;
|
|
21
|
+
auth?: ValidatedToken;
|
|
22
|
+
authTokenType?: 'Bearer' | 'DPoP';
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* NestJS CanActivate interface (minimal)
|
|
28
|
+
*/
|
|
29
|
+
interface CanActivate {
|
|
30
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* NestJS HttpException (minimal interface)
|
|
34
|
+
*/
|
|
35
|
+
interface HttpExceptionConstructor {
|
|
36
|
+
new (response: object, status: number): Error;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create NestJS guard factory for token validation
|
|
40
|
+
*
|
|
41
|
+
* @param server - AuthrimServer instance
|
|
42
|
+
* @param httpException - HttpException class from @nestjs/common
|
|
43
|
+
* @param options - Middleware options
|
|
44
|
+
* @returns NestJS Guard class
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { Controller, Get, UseGuards } from '@nestjs/common';
|
|
49
|
+
* import { HttpException } from '@nestjs/common';
|
|
50
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
51
|
+
* import { createAuthrimGuard, Auth } from '@authrim/server/adapters/nestjs';
|
|
52
|
+
*
|
|
53
|
+
* const server = createAuthrimServer({
|
|
54
|
+
* issuer: 'https://auth.example.com',
|
|
55
|
+
* audience: 'https://api.example.com',
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const AuthrimGuard = createAuthrimGuard(server, HttpException);
|
|
59
|
+
*
|
|
60
|
+
* @Controller('api')
|
|
61
|
+
* export class AppController {
|
|
62
|
+
* @Get('protected')
|
|
63
|
+
* @UseGuards(AuthrimGuard)
|
|
64
|
+
* getProtected(@Auth() auth: ValidatedToken) {
|
|
65
|
+
* return { user: auth.claims.sub };
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare function createAuthrimGuard(server: AuthrimServer, HttpException: HttpExceptionConstructor, options?: MiddlewareOptions): new () => CanActivate;
|
|
71
|
+
/**
|
|
72
|
+
* Parameter decorator factory for extracting auth from request
|
|
73
|
+
*
|
|
74
|
+
* Note: This is a minimal implementation. For full NestJS decorator support,
|
|
75
|
+
* you'll need to use @nestjs/common's createParamDecorator.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
|
80
|
+
* import { getAuthFromRequest } from '@authrim/server/adapters/nestjs';
|
|
81
|
+
*
|
|
82
|
+
* export const Auth = createParamDecorator(
|
|
83
|
+
* (data: unknown, ctx: ExecutionContext) => {
|
|
84
|
+
* return getAuthFromRequest(ctx);
|
|
85
|
+
* }
|
|
86
|
+
* );
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function getAuthFromRequest(context: ExecutionContext): ValidatedToken | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Get auth token type from request
|
|
92
|
+
*/
|
|
93
|
+
declare function getAuthTokenTypeFromRequest(context: ExecutionContext): 'Bearer' | 'DPoP' | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Create optional NestJS guard factory (doesn't fail if no token)
|
|
96
|
+
*
|
|
97
|
+
* @param server - AuthrimServer instance
|
|
98
|
+
* @param _options - Middleware options (unused for optional guard)
|
|
99
|
+
* @returns NestJS Guard class that always allows access
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { Controller, Get, UseGuards } from '@nestjs/common';
|
|
104
|
+
* import { createAuthrimServer } from '@authrim/server';
|
|
105
|
+
* import { createAuthrimOptionalGuard, Auth } from '@authrim/server/adapters/nestjs';
|
|
106
|
+
*
|
|
107
|
+
* const server = createAuthrimServer({
|
|
108
|
+
* issuer: 'https://auth.example.com',
|
|
109
|
+
* audience: 'https://api.example.com',
|
|
110
|
+
* });
|
|
111
|
+
*
|
|
112
|
+
* const AuthrimOptionalGuard = createAuthrimOptionalGuard(server);
|
|
113
|
+
*
|
|
114
|
+
* @Controller('api')
|
|
115
|
+
* export class AppController {
|
|
116
|
+
* @Get('public')
|
|
117
|
+
* @UseGuards(AuthrimOptionalGuard)
|
|
118
|
+
* getPublic(@Auth() auth: ValidatedToken | undefined) {
|
|
119
|
+
* return { user: auth?.claims.sub ?? 'anonymous' };
|
|
120
|
+
* }
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare function createAuthrimOptionalGuard(server: AuthrimServer, _options?: MiddlewareOptions): new () => CanActivate;
|
|
125
|
+
|
|
126
|
+
export { createAuthrimGuard, createAuthrimOptionalGuard, getAuthFromRequest, getAuthTokenTypeFromRequest };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {c,a}from'../chunk-N3ONRO35.js';function x(o,n,a$1={}){return class{async canActivate(d){let r=d.switchToHttp().getRequest(),s=r.get("host")??"localhost",i=`${r.protocol}://${s}${r.originalUrl}`,t=await c(o,{headers:r.headers,method:r.method,url:i});if(t.error){let p=new a(t.error.code,t.error.message);throw a$1.onError&&a$1.onError(t.error),new n({statusCode:t.error.httpStatus,error:p.meta.wwwAuthenticateError??"Unauthorized",message:t.error.message},t.error.httpStatus)}return r.auth=t.data.claims,r.authTokenType=t.data.tokenType,true}}}function f(o){return o.switchToHttp().getRequest().auth}function w(o){return o.switchToHttp().getRequest().authTokenType}function A(o,n={}){return class{async canActivate(c$1){let e=c$1.switchToHttp().getRequest();if(!e.headers.authorization)return true;let s=e.get("host")??"localhost",i=`${e.protocol}://${s}${e.originalUrl}`,t=await c(o,{headers:e.headers,method:e.method,url:i});return t.data&&(e.auth=t.data.claims,e.authTokenType=t.data.tokenType),true}}}
|
|
2
|
+
export{x as createAuthrimGuard,A as createAuthrimOptionalGuard,f as getAuthFromRequest,w as getAuthTokenTypeFromRequest};//# sourceMappingURL=nestjs.js.map
|
|
3
|
+
//# sourceMappingURL=nestjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/nestjs.ts"],"names":["createAuthrimGuard","server","HttpException","options","context","request","host","url","result","authenticateRequest","error","AuthrimServerError","getAuthFromRequest","getAuthTokenTypeFromRequest","createAuthrimOptionalGuard","_options"],"mappings":"uCA2EO,SAASA,CAAAA,CACdC,EACAC,CAAAA,CACAC,GAAAA,CAA6B,EAAC,CACP,CACvB,OAAO,KAA0C,CAC/C,MAAM,YAAYC,CAAAA,CAA6C,CAE7D,IAAMC,CAAAA,CADcD,CAAAA,CAAQ,cAAa,CACb,UAAA,EAAW,CAGjCE,CAAAA,CAAOD,CAAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAK,WAAA,CAC9BE,EAAM,CAAA,EAAGF,CAAAA,CAAQ,QAAQ,CAAA,GAAA,EAAMC,CAAI,CAAA,EAAGD,CAAAA,CAAQ,WAAW,CAAA,CAAA,CAGzDG,EAAS,MAAMC,CAAAA,CAAoBR,CAAAA,CAAQ,CAC/C,OAAA,CAASI,CAAAA,CAAQ,QACjB,MAAA,CAAQA,CAAAA,CAAQ,MAAA,CAChB,GAAA,CAAAE,CACF,CAAC,EAED,GAAIC,CAAAA,CAAO,MAAO,CAChB,IAAME,EAAQ,IAAIC,CAAAA,CAChBH,CAAAA,CAAO,KAAA,CAAM,IAAA,CACbA,CAAAA,CAAO,MAAM,OACf,CAAA,CAEA,MAAIL,GAAAA,CAAQ,OAAA,EACVA,GAAAA,CAAQ,QAAQK,CAAAA,CAAO,KAAK,CAAA,CAGxB,IAAIN,CAAAA,CACR,CACE,WAAYM,CAAAA,CAAO,KAAA,CAAM,WACzB,KAAA,CAAOE,CAAAA,CAAM,KAAK,oBAAA,EAAwB,cAAA,CAC1C,OAAA,CAASF,CAAAA,CAAO,KAAA,CAAM,OACxB,EACAA,CAAAA,CAAO,KAAA,CAAM,UACf,CACF,CAGA,OAAAH,EAAQ,IAAA,CAAOG,CAAAA,CAAO,IAAA,CAAK,MAAA,CAC3BH,CAAAA,CAAQ,aAAA,CAAgBG,EAAO,IAAA,CAAK,SAAA,CAE7B,IACT,CACF,CACF,CAoBO,SAASI,CAAAA,CAAmBR,CAAAA,CAAuD,CAExF,OADgBA,CAAAA,CAAQ,cAAa,CAAE,UAAA,EAAW,CACnC,IACjB,CAKO,SAASS,EACdT,CAAAA,CAC+B,CAE/B,OADgBA,CAAAA,CAAQ,YAAA,EAAa,CAAE,YAAW,CACnC,aACjB,CAgCO,SAASU,CAAAA,CACdb,EACAc,CAAAA,CAA8B,EAAC,CACR,CACvB,OAAO,KAAkD,CACvD,MAAM,WAAA,CAAYX,GAAAA,CAA6C,CAE7D,IAAMC,CAAAA,CADcD,IAAQ,YAAA,EAAa,CACb,UAAA,EAAW,CAIvC,GAAI,CADeC,EAAQ,OAAA,CAAQ,aAAA,CAEjC,OAAO,KAAA,CAIT,IAAMC,EAAOD,CAAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAK,WAAA,CAC9BE,CAAAA,CAAM,GAAGF,CAAAA,CAAQ,QAAQ,CAAA,GAAA,EAAMC,CAAI,CAAA,EAAGD,CAAAA,CAAQ,WAAW,CAAA,CAAA,CAGzDG,CAAAA,CAAS,MAAMC,CAAAA,CAAoBR,CAAAA,CAAQ,CAC/C,QAASI,CAAAA,CAAQ,OAAA,CACjB,OAAQA,CAAAA,CAAQ,MAAA,CAChB,IAAAE,CACF,CAAC,CAAA,CAED,OAAIC,CAAAA,CAAO,IAAA,GACTH,EAAQ,IAAA,CAAOG,CAAAA,CAAO,IAAA,CAAK,MAAA,CAC3BH,CAAAA,CAAQ,aAAA,CAAgBG,EAAO,IAAA,CAAK,SAAA,CAAA,CAI/B,IACT,CACF,CACF","file":"nestjs.js","sourcesContent":["/**\r\n * NestJS Adapter\r\n *\r\n * Guard and decorator for NestJS applications.\r\n */\r\n\r\nimport type { AuthrimServer } from '../core/client.js';\r\nimport type { MiddlewareOptions } from '../middleware/types.js';\r\nimport type { ValidatedToken } from '../types/claims.js';\r\nimport { authenticateRequest } from '../middleware/authenticate.js';\r\nimport { AuthrimServerError } from '../types/errors.js';\r\n\r\n/**\r\n * NestJS ExecutionContext type (minimal interface)\r\n */\r\ninterface ExecutionContext {\r\n switchToHttp(): {\r\n getRequest(): {\r\n headers: Record<string, string | string[] | undefined>;\r\n method: string;\r\n protocol: string;\r\n get(name: string): string | undefined;\r\n originalUrl: string;\r\n auth?: ValidatedToken;\r\n authTokenType?: 'Bearer' | 'DPoP';\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * NestJS CanActivate interface (minimal)\r\n */\r\ninterface CanActivate {\r\n canActivate(context: ExecutionContext): Promise<boolean>;\r\n}\r\n\r\n/**\r\n * NestJS HttpException (minimal interface)\r\n */\r\ninterface HttpExceptionConstructor {\r\n new (response: object, status: number): Error;\r\n}\r\n\r\n/**\r\n * Create NestJS guard factory for token validation\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param httpException - HttpException class from @nestjs/common\r\n * @param options - Middleware options\r\n * @returns NestJS Guard class\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Controller, Get, UseGuards } from '@nestjs/common';\r\n * import { HttpException } from '@nestjs/common';\r\n * import { createAuthrimServer } from '@authrim/server';\r\n * import { createAuthrimGuard, Auth } from '@authrim/server/adapters/nestjs';\r\n *\r\n * const server = createAuthrimServer({\r\n * issuer: 'https://auth.example.com',\r\n * audience: 'https://api.example.com',\r\n * });\r\n *\r\n * const AuthrimGuard = createAuthrimGuard(server, HttpException);\r\n *\r\n * @Controller('api')\r\n * export class AppController {\r\n * @Get('protected')\r\n * @UseGuards(AuthrimGuard)\r\n * getProtected(@Auth() auth: ValidatedToken) {\r\n * return { user: auth.claims.sub };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function createAuthrimGuard(\r\n server: AuthrimServer,\r\n HttpException: HttpExceptionConstructor,\r\n options: MiddlewareOptions = {}\r\n): new () => CanActivate {\r\n return class AuthrimGuard implements CanActivate {\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n const httpContext = context.switchToHttp();\r\n const request = httpContext.getRequest();\r\n\r\n // Build URL\r\n const host = request.get('host') ?? 'localhost';\r\n const url = `${request.protocol}://${host}${request.originalUrl}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: request.headers as Record<string, string | string[] | undefined>,\r\n method: request.method,\r\n url,\r\n });\r\n\r\n if (result.error) {\r\n const error = new AuthrimServerError(\r\n result.error.code as any,\r\n result.error.message\r\n );\r\n\r\n if (options.onError) {\r\n options.onError(result.error);\r\n }\r\n\r\n throw new HttpException(\r\n {\r\n statusCode: result.error.httpStatus,\r\n error: error.meta.wwwAuthenticateError ?? 'Unauthorized',\r\n message: result.error.message,\r\n },\r\n result.error.httpStatus\r\n );\r\n }\r\n\r\n // Attach auth to request\r\n request.auth = result.data.claims;\r\n request.authTokenType = result.data.tokenType;\r\n\r\n return true;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Parameter decorator factory for extracting auth from request\r\n *\r\n * Note: This is a minimal implementation. For full NestJS decorator support,\r\n * you'll need to use @nestjs/common's createParamDecorator.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { createParamDecorator, ExecutionContext } from '@nestjs/common';\r\n * import { getAuthFromRequest } from '@authrim/server/adapters/nestjs';\r\n *\r\n * export const Auth = createParamDecorator(\r\n * (data: unknown, ctx: ExecutionContext) => {\r\n * return getAuthFromRequest(ctx);\r\n * }\r\n * );\r\n * ```\r\n */\r\nexport function getAuthFromRequest(context: ExecutionContext): ValidatedToken | undefined {\r\n const request = context.switchToHttp().getRequest();\r\n return request.auth;\r\n}\r\n\r\n/**\r\n * Get auth token type from request\r\n */\r\nexport function getAuthTokenTypeFromRequest(\r\n context: ExecutionContext\r\n): 'Bearer' | 'DPoP' | undefined {\r\n const request = context.switchToHttp().getRequest();\r\n return request.authTokenType;\r\n}\r\n\r\n/**\r\n * Create optional NestJS guard factory (doesn't fail if no token)\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param _options - Middleware options (unused for optional guard)\r\n * @returns NestJS Guard class that always allows access\r\n *\r\n * @example\r\n * ```typescript\r\n * import { Controller, Get, UseGuards } from '@nestjs/common';\r\n * import { createAuthrimServer } from '@authrim/server';\r\n * import { createAuthrimOptionalGuard, Auth } from '@authrim/server/adapters/nestjs';\r\n *\r\n * const server = createAuthrimServer({\r\n * issuer: 'https://auth.example.com',\r\n * audience: 'https://api.example.com',\r\n * });\r\n *\r\n * const AuthrimOptionalGuard = createAuthrimOptionalGuard(server);\r\n *\r\n * @Controller('api')\r\n * export class AppController {\r\n * @Get('public')\r\n * @UseGuards(AuthrimOptionalGuard)\r\n * getPublic(@Auth() auth: ValidatedToken | undefined) {\r\n * return { user: auth?.claims.sub ?? 'anonymous' };\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function createAuthrimOptionalGuard(\r\n server: AuthrimServer,\r\n _options: MiddlewareOptions = {}\r\n): new () => CanActivate {\r\n return class AuthrimOptionalGuard implements CanActivate {\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n const httpContext = context.switchToHttp();\r\n const request = httpContext.getRequest();\r\n\r\n // Check if Authorization header exists\r\n const authHeader = request.headers['authorization'];\r\n if (!authHeader) {\r\n return true;\r\n }\r\n\r\n // Build URL\r\n const host = request.get('host') ?? 'localhost';\r\n const url = `${request.protocol}://${host}${request.originalUrl}`;\r\n\r\n // Authenticate\r\n const result = await authenticateRequest(server, {\r\n headers: request.headers as Record<string, string | string[] | undefined>,\r\n method: request.method,\r\n url,\r\n });\r\n\r\n if (result.data) {\r\n request.auth = result.data.claims;\r\n request.authTokenType = result.data.tokenType;\r\n }\r\n\r\n // Always allow access for optional guard\r\n return true;\r\n }\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';function S(){return {fetch(e,t){return globalThis.fetch(e,t)}}}function f(e){let t;if(typeof Buffer<"u")t=Buffer.from(e).toString("base64");else {let n=Array.from(e).map(r=>String.fromCharCode(r)).join("");t=btoa(n);}return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function p(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=(4-t.length%4)%4;if(t+="=".repeat(n),typeof Buffer<"u")return new Uint8Array(Buffer.from(t,"base64"));{let r=atob(t),i=new Uint8Array(r.length);for(let o=0;o<r.length;o++)i[o]=r.charCodeAt(o);return i}}function A(e){return f(new TextEncoder().encode(e))}function g(e){return new TextDecoder().decode(p(e))}var d={RS256:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},RS384:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-384"},RS512:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},PS256:{name:"RSA-PSS",hash:"SHA-256"},PS384:{name:"RSA-PSS",hash:"SHA-384"},PS512:{name:"RSA-PSS",hash:"SHA-512"},ES256:{name:"ECDSA",namedCurve:"P-256"},ES384:{name:"ECDSA",namedCurve:"P-384"},ES512:{name:"ECDSA",namedCurve:"P-521"}};function h(e){let t=d[e];if(!t)throw new Error(`Unsupported algorithm: ${e}`);return e.startsWith("PS")?{name:"RSA-PSS",saltLength:{PS256:32,PS384:48,PS512:64}[e]??32}:e.startsWith("ES")?{name:"ECDSA",hash:{ES256:"SHA-256",ES384:"SHA-384",ES512:"SHA-512"}[e]??"SHA-256"}:t}function y(e){let t=e.kty;switch(t){case "RSA":return {e:e.e,kty:e.kty,n:e.n};case "EC":return {crv:e.crv,kty:e.kty,x:e.x,y:e.y};case "OKP":return {crv:e.crv,kty:e.kty,x:e.x};default:throw new Error(`Unsupported key type for thumbprint: ${t}`)}}function P(){let e=globalThis.crypto;return {async verifySignature(t,n,r,i){let o=h(t);return e.subtle.verify(o,n,r,i)},async importJwk(t,n){let r=d[n];if(!r)throw new Error(`Unsupported algorithm: ${n}`);return e.subtle.importKey("jwk",t,r,true,["verify"])},async sha256(t){let n=typeof t=="string"?new TextEncoder().encode(t):t,r=await e.subtle.digest("SHA-256",n);return new Uint8Array(r)},async calculateThumbprint(t){let n=y(t),r=JSON.stringify(n,Object.keys(n).sort()),i=await this.sha256(r);return f(i)}}}function x(){return {nowSeconds(){return Math.floor(Date.now()/1e3)},nowMs(){return Date.now()}}}function w(e={}){let{ttlMs:t=36e5,maxSize:n=1e3}=e,r=new Map;function i(){let o=Date.now(),s=[];for(let[a,c]of r.entries())c.expiresAt<=o&&s.push(a);for(let a of s)r.delete(a);if(r.size>n){let a=r.size-n,c=r.keys();for(let u=0;u<a;u++){let m=c.next();m.done||r.delete(m.value);}}}return {get(o){let s=r.get(o);if(s){if(s.expiresAt<=Date.now()){r.delete(o);return}return r.delete(o),r.set(o,s),s.value}},set(o,s,a){if(r.has(o))r.delete(o);else if(r.size>=n&&(i(),r.size>=n)){let u=r.keys().next().value;u!==void 0&&r.delete(u);}let c=Date.now()+(a??t);r.set(o,{value:s,expiresAt:c});},delete(o){r.delete(o);},clear(){r.clear();}}}
|
|
2
|
+
exports.a=S;exports.b=f;exports.c=p;exports.d=A;exports.e=g;exports.f=P;exports.g=x;exports.h=w;//# sourceMappingURL=chunk-7POGA5LZ.cjs.map
|
|
3
|
+
//# sourceMappingURL=chunk-7POGA5LZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers-impl/fetch-http.ts","../src/utils/base64url.ts","../src/providers-impl/web-crypto.ts","../src/providers-impl/system-clock.ts","../src/providers-impl/memory-cache.ts"],"names":["fetchHttpProvider","input","init","base64UrlEncode","data","base64","binary","byte","base64UrlDecode","str","paddingNeeded","bytes","i","base64UrlEncodeString","base64UrlDecodeString","ALGORITHM_PARAMS","getVerifyParams","alg","params","getThumbprintMembers","jwk","kty","webCryptoProvider","crypto","key","signature","hash","members","json","systemClock","memoryCache","options","ttlMs","maxSize","cache","cleanup","now","keysToDelete","entry","excess","keysIterator","result","value","entryTtlMs","oldestKey","expiresAt"],"mappings":"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","file":"chunk-7POGA5LZ.cjs","sourcesContent":["/**\r\n * Fetch-based HTTP Provider Implementation\r\n *\r\n * Uses globalThis.fetch for maximum runtime compatibility.\r\n */\r\n\r\nimport type { HttpProvider } from '../providers/http.js';\r\n\r\n/**\r\n * Create a fetch-based HTTP provider\r\n *\r\n * This implementation uses the global fetch API which is available in:\r\n * - Node.js 18+\r\n * - Bun\r\n * - Deno\r\n * - Cloudflare Workers\r\n * - Vercel Edge Functions\r\n * - All modern browsers\r\n *\r\n * @returns HttpProvider implementation\r\n */\r\nexport function fetchHttpProvider(): HttpProvider {\r\n return {\r\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\r\n return globalThis.fetch(input, init);\r\n },\r\n };\r\n}\r\n","/**\r\n * Base64URL Encoding/Decoding Utilities\r\n *\r\n * RFC 4648 Section 5 - Base64 Encoding with URL and Filename Safe Alphabet\r\n */\r\n\r\n/**\r\n * Encode bytes to base64url string\r\n *\r\n * @param data - Bytes to encode\r\n * @returns Base64url-encoded string (no padding)\r\n */\r\nexport function base64UrlEncode(data: Uint8Array): string {\r\n // Convert to base64\r\n let base64: string;\r\n if (typeof Buffer !== 'undefined') {\r\n // Node.js\r\n base64 = Buffer.from(data).toString('base64');\r\n } else {\r\n // Browser/Edge runtime\r\n const binary = Array.from(data)\r\n .map((byte) => String.fromCharCode(byte))\r\n .join('');\r\n base64 = btoa(binary);\r\n }\r\n\r\n // Convert to base64url (replace + with -, / with _, remove padding)\r\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\r\n}\r\n\r\n/**\r\n * Decode base64url string to bytes\r\n *\r\n * @param str - Base64url-encoded string\r\n * @returns Decoded bytes\r\n */\r\nexport function base64UrlDecode(str: string): Uint8Array {\r\n // Convert from base64url to base64\r\n let base64 = str.replace(/-/g, '+').replace(/_/g, '/');\r\n\r\n // Add padding if needed\r\n const paddingNeeded = (4 - (base64.length % 4)) % 4;\r\n base64 += '='.repeat(paddingNeeded);\r\n\r\n // Decode\r\n if (typeof Buffer !== 'undefined') {\r\n // Node.js\r\n return new Uint8Array(Buffer.from(base64, 'base64'));\r\n } else {\r\n // Browser/Edge runtime\r\n const binary = atob(base64);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i++) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n return bytes;\r\n }\r\n}\r\n\r\n/**\r\n * Encode string to base64url\r\n *\r\n * @param str - String to encode (UTF-8)\r\n * @returns Base64url-encoded string\r\n */\r\nexport function base64UrlEncodeString(str: string): string {\r\n return base64UrlEncode(new TextEncoder().encode(str));\r\n}\r\n\r\n/**\r\n * Decode base64url to string\r\n *\r\n * @param str - Base64url-encoded string\r\n * @returns Decoded string (UTF-8)\r\n */\r\nexport function base64UrlDecodeString(str: string): string {\r\n return new TextDecoder().decode(base64UrlDecode(str));\r\n}\r\n","/**\r\n * Web Crypto API Provider Implementation\r\n *\r\n * Uses crypto.subtle for cryptographic operations.\r\n */\r\n\r\nimport type { CryptoProvider } from '../providers/crypto.js';\r\nimport { base64UrlEncode } from '../utils/base64url.js';\r\n\r\n/**\r\n * Algorithm parameters mapping\r\n */\r\nconst ALGORITHM_PARAMS: Record<string, AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams> = {\r\n // RSA PKCS#1 v1.5\r\n RS256: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },\r\n RS384: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-384' },\r\n RS512: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' },\r\n // RSA-PSS\r\n PS256: { name: 'RSA-PSS', hash: 'SHA-256' },\r\n PS384: { name: 'RSA-PSS', hash: 'SHA-384' },\r\n PS512: { name: 'RSA-PSS', hash: 'SHA-512' },\r\n // ECDSA\r\n ES256: { name: 'ECDSA', namedCurve: 'P-256' },\r\n ES384: { name: 'ECDSA', namedCurve: 'P-384' },\r\n ES512: { name: 'ECDSA', namedCurve: 'P-521' },\r\n};\r\n\r\n/**\r\n * Get verification algorithm parameters\r\n */\r\nfunction getVerifyParams(alg: string): AlgorithmIdentifier | RsaPssParams | EcdsaParams {\r\n const params = ALGORITHM_PARAMS[alg];\r\n if (!params) {\r\n throw new Error(`Unsupported algorithm: ${alg}`);\r\n }\r\n\r\n if (alg.startsWith('PS')) {\r\n // RSA-PSS requires salt length\r\n const hashLength = { PS256: 32, PS384: 48, PS512: 64 }[alg] ?? 32;\r\n return { name: 'RSA-PSS', saltLength: hashLength };\r\n }\r\n\r\n if (alg.startsWith('ES')) {\r\n const hashName = { ES256: 'SHA-256', ES384: 'SHA-384', ES512: 'SHA-512' }[alg] ?? 'SHA-256';\r\n return { name: 'ECDSA', hash: hashName };\r\n }\r\n\r\n return params;\r\n}\r\n\r\n/**\r\n * Get required key members for thumbprint calculation (RFC 7638)\r\n */\r\nfunction getThumbprintMembers(jwk: JsonWebKey): Record<string, unknown> {\r\n const kty = jwk.kty;\r\n\r\n switch (kty) {\r\n case 'RSA':\r\n return { e: jwk.e, kty: jwk.kty, n: jwk.n };\r\n case 'EC':\r\n return { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };\r\n case 'OKP':\r\n return { crv: jwk.crv, kty: jwk.kty, x: jwk.x };\r\n default:\r\n throw new Error(`Unsupported key type for thumbprint: ${kty}`);\r\n }\r\n}\r\n\r\n/**\r\n * Create a Web Crypto API-based crypto provider\r\n *\r\n * This implementation uses crypto.subtle which is available in:\r\n * - Node.js 18+\r\n * - Bun\r\n * - Deno\r\n * - Cloudflare Workers\r\n * - Vercel Edge Functions\r\n * - All modern browsers\r\n *\r\n * @returns CryptoProvider implementation\r\n */\r\nexport function webCryptoProvider(): CryptoProvider {\r\n const crypto = globalThis.crypto;\r\n\r\n return {\r\n async verifySignature(\r\n alg: string,\r\n key: CryptoKey,\r\n signature: Uint8Array,\r\n data: Uint8Array\r\n ): Promise<boolean> {\r\n const params = getVerifyParams(alg);\r\n return crypto.subtle.verify(params, key, signature as BufferSource, data as BufferSource);\r\n },\r\n\r\n async importJwk(jwk: JsonWebKey, alg: string): Promise<CryptoKey> {\r\n const params = ALGORITHM_PARAMS[alg];\r\n if (!params) {\r\n throw new Error(`Unsupported algorithm: ${alg}`);\r\n }\r\n return crypto.subtle.importKey('jwk', jwk, params, true, ['verify']);\r\n },\r\n\r\n async sha256(data: string | Uint8Array): Promise<Uint8Array> {\r\n const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;\r\n const hash = await crypto.subtle.digest('SHA-256', bytes as BufferSource);\r\n return new Uint8Array(hash);\r\n },\r\n\r\n async calculateThumbprint(jwk: JsonWebKey): Promise<string> {\r\n // Get required members in lexicographic order (RFC 7638)\r\n const members = getThumbprintMembers(jwk);\r\n const json = JSON.stringify(members, Object.keys(members).sort());\r\n const hash = await this.sha256(json);\r\n return base64UrlEncode(hash);\r\n },\r\n };\r\n}\r\n","/**\r\n * System Clock Provider Implementation\r\n *\r\n * Uses Date.now() for time operations.\r\n */\r\n\r\nimport type { ClockProvider } from '../providers/clock.js';\r\n\r\n/**\r\n * Create a system clock provider\r\n *\r\n * Uses Date.now() which is available in all JavaScript runtimes.\r\n *\r\n * @returns ClockProvider implementation\r\n */\r\nexport function systemClock(): ClockProvider {\r\n return {\r\n nowSeconds(): number {\r\n return Math.floor(Date.now() / 1000);\r\n },\r\n\r\n nowMs(): number {\r\n return Date.now();\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create a mock clock provider for testing\r\n *\r\n * @param initialTime - Initial time in milliseconds\r\n * @returns ClockProvider with time control methods\r\n */\r\nexport function mockClock(\r\n initialTime: number = Date.now()\r\n): ClockProvider & { advance(ms: number): void; setTime(ms: number): void } {\r\n let currentTime = initialTime;\r\n\r\n return {\r\n nowSeconds(): number {\r\n return Math.floor(currentTime / 1000);\r\n },\r\n\r\n nowMs(): number {\r\n return currentTime;\r\n },\r\n\r\n advance(ms: number): void {\r\n currentTime += ms;\r\n },\r\n\r\n setTime(ms: number): void {\r\n currentTime = ms;\r\n },\r\n };\r\n}\r\n","/**\r\n * In-Memory Cache Provider Implementation\r\n *\r\n * Simple TTL-based cache with optional size limits.\r\n */\r\n\r\nimport type { CacheProvider } from '../providers/cache.js';\r\nimport type { MemoryCacheOptions } from '../types/config.js';\r\n\r\n/**\r\n * Cache entry with expiration\r\n */\r\ninterface CacheEntry<T> {\r\n value: T;\r\n expiresAt: number;\r\n}\r\n\r\n/**\r\n * Create an in-memory cache provider\r\n *\r\n * Features:\r\n * - TTL-based expiration\r\n * - Optional size limits with LRU eviction\r\n * - Lazy cleanup on access\r\n *\r\n * @param options - Cache configuration options\r\n * @returns CacheProvider implementation\r\n */\r\nexport function memoryCache<T>(options: MemoryCacheOptions = {}): CacheProvider<T> {\r\n const { ttlMs = 3600_000, maxSize = 1000 } = options;\r\n const cache = new Map<string, CacheEntry<T>>();\r\n\r\n /**\r\n * Remove expired entries and enforce size limit\r\n */\r\n function cleanup(): void {\r\n const now = Date.now();\r\n const keysToDelete: string[] = [];\r\n\r\n for (const [key, entry] of cache.entries()) {\r\n if (entry.expiresAt <= now) {\r\n keysToDelete.push(key);\r\n }\r\n }\r\n\r\n for (const key of keysToDelete) {\r\n cache.delete(key);\r\n }\r\n\r\n // Enforce max size (LRU: oldest entries first in Map iteration order)\r\n if (cache.size > maxSize) {\r\n const excess = cache.size - maxSize;\r\n const keysIterator = cache.keys();\r\n for (let i = 0; i < excess; i++) {\r\n const result = keysIterator.next();\r\n if (!result.done) {\r\n cache.delete(result.value);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n get(key: string): T | undefined {\r\n const entry = cache.get(key);\r\n if (!entry) {\r\n return undefined;\r\n }\r\n\r\n // Check expiration\r\n if (entry.expiresAt <= Date.now()) {\r\n cache.delete(key);\r\n return undefined;\r\n }\r\n\r\n // Move to end for LRU\r\n cache.delete(key);\r\n cache.set(key, entry);\r\n\r\n return entry.value;\r\n },\r\n\r\n set(key: string, value: T, entryTtlMs?: number): void {\r\n // If key already exists, just update it\r\n if (cache.has(key)) {\r\n cache.delete(key); // Remove to reset LRU position\r\n } else if (cache.size >= maxSize) {\r\n // Need to make room for new entry\r\n cleanup();\r\n // If still at max after cleanup, remove oldest\r\n if (cache.size >= maxSize) {\r\n const oldestKey = cache.keys().next().value;\r\n if (oldestKey !== undefined) {\r\n cache.delete(oldestKey);\r\n }\r\n }\r\n }\r\n\r\n const expiresAt = Date.now() + (entryTtlMs ?? ttlMs);\r\n cache.set(key, { value, expiresAt });\r\n },\r\n\r\n delete(key: string): void {\r\n cache.delete(key);\r\n },\r\n\r\n clear(): void {\r\n cache.clear();\r\n },\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var u=class extends Error{constructor(t,a,e){super(a),this.name="AuthrimServerError",this.code=t,this.details=e?.details,this.cause=e?.cause;}get meta(){return c(this.code)}},h={invalid_token:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},token_expired:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},token_not_yet_valid:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},token_malformed:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},signature_invalid:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},algorithm_mismatch:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},invalid_issuer:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},invalid_audience:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},jwks_fetch_error:{httpStatus:503,transient:true,retryable:true},jwks_key_not_found:{httpStatus:401,transient:true,retryable:true,wwwAuthenticateError:"invalid_token"},jwks_key_ambiguous:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},jwks_key_import_error:{httpStatus:500,transient:false,retryable:false},dpop_proof_missing:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_proof_invalid:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_proof_signature_invalid:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_method_mismatch:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_uri_mismatch:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_ath_mismatch:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_binding_mismatch:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_iat_expired:{httpStatus:401,transient:false,retryable:false,wwwAuthenticateError:"invalid_token"},dpop_nonce_required:{httpStatus:401,transient:true,retryable:true,wwwAuthenticateError:"use_dpop_nonce"},introspection_error:{httpStatus:503,transient:true,retryable:true},revocation_error:{httpStatus:503,transient:true,retryable:true},configuration_error:{httpStatus:500,transient:false,retryable:false},provider_error:{httpStatus:500,transient:false,retryable:false},network_error:{httpStatus:503,transient:true,retryable:true},timeout_error:{httpStatus:504,transient:true,retryable:true}};function c(r){return h[r]}function _(r,t){let a=t.toLowerCase();for(let[e,n]of Object.entries(r))if(e.toLowerCase()===a)return Array.isArray(n)?n[0]:n}function f(r){if(!r)return null;let t=r.split(" ");if(t.length!==2)return null;let[a,e]=t;if(!a||!e)return null;let n=a.toLowerCase();return n==="bearer"?{scheme:"Bearer",token:e}:n==="dpop"?{scheme:"DPoP",token:e}:null}async function v(r,t){let a=_(t.headers,"Authorization"),e=f(a);if(!e)return {data:null,error:{code:"invalid_token",message:"Missing or invalid Authorization header",httpStatus:401}};let{scheme:n,token:d}=e,o=await r.validateToken(d);if(o.error){let s=new u(o.error.code,o.error.message).meta;return {data:null,error:{code:o.error.code,message:o.error.message,httpStatus:s.httpStatus}}}let i=o.data;if(!i)return {data:null,error:{code:"invalid_token",message:"Token validation failed",httpStatus:401}};let p=i.claims.cnf?.jkt!==void 0;if(n==="DPoP"||p){let s=_(t.headers,"DPoP");if(!s)return {data:null,error:{code:"dpop_proof_missing",message:"DPoP proof required but not provided",httpStatus:401}};let l=await r.validateDPoP(s,{method:t.method,uri:t.url,accessToken:d,expectedThumbprint:i.claims.cnf?.jkt});if(!l.valid)return {data:null,error:{code:l.errorCode??"dpop_proof_invalid",message:l.errorMessage??"Invalid DPoP proof",httpStatus:401}}}return {data:{claims:i,tokenType:p?"DPoP":"Bearer"},error:null}}export{u as a,c as b,v as c};//# sourceMappingURL=chunk-N3ONRO35.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-N3ONRO35.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/errors.ts","../src/middleware/authenticate.ts"],"names":["AuthrimServerError","code","message","options","getServerErrorMeta","ERROR_META_MAP","getHeader","headers","name","lowerName","key","value","parseAuthorizationHeader","header","parts","scheme","token","normalizedScheme","authenticateRequest","server","request","authHeader","parsed","validationResult","errorMeta","claims","hasDPoPBinding","dpopHeader","dpopResult"],"mappings":"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","file":"chunk-N3ONRO35.js","sourcesContent":["/**\r\n * Authrim Server SDK Error Types\r\n *\r\n * These error codes are specific to server-side token validation and DPoP operations.\r\n */\r\n\r\n/**\r\n * Server SDK error codes\r\n */\r\nexport type AuthrimServerErrorCode =\r\n // JWT validation errors\r\n | 'invalid_token'\r\n | 'token_expired'\r\n | 'token_not_yet_valid'\r\n | 'token_malformed'\r\n | 'signature_invalid'\r\n | 'algorithm_mismatch'\r\n // Issuer/Audience validation\r\n | 'invalid_issuer'\r\n | 'invalid_audience'\r\n // JWKS errors\r\n | 'jwks_fetch_error'\r\n | 'jwks_key_not_found'\r\n | 'jwks_key_ambiguous'\r\n | 'jwks_key_import_error'\r\n // DPoP errors\r\n | 'dpop_proof_missing'\r\n | 'dpop_proof_invalid'\r\n | 'dpop_proof_signature_invalid'\r\n | 'dpop_method_mismatch'\r\n | 'dpop_uri_mismatch'\r\n | 'dpop_ath_mismatch'\r\n | 'dpop_binding_mismatch'\r\n | 'dpop_iat_expired'\r\n | 'dpop_nonce_required'\r\n // Token introspection/revocation errors\r\n | 'introspection_error'\r\n | 'revocation_error'\r\n // Configuration errors\r\n | 'configuration_error'\r\n | 'provider_error'\r\n // Network errors\r\n | 'network_error'\r\n | 'timeout_error';\r\n\r\n/**\r\n * Error metadata for recovery information\r\n */\r\nexport interface AuthrimServerErrorMeta {\r\n /** HTTP status code to return */\r\n httpStatus: number;\r\n /** Whether this is a transient error */\r\n transient: boolean;\r\n /** Whether automatic retry is possible */\r\n retryable: boolean;\r\n /** WWW-Authenticate error attribute */\r\n wwwAuthenticateError?: string;\r\n}\r\n\r\n/**\r\n * Options for creating an AuthrimServerError\r\n */\r\nexport interface AuthrimServerErrorOptions {\r\n details?: Record<string, unknown>;\r\n cause?: Error;\r\n}\r\n\r\n/**\r\n * Authrim Server SDK Error class\r\n */\r\nexport class AuthrimServerError extends Error {\r\n /** Error code for programmatic handling */\r\n readonly code: AuthrimServerErrorCode;\r\n\r\n /** Additional error details */\r\n readonly details?: Record<string, unknown>;\r\n\r\n /** Underlying cause */\r\n readonly cause?: Error;\r\n\r\n constructor(\r\n code: AuthrimServerErrorCode,\r\n message: string,\r\n options?: AuthrimServerErrorOptions\r\n ) {\r\n super(message);\r\n this.name = 'AuthrimServerError';\r\n this.code = code;\r\n this.details = options?.details;\r\n this.cause = options?.cause;\r\n }\r\n\r\n /**\r\n * Get error metadata for HTTP response\r\n */\r\n get meta(): AuthrimServerErrorMeta {\r\n return getServerErrorMeta(this.code);\r\n }\r\n}\r\n\r\n/**\r\n * Error metadata mapping for each error code\r\n */\r\nconst ERROR_META_MAP: Record<AuthrimServerErrorCode, AuthrimServerErrorMeta> = {\r\n // JWT validation errors\r\n invalid_token: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n token_expired: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n token_not_yet_valid: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n token_malformed: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n signature_invalid: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n algorithm_mismatch: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n\r\n // Issuer/Audience validation\r\n invalid_issuer: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n invalid_audience: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n\r\n // JWKS errors\r\n jwks_fetch_error: {\r\n httpStatus: 503,\r\n transient: true,\r\n retryable: true,\r\n },\r\n jwks_key_not_found: {\r\n httpStatus: 401,\r\n transient: true,\r\n retryable: true,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n jwks_key_ambiguous: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n jwks_key_import_error: {\r\n httpStatus: 500,\r\n transient: false,\r\n retryable: false,\r\n },\r\n\r\n // DPoP errors\r\n dpop_proof_missing: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_proof_invalid: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_proof_signature_invalid: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_method_mismatch: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_uri_mismatch: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_ath_mismatch: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_binding_mismatch: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_iat_expired: {\r\n httpStatus: 401,\r\n transient: false,\r\n retryable: false,\r\n wwwAuthenticateError: 'invalid_token',\r\n },\r\n dpop_nonce_required: {\r\n httpStatus: 401,\r\n transient: true,\r\n retryable: true,\r\n wwwAuthenticateError: 'use_dpop_nonce',\r\n },\r\n\r\n // Token introspection/revocation errors\r\n introspection_error: {\r\n httpStatus: 503,\r\n transient: true,\r\n retryable: true,\r\n },\r\n revocation_error: {\r\n httpStatus: 503,\r\n transient: true,\r\n retryable: true,\r\n },\r\n\r\n // Configuration errors\r\n configuration_error: {\r\n httpStatus: 500,\r\n transient: false,\r\n retryable: false,\r\n },\r\n provider_error: {\r\n httpStatus: 500,\r\n transient: false,\r\n retryable: false,\r\n },\r\n\r\n // Network errors\r\n network_error: {\r\n httpStatus: 503,\r\n transient: true,\r\n retryable: true,\r\n },\r\n timeout_error: {\r\n httpStatus: 504,\r\n transient: true,\r\n retryable: true,\r\n },\r\n};\r\n\r\n/**\r\n * Get error metadata for a given error code\r\n */\r\nexport function getServerErrorMeta(code: AuthrimServerErrorCode): AuthrimServerErrorMeta {\r\n return ERROR_META_MAP[code];\r\n}\r\n","/**\r\n * Core Authentication Function (Framework-Agnostic)\r\n *\r\n * This function is the ONLY authentication logic.\r\n * Framework adapters are thin wrappers that:\r\n * 1. Extract headers/method/url from framework-specific request\r\n * 2. Call authenticateRequest()\r\n * 3. Attach result to framework-specific context\r\n *\r\n * Header normalization:\r\n * - All header names are normalized to lowercase internally\r\n * - If multiple Authorization headers exist, only the first is used\r\n * - DPoP header lookup is case-insensitive\r\n */\r\n\r\nimport type { AuthrimServer } from '../core/client.js';\r\nimport type { AuthenticateRequest, AuthenticateResult } from './types.js';\r\nimport { AuthrimServerError } from '../types/errors.js';\r\n\r\n/**\r\n * Get header value (case-insensitive)\r\n */\r\nfunction getHeader(\r\n headers: Record<string, string | string[] | undefined>,\r\n name: string\r\n): string | undefined {\r\n const lowerName = name.toLowerCase();\r\n\r\n for (const [key, value] of Object.entries(headers)) {\r\n if (key.toLowerCase() === lowerName) {\r\n if (Array.isArray(value)) {\r\n return value[0];\r\n }\r\n return value;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Parse Authorization header\r\n *\r\n * @param header - Authorization header value\r\n * @returns Parsed token and type\r\n */\r\nfunction parseAuthorizationHeader(\r\n header: string | undefined\r\n): { scheme: 'Bearer' | 'DPoP'; token: string } | null {\r\n if (!header) {\r\n return null;\r\n }\r\n\r\n const parts = header.split(' ');\r\n if (parts.length !== 2) {\r\n return null;\r\n }\r\n\r\n const [scheme, token] = parts;\r\n if (!scheme || !token) {\r\n return null;\r\n }\r\n\r\n const normalizedScheme = scheme.toLowerCase();\r\n if (normalizedScheme === 'bearer') {\r\n return { scheme: 'Bearer', token };\r\n }\r\n if (normalizedScheme === 'dpop') {\r\n return { scheme: 'DPoP', token };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Authenticate a request\r\n *\r\n * @param server - AuthrimServer instance\r\n * @param request - Framework-agnostic request\r\n * @returns Authentication result\r\n */\r\nexport async function authenticateRequest(\r\n server: AuthrimServer,\r\n request: AuthenticateRequest\r\n): Promise<AuthenticateResult> {\r\n // Parse Authorization header\r\n const authHeader = getHeader(request.headers, 'Authorization');\r\n const parsed = parseAuthorizationHeader(authHeader);\r\n\r\n if (!parsed) {\r\n return {\r\n data: null,\r\n error: {\r\n code: 'invalid_token',\r\n message: 'Missing or invalid Authorization header',\r\n httpStatus: 401,\r\n },\r\n };\r\n }\r\n\r\n const { scheme, token } = parsed;\r\n\r\n // Validate token\r\n const validationResult = await server.validateToken(token);\r\n\r\n if (validationResult.error) {\r\n const errorMeta = new AuthrimServerError(\r\n validationResult.error.code as any,\r\n validationResult.error.message\r\n ).meta;\r\n\r\n return {\r\n data: null,\r\n error: {\r\n code: validationResult.error.code,\r\n message: validationResult.error.message,\r\n httpStatus: errorMeta.httpStatus,\r\n },\r\n };\r\n }\r\n\r\n const claims = validationResult.data;\r\n if (!claims) {\r\n return {\r\n data: null,\r\n error: {\r\n code: 'invalid_token',\r\n message: 'Token validation failed',\r\n httpStatus: 401,\r\n },\r\n };\r\n }\r\n\r\n // Check if token is DPoP-bound\r\n const hasDPoPBinding = claims.claims.cnf?.jkt !== undefined;\r\n\r\n // If using DPoP scheme or token has DPoP binding, validate DPoP proof\r\n if (scheme === 'DPoP' || hasDPoPBinding) {\r\n const dpopHeader = getHeader(request.headers, 'DPoP');\r\n\r\n if (!dpopHeader) {\r\n return {\r\n data: null,\r\n error: {\r\n code: 'dpop_proof_missing',\r\n message: 'DPoP proof required but not provided',\r\n httpStatus: 401,\r\n },\r\n };\r\n }\r\n\r\n const dpopResult = await server.validateDPoP(dpopHeader, {\r\n method: request.method,\r\n uri: request.url,\r\n accessToken: token,\r\n expectedThumbprint: claims.claims.cnf?.jkt,\r\n });\r\n\r\n if (!dpopResult.valid) {\r\n return {\r\n data: null,\r\n error: {\r\n code: dpopResult.errorCode ?? 'dpop_proof_invalid',\r\n message: dpopResult.errorMessage ?? 'Invalid DPoP proof',\r\n httpStatus: 401,\r\n },\r\n };\r\n }\r\n }\r\n\r\n return {\r\n data: {\r\n claims,\r\n tokenType: hasDPoPBinding ? 'DPoP' : 'Bearer',\r\n },\r\n error: null,\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';function o(r){return r.replace(/[\x00-\x08\x0A-\x1F\x7F]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"').substring(0,256)}function a(r){return {error:r.meta.wwwAuthenticateError??"server_error",error_description:r.message}}function s(r,e,t="Bearer"){let n=[t];e&&n.push(`realm="${o(e)}"`);let i=r.meta.wwwAuthenticateError;return i&&(n.push(`error="${o(i)}"`),n.push(`error_description="${o(r.message)}"`)),n.join(", ")}function c(r,e={}){let t={"Content-Type":"application/json"};return r.meta.httpStatus===401&&(t["WWW-Authenticate"]=s(r,e.realm,e.scheme??"Bearer")),r.code==="dpop_nonce_required"&&e.dpopNonce&&(t["DPoP-Nonce"]=e.dpopNonce),t}exports.a=a;exports.b=s;exports.c=c;//# sourceMappingURL=chunk-O2ALCNXB.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-O2ALCNXB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/error-response.ts"],"names":["sanitizeHeaderValue","value","buildErrorResponse","error","buildWwwAuthenticateHeader","realm","scheme","parts","wwwError","buildErrorHeaders","options","headers"],"mappings":"aA2BA,SAASA,CAAAA,CAAoBC,CAAAA,CAAuB,CAClD,OAAOA,CAAAA,CAMJ,OAAA,CAAQ,2BAAA,CAA6B,EAAE,CAAA,CAEvC,OAAA,CAAQ,KAAA,CAAO,MAAM,CAAA,CAErB,OAAA,CAAQ,IAAA,CAAM,KAAK,CAAA,CAEnB,SAAA,CAAU,CAAA,CAAG,GAAG,CACrB,CAQO,SAASC,CAAAA,CAAmBC,CAAAA,CAA8C,CAC/E,OAAO,CACL,KAAA,CAAOA,CAAAA,CAAM,IAAA,CAAK,oBAAA,EAAwB,cAAA,CAC1C,iBAAA,CAAmBA,CAAAA,CAAM,OAC3B,CACF,CAUO,SAASC,CAAAA,CACdD,CAAAA,CACAE,CAAAA,CACAC,CAAAA,CAA4B,QAAA,CACpB,CACR,IAAMC,CAAAA,CAAkB,CAACD,CAAM,CAAA,CAE3BD,CAAAA,EAEFE,CAAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAUP,CAAAA,CAAoBK,CAAK,CAAC,CAAA,CAAA,CAAG,CAAA,CAGpD,IAAMG,EAAWL,CAAAA,CAAM,IAAA,CAAK,oBAAA,CAC5B,OAAIK,CAAAA,GAEFD,CAAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAUP,CAAAA,CAAoBQ,CAAQ,CAAC,CAAA,CAAA,CAAG,CAAA,CAErDD,CAAAA,CAAM,IAAA,CAAK,CAAA,mBAAA,EAAsBP,CAAAA,CAAoBG,CAAAA,CAAM,OAAO,CAAC,CAAA,CAAA,CAAG,CAAA,CAAA,CAGjEI,CAAAA,CAAM,IAAA,CAAK,IAAI,CACxB,CASO,SAASE,CAAAA,CACdN,CAAAA,CACAO,CAAAA,CAII,GACoB,CACxB,IAAMC,CAAAA,CAAkC,CACtC,cAAA,CAAgB,kBAClB,CAAA,CAGA,OAAIR,CAAAA,CAAM,IAAA,CAAK,UAAA,GAAe,GAAA,GAC5BQ,CAAAA,CAAQ,kBAAkB,CAAA,CAAIP,CAAAA,CAC5BD,CAAAA,CACAO,CAAAA,CAAQ,KAAA,CACRA,CAAAA,CAAQ,MAAA,EAAU,QACpB,CAAA,CAAA,CAIEP,CAAAA,CAAM,IAAA,GAAS,qBAAA,EAAyBO,CAAAA,CAAQ,SAAA,GAClDC,CAAAA,CAAQ,YAAY,CAAA,CAAID,CAAAA,CAAQ,WAG3BC,CACT","file":"chunk-O2ALCNXB.cjs","sourcesContent":["/**\r\n * HTTP Error Response Utilities\r\n *\r\n * Helpers for building OAuth 2.0 / RFC 6750 compliant error responses.\r\n */\r\n\r\nimport { AuthrimServerError } from '../types/errors.js';\r\n\r\n/**\r\n * OAuth 2.0 error response body\r\n */\r\nexport interface ErrorResponseBody {\r\n error: string;\r\n error_description?: string;\r\n}\r\n\r\n/**\r\n * Sanitize a string value for use in HTTP header quoted-string\r\n *\r\n * Per RFC 7230 Section 3.2.6, a quoted-string consists of:\r\n * - DQUOTE *( qdtext / quoted-pair ) DQUOTE\r\n * - qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text\r\n * - quoted-pair = \"\\\" ( HTAB / SP / VCHAR / obs-text )\r\n *\r\n * We escape backslash and double-quote, and remove control characters.\r\n * CRITICAL: Must remove CR (\\r, 0x0D) and LF (\\n, 0x0A) to prevent header injection.\r\n */\r\nfunction sanitizeHeaderValue(value: string): string {\r\n return value\r\n // Remove ALL control characters except tab (0x09):\r\n // - 0x00-0x08: NUL through BS\r\n // - 0x0A-0x1F: LF (0x0A), VT (0x0B), FF (0x0C), CR (0x0D), SO through US\r\n // - 0x7F: DEL\r\n // Note: Tab (0x09) is allowed per RFC 7230\r\n .replace(/[\\x00-\\x08\\x0A-\\x1F\\x7F]/g, '')\r\n // Escape backslash first\r\n .replace(/\\\\/g, '\\\\\\\\')\r\n // Escape double quotes\r\n .replace(/\"/g, '\\\\\"')\r\n // Limit length to prevent header size issues\r\n .substring(0, 256);\r\n}\r\n\r\n/**\r\n * Build an error response body from an AuthrimServerError\r\n *\r\n * @param error - The error to convert\r\n * @returns Error response body\r\n */\r\nexport function buildErrorResponse(error: AuthrimServerError): ErrorResponseBody {\r\n return {\r\n error: error.meta.wwwAuthenticateError ?? 'server_error',\r\n error_description: error.message,\r\n };\r\n}\r\n\r\n/**\r\n * Build WWW-Authenticate header value (RFC 6750)\r\n *\r\n * @param error - The error\r\n * @param realm - Optional realm value\r\n * @param scheme - Authentication scheme ('Bearer' or 'DPoP')\r\n * @returns WWW-Authenticate header value\r\n */\r\nexport function buildWwwAuthenticateHeader(\r\n error: AuthrimServerError,\r\n realm?: string,\r\n scheme: 'Bearer' | 'DPoP' = 'Bearer'\r\n): string {\r\n const parts: string[] = [scheme];\r\n\r\n if (realm) {\r\n // Sanitize realm to prevent header injection\r\n parts.push(`realm=\"${sanitizeHeaderValue(realm)}\"`);\r\n }\r\n\r\n const wwwError = error.meta.wwwAuthenticateError;\r\n if (wwwError) {\r\n // wwwError is from a controlled set, but sanitize for safety\r\n parts.push(`error=\"${sanitizeHeaderValue(wwwError)}\"`);\r\n // Sanitize error message to prevent header injection\r\n parts.push(`error_description=\"${sanitizeHeaderValue(error.message)}\"`);\r\n }\r\n\r\n return parts.join(', ');\r\n}\r\n\r\n/**\r\n * Build error headers for HTTP response\r\n *\r\n * @param error - The error\r\n * @param options - Options for header building\r\n * @returns Headers object\r\n */\r\nexport function buildErrorHeaders(\r\n error: AuthrimServerError,\r\n options: {\r\n realm?: string;\r\n scheme?: 'Bearer' | 'DPoP';\r\n dpopNonce?: string;\r\n } = {}\r\n): Record<string, string> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n // Add WWW-Authenticate for 401 errors\r\n if (error.meta.httpStatus === 401) {\r\n headers['WWW-Authenticate'] = buildWwwAuthenticateHeader(\r\n error,\r\n options.realm,\r\n options.scheme ?? 'Bearer'\r\n );\r\n }\r\n\r\n // Add DPoP-Nonce for nonce-required errors\r\n if (error.code === 'dpop_nonce_required' && options.dpopNonce) {\r\n headers['DPoP-Nonce'] = options.dpopNonce;\r\n }\r\n\r\n return headers;\r\n}\r\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
function S(){return {fetch(e,t){return globalThis.fetch(e,t)}}}function f(e){let t;if(typeof Buffer<"u")t=Buffer.from(e).toString("base64");else {let n=Array.from(e).map(r=>String.fromCharCode(r)).join("");t=btoa(n);}return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function p(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=(4-t.length%4)%4;if(t+="=".repeat(n),typeof Buffer<"u")return new Uint8Array(Buffer.from(t,"base64"));{let r=atob(t),i=new Uint8Array(r.length);for(let o=0;o<r.length;o++)i[o]=r.charCodeAt(o);return i}}function A(e){return f(new TextEncoder().encode(e))}function g(e){return new TextDecoder().decode(p(e))}var d={RS256:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},RS384:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-384"},RS512:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},PS256:{name:"RSA-PSS",hash:"SHA-256"},PS384:{name:"RSA-PSS",hash:"SHA-384"},PS512:{name:"RSA-PSS",hash:"SHA-512"},ES256:{name:"ECDSA",namedCurve:"P-256"},ES384:{name:"ECDSA",namedCurve:"P-384"},ES512:{name:"ECDSA",namedCurve:"P-521"}};function h(e){let t=d[e];if(!t)throw new Error(`Unsupported algorithm: ${e}`);return e.startsWith("PS")?{name:"RSA-PSS",saltLength:{PS256:32,PS384:48,PS512:64}[e]??32}:e.startsWith("ES")?{name:"ECDSA",hash:{ES256:"SHA-256",ES384:"SHA-384",ES512:"SHA-512"}[e]??"SHA-256"}:t}function y(e){let t=e.kty;switch(t){case "RSA":return {e:e.e,kty:e.kty,n:e.n};case "EC":return {crv:e.crv,kty:e.kty,x:e.x,y:e.y};case "OKP":return {crv:e.crv,kty:e.kty,x:e.x};default:throw new Error(`Unsupported key type for thumbprint: ${t}`)}}function P(){let e=globalThis.crypto;return {async verifySignature(t,n,r,i){let o=h(t);return e.subtle.verify(o,n,r,i)},async importJwk(t,n){let r=d[n];if(!r)throw new Error(`Unsupported algorithm: ${n}`);return e.subtle.importKey("jwk",t,r,true,["verify"])},async sha256(t){let n=typeof t=="string"?new TextEncoder().encode(t):t,r=await e.subtle.digest("SHA-256",n);return new Uint8Array(r)},async calculateThumbprint(t){let n=y(t),r=JSON.stringify(n,Object.keys(n).sort()),i=await this.sha256(r);return f(i)}}}function x(){return {nowSeconds(){return Math.floor(Date.now()/1e3)},nowMs(){return Date.now()}}}function w(e={}){let{ttlMs:t=36e5,maxSize:n=1e3}=e,r=new Map;function i(){let o=Date.now(),s=[];for(let[a,c]of r.entries())c.expiresAt<=o&&s.push(a);for(let a of s)r.delete(a);if(r.size>n){let a=r.size-n,c=r.keys();for(let u=0;u<a;u++){let m=c.next();m.done||r.delete(m.value);}}}return {get(o){let s=r.get(o);if(s){if(s.expiresAt<=Date.now()){r.delete(o);return}return r.delete(o),r.set(o,s),s.value}},set(o,s,a){if(r.has(o))r.delete(o);else if(r.size>=n&&(i(),r.size>=n)){let u=r.keys().next().value;u!==void 0&&r.delete(u);}let c=Date.now()+(a??t);r.set(o,{value:s,expiresAt:c});},delete(o){r.delete(o);},clear(){r.clear();}}}
|
|
2
|
+
export{S as a,f as b,p as c,A as d,g as e,P as f,x as g,w as h};//# sourceMappingURL=chunk-OS567YCE.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-OS567YCE.js.map
|