@tern-secure/nextjs 5.1.12 → 5.2.0-canary.v20250918173007
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/cjs/app-router/admin/api/endpoints/abstract.js +39 -0
- package/dist/cjs/app-router/admin/api/endpoints/abstract.js.map +1 -0
- package/dist/cjs/app-router/admin/api/endpoints/sessions.js +2 -0
- package/dist/cjs/app-router/admin/api/endpoints/sessions.js.map +1 -0
- package/dist/cjs/app-router/admin/api/endpoints/users.js +4 -0
- package/dist/cjs/app-router/admin/api/endpoints/users.js.map +1 -0
- package/dist/cjs/app-router/admin/claude-authenticateRequestProcessor.js +79 -0
- package/dist/cjs/app-router/admin/claude-authenticateRequestProcessor.js.map +1 -0
- package/dist/cjs/app-router/admin/endpointRouter.js +72 -0
- package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -0
- package/dist/cjs/app-router/admin/fnValidators.js +4 -3
- package/dist/cjs/app-router/admin/fnValidators.js.map +1 -1
- package/dist/cjs/app-router/admin/handlerUtils.js +63 -0
- package/dist/cjs/app-router/admin/handlerUtils.js.map +1 -0
- package/dist/cjs/app-router/admin/index.js +8 -0
- package/dist/cjs/app-router/admin/index.js.map +1 -1
- package/dist/cjs/app-router/admin/sessionHandlers.js +15 -13
- package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js +31 -36
- package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
- package/dist/cjs/app-router/admin/types.js +0 -1
- package/dist/cjs/app-router/admin/types.js.map +1 -1
- package/dist/cjs/app-router/admin/validators.js +1 -2
- package/dist/cjs/app-router/admin/validators.js.map +1 -1
- package/dist/cjs/utils/NextCookieAdapter.js.map +1 -1
- package/dist/esm/app-router/admin/api/endpoints/abstract.js +15 -0
- package/dist/esm/app-router/admin/api/endpoints/abstract.js.map +1 -0
- package/dist/esm/app-router/admin/api/endpoints/sessions.js +1 -0
- package/dist/esm/app-router/admin/api/endpoints/sessions.js.map +1 -0
- package/dist/esm/app-router/admin/api/endpoints/users.js +3 -0
- package/dist/esm/app-router/admin/api/endpoints/users.js.map +1 -0
- package/dist/esm/app-router/admin/claude-authenticateRequestProcessor.js +55 -0
- package/dist/esm/app-router/admin/claude-authenticateRequestProcessor.js.map +1 -0
- package/dist/esm/app-router/admin/endpointRouter.js +48 -0
- package/dist/esm/app-router/admin/endpointRouter.js.map +1 -0
- package/dist/esm/app-router/admin/fnValidators.js +4 -3
- package/dist/esm/app-router/admin/fnValidators.js.map +1 -1
- package/dist/esm/app-router/admin/handlerUtils.js +38 -0
- package/dist/esm/app-router/admin/handlerUtils.js.map +1 -0
- package/dist/esm/app-router/admin/index.js +5 -0
- package/dist/esm/app-router/admin/index.js.map +1 -1
- package/dist/esm/app-router/admin/sessionHandlers.js +15 -13
- package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/esm/app-router/admin/ternsecureNextjsHandler.js +34 -41
- package/dist/esm/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
- package/dist/esm/app-router/admin/types.js +0 -1
- package/dist/esm/app-router/admin/types.js.map +1 -1
- package/dist/esm/app-router/admin/validators.js +1 -2
- package/dist/esm/app-router/admin/validators.js.map +1 -1
- package/dist/esm/utils/NextCookieAdapter.js.map +1 -1
- package/dist/types/app-router/admin/api/endpoints/abstract.d.ts +19 -0
- package/dist/types/app-router/admin/api/endpoints/abstract.d.ts.map +1 -0
- package/dist/types/app-router/admin/api/endpoints/sessions.d.ts +2 -0
- package/dist/types/app-router/admin/api/endpoints/sessions.d.ts.map +1 -0
- package/dist/types/app-router/admin/api/endpoints/users.d.ts +2 -0
- package/dist/types/app-router/admin/api/endpoints/users.d.ts.map +1 -0
- package/dist/types/app-router/admin/claude-authenticateRequestProcessor.d.ts +37 -0
- package/dist/types/app-router/admin/claude-authenticateRequestProcessor.d.ts.map +1 -0
- package/dist/types/app-router/admin/endpointRouter.d.ts +10 -0
- package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -0
- package/dist/types/app-router/admin/fnValidators.d.ts +11 -12
- package/dist/types/app-router/admin/fnValidators.d.ts.map +1 -1
- package/dist/types/app-router/admin/handlerUtils.d.ts +19 -0
- package/dist/types/app-router/admin/handlerUtils.d.ts.map +1 -0
- package/dist/types/app-router/admin/index.d.ts +4 -1
- package/dist/types/app-router/admin/index.d.ts.map +1 -1
- package/dist/types/app-router/admin/sessionHandlers.d.ts +3 -4
- package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
- package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts +3 -4
- package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts.map +1 -1
- package/dist/types/app-router/admin/types.d.ts +2 -3
- package/dist/types/app-router/admin/types.d.ts.map +1 -1
- package/dist/types/app-router/admin/validators.d.ts +10 -12
- package/dist/types/app-router/admin/validators.d.ts.map +1 -1
- package/dist/types/utils/NextCookieAdapter.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var abstract_exports = {};
|
|
20
|
+
__export(abstract_exports, {
|
|
21
|
+
BaseEndpointHandler: () => BaseEndpointHandler
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(abstract_exports);
|
|
24
|
+
class BaseEndpointHandler {
|
|
25
|
+
validateMethod(allowedMethods, method) {
|
|
26
|
+
return allowedMethods.includes(method);
|
|
27
|
+
}
|
|
28
|
+
validateSubEndpoint(subEndpoint, requiredSubEndpoint) {
|
|
29
|
+
if (requiredSubEndpoint) {
|
|
30
|
+
return subEndpoint !== void 0;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
36
|
+
0 && (module.exports = {
|
|
37
|
+
BaseEndpointHandler
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=abstract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/app-router/admin/api/endpoints/abstract.ts"],"sourcesContent":["import type {\n AuthEndpoint,\n SessionSubEndpoint,\n TernSecureInternalHandlerConfig,\n} from '../../types';\n\nexport interface HandlerContext {\n request: Request;\n pathSegments: string[];\n endpoint: AuthEndpoint;\n subEndpoint: SessionSubEndpoint | undefined;\n method: string;\n}\n\nexport interface EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean;\n handle(\n handlerContext: HandlerContext,\n config: TernSecureInternalHandlerConfig,\n ): Promise<Response>;\n}\n\nexport abstract class BaseEndpointHandler implements EndpointHandler {\n abstract canHandle(endpoint: AuthEndpoint): boolean;\n abstract handle(\n handlerContext: HandlerContext,\n config: TernSecureInternalHandlerConfig,\n ): Promise<Response>;\n\n protected validateMethod(allowedMethods: string[], method: string): boolean {\n return allowedMethods.includes(method);\n }\n\n protected validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n requiredSubEndpoint?: boolean,\n ): boolean {\n if (requiredSubEndpoint) {\n return subEndpoint !== undefined;\n }\n return true;\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBO,MAAe,oBAA+C;AAAA,EAOzD,eAAe,gBAA0B,QAAyB;AAC1E,WAAO,eAAe,SAAS,MAAM;AAAA,EACvC;AAAA,EAEU,oBACR,aACA,qBACS;AACT,QAAI,qBAAqB;AACvB,aAAO,gBAAgB;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/app-router/admin/api/endpoints/users.ts"],"sourcesContent":["{/*import type { NextResponse } from 'next/server';\n\nimport type { AuthEndpoint, TernSecureInternalHandlerConfig } from '../../types';\nimport type { EndpointHandler, HandlerContext } from './abstract';\nimport { createApiErrorResponse } from './responses';\nimport { SessionEndpointHandler } from './sessionHandlers';\n\nclass UsersHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'users';\n }\n\n handle(\n _handlerContext: HandlerContext,\n _config: TernSecureInternalHandlerConfig,\n ): Promise<NextResponse> {\n return Promise.resolve(\n createApiErrorResponse('ENDPOINT_NOT_IMPLEMENTED', 'Users endpoint not implemented', 501),\n );\n }\n}*/}"],"mappings":";AAAA;AAoBG;","names":[]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var claude_authenticateRequestProcessor_exports = {};
|
|
20
|
+
__export(claude_authenticateRequestProcessor_exports, {
|
|
21
|
+
createRequestProcessor: () => createRequestProcessor
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(claude_authenticateRequestProcessor_exports);
|
|
24
|
+
var import_backend = require("@tern-secure/backend");
|
|
25
|
+
class RequestProcessorContext {
|
|
26
|
+
constructor(ternSecureRequest, options) {
|
|
27
|
+
this.ternSecureRequest = ternSecureRequest;
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.initHeaderValues();
|
|
30
|
+
this.initCookieValues();
|
|
31
|
+
this.ternUrl = this.ternSecureRequest.ternUrl;
|
|
32
|
+
}
|
|
33
|
+
initHeaderValues() {
|
|
34
|
+
this.sessionTokenInHeader = this.parseAuthorizationHeader(
|
|
35
|
+
this.getHeader(import_backend.constants.Headers.Authorization)
|
|
36
|
+
);
|
|
37
|
+
this.origin = this.getHeader(import_backend.constants.Headers.Origin);
|
|
38
|
+
this.host = this.getHeader(import_backend.constants.Headers.Host);
|
|
39
|
+
this.forwardedHost = this.getHeader(import_backend.constants.Headers.ForwardedHost);
|
|
40
|
+
this.forwardedProto = this.getHeader(import_backend.constants.Headers.CloudFrontForwardedProto) || this.getHeader(import_backend.constants.Headers.ForwardedProto);
|
|
41
|
+
this.referrer = this.getHeader(import_backend.constants.Headers.Referrer);
|
|
42
|
+
this.userAgent = this.getHeader(import_backend.constants.Headers.UserAgent);
|
|
43
|
+
this.secFetchDest = this.getHeader(import_backend.constants.Headers.SecFetchDest);
|
|
44
|
+
this.accept = this.getHeader(import_backend.constants.Headers.Accept);
|
|
45
|
+
}
|
|
46
|
+
initCookieValues() {
|
|
47
|
+
this.csrfTokenInCookie = this.getCookie(import_backend.constants.Cookies.CsrfToken);
|
|
48
|
+
}
|
|
49
|
+
getQueryParam(name) {
|
|
50
|
+
return this.ternSecureRequest.ternUrl.searchParams.get(name);
|
|
51
|
+
}
|
|
52
|
+
getHeader(name) {
|
|
53
|
+
return this.ternSecureRequest.headers.get(name) || void 0;
|
|
54
|
+
}
|
|
55
|
+
getCookie(name) {
|
|
56
|
+
return this.ternSecureRequest.cookies.get(name) || void 0;
|
|
57
|
+
}
|
|
58
|
+
parseAuthorizationHeader(authorizationHeader) {
|
|
59
|
+
if (!authorizationHeader) {
|
|
60
|
+
return void 0;
|
|
61
|
+
}
|
|
62
|
+
const [scheme, token] = authorizationHeader.split(" ", 2);
|
|
63
|
+
if (!token) {
|
|
64
|
+
return scheme;
|
|
65
|
+
}
|
|
66
|
+
if (scheme === "Bearer") {
|
|
67
|
+
return token;
|
|
68
|
+
}
|
|
69
|
+
return void 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const createRequestProcessor = async (ternSecureRequest, options) => {
|
|
73
|
+
return new RequestProcessorContext(ternSecureRequest, options);
|
|
74
|
+
};
|
|
75
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
76
|
+
0 && (module.exports = {
|
|
77
|
+
createRequestProcessor
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=claude-authenticateRequestProcessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/claude-authenticateRequestProcessor.ts"],"sourcesContent":["import type { TernSecureRequest } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\n\nimport type { TernSecureHandlerOptions} from './types';\n\n/**\n * Request context for better type safety and clarity\n */\ninterface RequestProcessorContext extends TernSecureHandlerOptions {\n // header-based values\n sessionTokenInHeader: string | undefined;\n origin: string | undefined;\n host: string | undefined;\n forwardedHost: string | undefined;\n forwardedProto: string | undefined;\n referrer: string | undefined;\n userAgent: string | undefined;\n secFetchDest: string | undefined;\n accept: string | undefined;\n\n // cookie-based values\n sessionTokenInCookie: string | undefined;\n refreshTokenInCookie: string | undefined;\n csrfTokenInCookie: string | undefined;\n\n ternUrl: URL;\n}\n\n/**\n * Request processor utility class for common operations\n */\nclass RequestProcessorContext implements RequestProcessorContext {\n public constructor(\n private ternSecureRequest: TernSecureRequest,\n private options: TernSecureHandlerOptions,\n ) {\n this.initHeaderValues();\n this.initCookieValues();\n this.ternUrl = this.ternSecureRequest.ternUrl;\n }\n\n private initHeaderValues() {\n this.sessionTokenInHeader = this.parseAuthorizationHeader(\n this.getHeader(constants.Headers.Authorization),\n );\n this.origin = this.getHeader(constants.Headers.Origin);\n this.host = this.getHeader(constants.Headers.Host);\n this.forwardedHost = this.getHeader(constants.Headers.ForwardedHost);\n this.forwardedProto =\n this.getHeader(constants.Headers.CloudFrontForwardedProto) ||\n this.getHeader(constants.Headers.ForwardedProto);\n this.referrer = this.getHeader(constants.Headers.Referrer);\n this.userAgent = this.getHeader(constants.Headers.UserAgent);\n this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);\n this.accept = this.getHeader(constants.Headers.Accept);\n }\n\n private initCookieValues() {\n //this.sessionTokenInCookie = this.getCookie(this.options.cookies.name);\n this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);\n }\n\n private getQueryParam(name: string) {\n return this.ternSecureRequest.ternUrl.searchParams.get(name);\n }\n\n private getHeader(name: string) {\n return this.ternSecureRequest.headers.get(name) || undefined;\n }\n\n private getCookie(name: string) {\n return this.ternSecureRequest.cookies.get(name) || undefined;\n }\n\n private parseAuthorizationHeader(\n authorizationHeader: string | undefined | null,\n ): string | undefined {\n if (!authorizationHeader) {\n return undefined;\n }\n\n const [scheme, token] = authorizationHeader.split(' ', 2);\n\n if (!token) {\n // No scheme specified, treat the entire value as the token\n return scheme;\n }\n\n if (scheme === 'Bearer') {\n return token;\n }\n\n // Skip all other schemes\n return undefined;\n }\n}\n\nexport type { RequestProcessorContext };\n\nexport const createRequestProcessor = async (\n ternSecureRequest: TernSecureRequest,\n options: TernSecureHandlerOptions,\n): Promise<RequestProcessorContext> => {\n return new RequestProcessorContext(ternSecureRequest, options);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA0B;AA8B1B,MAAM,wBAA2D;AAAA,EACxD,YACG,mBACA,SACR;AAFQ;AACA;AAER,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AACtB,SAAK,UAAU,KAAK,kBAAkB;AAAA,EACxC;AAAA,EAEQ,mBAAmB;AACzB,SAAK,uBAAuB,KAAK;AAAA,MAC/B,KAAK,UAAU,yBAAU,QAAQ,aAAa;AAAA,IAChD;AACA,SAAK,SAAS,KAAK,UAAU,yBAAU,QAAQ,MAAM;AACrD,SAAK,OAAO,KAAK,UAAU,yBAAU,QAAQ,IAAI;AACjD,SAAK,gBAAgB,KAAK,UAAU,yBAAU,QAAQ,aAAa;AACnE,SAAK,iBACH,KAAK,UAAU,yBAAU,QAAQ,wBAAwB,KACzD,KAAK,UAAU,yBAAU,QAAQ,cAAc;AACjD,SAAK,WAAW,KAAK,UAAU,yBAAU,QAAQ,QAAQ;AACzD,SAAK,YAAY,KAAK,UAAU,yBAAU,QAAQ,SAAS;AAC3D,SAAK,eAAe,KAAK,UAAU,yBAAU,QAAQ,YAAY;AACjE,SAAK,SAAS,KAAK,UAAU,yBAAU,QAAQ,MAAM;AAAA,EACvD;AAAA,EAEQ,mBAAmB;AAEzB,SAAK,oBAAoB,KAAK,UAAU,yBAAU,QAAQ,SAAS;AAAA,EACrE;AAAA,EAEQ,cAAc,MAAc;AAClC,WAAO,KAAK,kBAAkB,QAAQ,aAAa,IAAI,IAAI;AAAA,EAC7D;AAAA,EAEQ,UAAU,MAAc;AAC9B,WAAO,KAAK,kBAAkB,QAAQ,IAAI,IAAI,KAAK;AAAA,EACrD;AAAA,EAEQ,UAAU,MAAc;AAC9B,WAAO,KAAK,kBAAkB,QAAQ,IAAI,IAAI,KAAK;AAAA,EACrD;AAAA,EAEQ,yBACN,qBACoB;AACpB,QAAI,CAAC,qBAAqB;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,CAAC,QAAQ,KAAK,IAAI,oBAAoB,MAAM,KAAK,CAAC;AAExD,QAAI,CAAC,OAAO;AAEV,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,UAAU;AACvB,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT;AACF;AAIO,MAAM,yBAAyB,OACpC,mBACA,YACqC;AACrC,SAAO,IAAI,wBAAwB,mBAAmB,OAAO;AAC/D;","names":[]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var endpointRouter_exports = {};
|
|
20
|
+
__export(endpointRouter_exports, {
|
|
21
|
+
EndpointRouter: () => EndpointRouter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(endpointRouter_exports);
|
|
24
|
+
var import_responses = require("./responses");
|
|
25
|
+
var import_sessionHandlers = require("./sessionHandlers");
|
|
26
|
+
class SessionsHandler {
|
|
27
|
+
canHandle(endpoint) {
|
|
28
|
+
return endpoint === "sessions";
|
|
29
|
+
}
|
|
30
|
+
async handle(handlerContext, config) {
|
|
31
|
+
const { request, subEndpoint, method } = handlerContext;
|
|
32
|
+
return await import_sessionHandlers.SessionEndpointHandler.handle(request, method, subEndpoint, config);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
class UsersHandler {
|
|
36
|
+
canHandle(endpoint) {
|
|
37
|
+
return endpoint === "users";
|
|
38
|
+
}
|
|
39
|
+
handle(_handlerContext, _config) {
|
|
40
|
+
return Promise.resolve(
|
|
41
|
+
(0, import_responses.createApiErrorResponse)("ENDPOINT_NOT_IMPLEMENTED", "Users endpoint not implemented", 501)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class EndpointRouter {
|
|
46
|
+
static handlers = [
|
|
47
|
+
new SessionsHandler(),
|
|
48
|
+
new UsersHandler()
|
|
49
|
+
];
|
|
50
|
+
static async route(handlerContext, config) {
|
|
51
|
+
const { endpoint } = handlerContext;
|
|
52
|
+
const handler = this.handlers.find((h) => h.canHandle(endpoint));
|
|
53
|
+
if (!handler) {
|
|
54
|
+
return (0, import_responses.createApiErrorResponse)("ENDPOINT_NOT_FOUND", "Endpoint not found", 404);
|
|
55
|
+
}
|
|
56
|
+
return handler.handle(handlerContext, config);
|
|
57
|
+
}
|
|
58
|
+
static addHandler(handler) {
|
|
59
|
+
this.handlers.push(handler);
|
|
60
|
+
}
|
|
61
|
+
static removeHandler(predicate) {
|
|
62
|
+
const index = this.handlers.findIndex(predicate);
|
|
63
|
+
if (index > -1) {
|
|
64
|
+
this.handlers.splice(index, 1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
69
|
+
0 && (module.exports = {
|
|
70
|
+
EndpointRouter
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=endpointRouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/endpointRouter.ts"],"sourcesContent":["import type { EndpointHandler} from './api/endpoints/abstract';\nimport type { HandlerContext } from './handlerUtils';\nimport { createApiErrorResponse } from './responses';\nimport { SessionEndpointHandler } from './sessionHandlers';\nimport type { AuthEndpoint, TernSecureInternalHandlerConfig } from './types';\n\nclass SessionsHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'sessions';\n }\n\n async handle(\n handlerContext: HandlerContext,\n config: TernSecureInternalHandlerConfig,\n ): Promise<Response> {\n const { request, subEndpoint, method } = handlerContext;\n return await SessionEndpointHandler.handle(request, method, subEndpoint, config);\n }\n}\n\nclass UsersHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'users';\n }\n\n handle(\n _handlerContext: HandlerContext,\n _config: TernSecureInternalHandlerConfig,\n ): Promise<Response> {\n return Promise.resolve(\n createApiErrorResponse('ENDPOINT_NOT_IMPLEMENTED', 'Users endpoint not implemented', 501),\n );\n }\n}\n\nexport class EndpointRouter {\n private static readonly handlers: EndpointHandler[] = [\n new SessionsHandler(),\n new UsersHandler(),\n ];\n\n static async route(\n handlerContext: HandlerContext,\n config: TernSecureInternalHandlerConfig,\n ): Promise<Response> {\n const { endpoint } = handlerContext;\n\n const handler = this.handlers.find(h => h.canHandle(endpoint));\n\n if (!handler) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n return handler.handle(handlerContext, config);\n }\n\n static addHandler(handler: EndpointHandler): void {\n this.handlers.push(handler);\n }\n\n static removeHandler(predicate: (handler: EndpointHandler) => boolean): void {\n const index = this.handlers.findIndex(predicate);\n if (index > -1) {\n this.handlers.splice(index, 1);\n }\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,uBAAuC;AACvC,6BAAuC;AAGvC,MAAM,gBAA2C;AAAA,EAC/C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OACJ,gBACA,QACmB;AACnB,UAAM,EAAE,SAAS,aAAa,OAAO,IAAI;AACzC,WAAO,MAAM,8CAAuB,OAAO,SAAS,QAAQ,aAAa,MAAM;AAAA,EACjF;AACF;AAEA,MAAM,aAAwC;AAAA,EAC5C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,OACE,iBACA,SACmB;AACnB,WAAO,QAAQ;AAAA,UACb,yCAAuB,4BAA4B,kCAAkC,GAAG;AAAA,IAC1F;AAAA,EACF;AACF;AAEO,MAAM,eAAe;AAAA,EAC1B,OAAwB,WAA8B;AAAA,IACpD,IAAI,gBAAgB;AAAA,IACpB,IAAI,aAAa;AAAA,EACnB;AAAA,EAEA,aAAa,MACX,gBACA,QACmB;AACnB,UAAM,EAAE,SAAS,IAAI;AAErB,UAAM,UAAU,KAAK,SAAS,KAAK,OAAK,EAAE,UAAU,QAAQ,CAAC;AAE7D,QAAI,CAAC,SAAS;AACZ,iBAAO,yCAAuB,sBAAsB,sBAAsB,GAAG;AAAA,IAC/E;AAEA,WAAO,QAAQ,OAAO,gBAAgB,MAAM;AAAA,EAC9C;AAAA,EAEA,OAAO,WAAW,SAAgC;AAChD,SAAK,SAAS,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,OAAO,cAAc,WAAwD;AAC3E,UAAM,QAAQ,KAAK,SAAS,UAAU,SAAS;AAC/C,QAAI,QAAQ,IAAI;AACd,WAAK,SAAS,OAAO,OAAO,CAAC;AAAA,IAC/B;AAAA,EACF;AACF;","names":[]}
|
|
@@ -22,7 +22,7 @@ __export(fnValidators_exports, {
|
|
|
22
22
|
createValidators: () => createValidators
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(fnValidators_exports);
|
|
25
|
-
var
|
|
25
|
+
var import_headers = require("next/headers");
|
|
26
26
|
var import_responses = require("./responses");
|
|
27
27
|
function createRequestContext(request) {
|
|
28
28
|
const url = new URL(request.url);
|
|
@@ -60,7 +60,7 @@ function createValidators(context) {
|
|
|
60
60
|
return null;
|
|
61
61
|
}
|
|
62
62
|
function createCorsOptionsResponse(corsOptions) {
|
|
63
|
-
const response = new
|
|
63
|
+
const response = new Response(null, { status: 204 });
|
|
64
64
|
if (corsOptions.allowedOrigins === "*") {
|
|
65
65
|
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
66
66
|
} else {
|
|
@@ -256,7 +256,8 @@ function createValidators(context) {
|
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
if (config.requireCsrfToken && sessionData.csrfToken) {
|
|
259
|
-
const
|
|
259
|
+
const cookieStore = await (0, import_headers.cookies)();
|
|
260
|
+
const csrfCookieValue = cookieStore.get("csrfToken")?.value;
|
|
260
261
|
const csrfError = validateCsrfToken(sessionData.csrfToken, csrfCookieValue);
|
|
261
262
|
if (csrfError) {
|
|
262
263
|
return { isValid: false, error: csrfError };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/fnValidators.ts"],"sourcesContent":["import { type NextRequest, NextResponse } from 'next/server';\n\nimport { createApiErrorResponse } from './responses';\nimport type {\n AuthEndpoint,\n ComprehensiveValidationResult,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionSubEndpoint,\n ValidationConfig,\n} from './types';\n\nexport interface RequestContext {\n request: NextRequest;\n origin: string | null;\n host: string | null;\n referer: string | null;\n userAgent: string;\n method: string;\n pathSegments: string[];\n}\n\nexport function createRequestContext(request: NextRequest): RequestContext {\n const url = new URL(request.url);\n const pathSegments = url.pathname.split('/').filter(Boolean);\n\n return {\n request,\n origin: request.headers.get('origin'),\n host: request.headers.get('host'),\n referer: request.headers.get('referer'),\n userAgent: request.headers.get('user-agent') || '',\n method: request.method,\n pathSegments,\n };\n}\n\n/**\n * Main validators factory function\n * Returns an object containing all validator functions and utilities\n */\nexport function createValidators(context: RequestContext) {\n const { request, origin, host, referer, userAgent, method, pathSegments } = context;\n\n async function validateCors(corsOptions: CorsOptions): Promise<NextResponse | null> {\n if (corsOptions.skipSameOrigin) {\n if (!origin || (host && origin.includes(host))) {\n return null;\n }\n }\n\n if (corsOptions.allowedOrigins !== '*') {\n const isAllowed = corsOptions.allowedOrigins.some(allowedOrigin => {\n if (allowedOrigin.startsWith('*')) {\n const domain = allowedOrigin.slice(1);\n return origin?.endsWith(domain);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n return createApiErrorResponse('CORS_ORIGIN_NOT_ALLOWED', 'Origin not allowed', 403);\n }\n }\n\n return null;\n }\n\n function createCorsOptionsResponse(corsOptions: CorsOptions): NextResponse {\n const response = new NextResponse(null, { status: 204 });\n\n if (corsOptions.allowedOrigins === '*') {\n response.headers.set('Access-Control-Allow-Origin', '*');\n } else {\n response.headers.set('Access-Control-Allow-Origin', corsOptions.allowedOrigins.join(','));\n }\n\n response.headers.set(\n 'Access-Control-Allow-Methods',\n corsOptions.allowedMethods?.join(',') || 'GET,POST',\n );\n response.headers.set(\n 'Access-Control-Allow-Headers',\n corsOptions.allowedHeaders?.join(',') || 'Content-Type,Authorization',\n );\n\n if (corsOptions.allowCredentials) {\n response.headers.set('Access-Control-Allow-Credentials', 'true');\n }\n\n if (corsOptions.maxAge) {\n response.headers.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n\n return response;\n }\n\n async function validateSecurity(securityOptions: SecurityOptions): Promise<NextResponse | null> {\n const csrfResult = validateCsrf(securityOptions);\n if (csrfResult) return csrfResult;\n\n const headersResult = validateRequiredHeaders(securityOptions);\n if (headersResult) return headersResult;\n\n const userAgentResult = validateUserAgent(securityOptions);\n if (userAgentResult) return userAgentResult;\n\n return null;\n }\n\n function validateCsrf(securityOptions: SecurityOptions): NextResponse | null {\n if (securityOptions.requireCSRF && origin && host && !origin.includes(host)) {\n const hasCSRFHeader = request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referer && host && referer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referer?.includes(allowedRef),\n );\n\n if (!isAllowedReferer) {\n return createApiErrorResponse('CSRF_PROTECTION', 'Access denied', 403);\n }\n }\n }\n return null;\n }\n\n function validateRequiredHeaders(securityOptions: SecurityOptions): NextResponse | null {\n if (securityOptions.requiredHeaders) {\n for (const [headerName, expectedValue] of Object.entries(securityOptions.requiredHeaders)) {\n const actualValue = request.headers.get(headerName);\n if (actualValue !== expectedValue) {\n return createApiErrorResponse(\n 'INVALID_HEADERS',\n 'Required header missing or invalid',\n 400,\n );\n }\n }\n }\n return null;\n }\n\n function validateUserAgent(securityOptions: SecurityOptions): NextResponse | null {\n if (securityOptions.userAgent?.block?.length) {\n const isBlocked = securityOptions.userAgent.block.some((blocked: string) =>\n userAgent.toLowerCase().includes(blocked.toLowerCase()),\n );\n\n if (isBlocked) {\n return createApiErrorResponse('USER_AGENT_BLOCKED', 'Access denied', 403);\n }\n }\n\n if (securityOptions.userAgent?.allow?.length) {\n const isAllowed = securityOptions.userAgent.allow.some((allowed: string) =>\n userAgent.toLowerCase().includes(allowed.toLowerCase()),\n );\n\n if (!isAllowed) {\n return createApiErrorResponse('USER_AGENT_NOT_ALLOWED', 'Access denied', 403);\n }\n }\n\n return null;\n }\n\n function validateCsrfToken(\n csrfToken: string,\n csrfCookieValue: string | undefined,\n ): NextResponse | null {\n if (!csrfToken) {\n return createApiErrorResponse('INVALID_CSRF_TOKEN', 'CSRF token is required', 400);\n }\n\n if (!csrfCookieValue) {\n return createApiErrorResponse('CSRF_COOKIE_MISSING', 'CSRF token cookie not found', 403);\n }\n\n if (csrfToken !== csrfCookieValue) {\n return createApiErrorResponse('CSRF_TOKEN_MISMATCH', 'CSRF token mismatch', 403);\n }\n\n return null;\n }\n\n function validatePathStructure(): NextResponse | null {\n if (pathSegments.length < 3) {\n return createApiErrorResponse(\n 'INVALID_ROUTE',\n 'Invalid route structure. Expected: /api/auth/{endpoint}',\n 404,\n );\n }\n return null;\n }\n\n function validateEndpoint(\n _endpoint: AuthEndpoint,\n endpointConfig: EndpointConfig,\n ): NextResponse | null {\n if (!endpointConfig || !endpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (method !== 'OPTIONS' && !endpointConfig.methods.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n function validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n ): NextResponse | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n async function validateSessionRequest(): Promise<{\n body: any;\n idToken?: string;\n csrfToken?: string;\n error?: NextResponse;\n }> {\n try {\n const body = await request.json();\n return { body, idToken: body.idToken, csrfToken: body.csrfToken };\n } catch (error) {\n return {\n body: null,\n error: createApiErrorResponse('INVALID_REQUEST_FORMAT', 'Invalid request format', 400),\n };\n }\n }\n\n function validateIdToken(idToken: string | undefined): NextResponse | null {\n if (!idToken) {\n return createApiErrorResponse(\n 'INVALID_TOKEN',\n 'ID token is required for creating session',\n 400,\n );\n }\n return null;\n }\n\n /**\n * Main validation orchestrator function\n * Runs all configured validations in the correct order\n */\n async function validateRequest(config: ValidationConfig): Promise<ComprehensiveValidationResult> {\n if (method === 'OPTIONS' && config.cors) {\n return {\n isValid: true,\n corsResponse: createCorsOptionsResponse(config.cors),\n };\n }\n const pathError = validatePathStructure();\n if (pathError) {\n return { isValid: false, error: pathError };\n }\n\n if (config.cors) {\n const corsError = await validateCors(config.cors);\n if (corsError) {\n return { isValid: false, error: corsError };\n }\n }\n\n if (config.security) {\n const securityError = await validateSecurity(config.security);\n if (securityError) {\n return { isValid: false, error: securityError };\n }\n }\n\n if (config.endpoint) {\n const endpointError = validateEndpoint(config.endpoint.name, config.endpoint.config);\n if (endpointError) {\n return { isValid: false, error: endpointError };\n }\n }\n\n if (config.subEndpoint) {\n const subEndpointError = validateSubEndpoint(\n config.subEndpoint.name,\n config.subEndpoint.config,\n );\n if (subEndpointError) {\n return { isValid: false, error: subEndpointError };\n }\n }\n\n let sessionData;\n if (method === 'POST' && (config.requireIdToken || config.requireCsrfToken)) {\n const sessionResult = await validateSessionRequest();\n if (sessionResult.error) {\n return { isValid: false, error: sessionResult.error };\n }\n\n sessionData = sessionResult;\n\n if (config.requireIdToken) {\n const idTokenError = validateIdToken(sessionData.idToken);\n if (idTokenError) {\n return { isValid: false, error: idTokenError };\n }\n }\n\n if (config.requireCsrfToken && sessionData.csrfToken) {\n const csrfCookieValue = request.cookies.get('csrfToken')?.value;\n const csrfError = validateCsrfToken(sessionData.csrfToken, csrfCookieValue);\n if (csrfError) {\n return { isValid: false, error: csrfError };\n }\n }\n }\n\n return {\n isValid: true,\n sessionData,\n };\n }\n\n /**\n * Convenience function for quick validation setup\n */\n function createValidationConfig(overrides: Partial<ValidationConfig> = {}): ValidationConfig {\n return {\n ...overrides,\n };\n }\n\n return {\n createValidationConfig,\n\n validateRequest,\n\n validateCors,\n validateSecurity,\n validatePathStructure,\n validateEndpoint,\n validateSubEndpoint,\n validateSessionRequest,\n validateIdToken,\n validateCsrfToken,\n\n createCorsOptionsResponse,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/fnValidators.ts"],"sourcesContent":["import { cookies } from 'next/headers';\n\nimport { createApiErrorResponse } from './responses';\nimport type {\n AuthEndpoint,\n ComprehensiveValidationResult,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionSubEndpoint,\n ValidationConfig,\n} from './types';\n//import type { RequestProcessorContext } from './claude-authenticateRequestProcessor';\n\nexport interface RequestContext {\n request: Request;\n origin: string | null;\n host: string | null;\n referer: string | null;\n userAgent: string;\n method: string;\n pathSegments: string[];\n}\n\nexport function createRequestContext(request: Request): RequestContext {\n const url = new URL(request.url);\n const pathSegments = url.pathname.split('/').filter(Boolean);\n\n return {\n request,\n origin: request.headers.get('origin'),\n host: request.headers.get('host'),\n referer: request.headers.get('referer'),\n userAgent: request.headers.get('user-agent') || '',\n method: request.method,\n pathSegments,\n };\n}\n\n/**\n * Main validators factory function\n * Returns an object containing all validator functions and utilities\n */\nexport function createValidators(context: RequestContext) {\n const { request, origin, host, referer, userAgent, method, pathSegments } = context;\n\n async function validateCors(corsOptions: CorsOptions): Promise<Response | null> {\n if (corsOptions.skipSameOrigin) {\n if (!origin || (host && origin.includes(host))) {\n return null;\n }\n }\n\n if (corsOptions.allowedOrigins !== '*') {\n const isAllowed = corsOptions.allowedOrigins.some(allowedOrigin => {\n if (allowedOrigin.startsWith('*')) {\n const domain = allowedOrigin.slice(1);\n return origin?.endsWith(domain);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n return createApiErrorResponse('CORS_ORIGIN_NOT_ALLOWED', 'Origin not allowed', 403);\n }\n }\n\n return null;\n }\n\n function createCorsOptionsResponse(corsOptions: CorsOptions): Response {\n const response = new Response(null, { status: 204 });\n\n if (corsOptions.allowedOrigins === '*') {\n response.headers.set('Access-Control-Allow-Origin', '*');\n } else {\n response.headers.set('Access-Control-Allow-Origin', corsOptions.allowedOrigins.join(','));\n }\n\n response.headers.set(\n 'Access-Control-Allow-Methods',\n corsOptions.allowedMethods?.join(',') || 'GET,POST',\n );\n response.headers.set(\n 'Access-Control-Allow-Headers',\n corsOptions.allowedHeaders?.join(',') || 'Content-Type,Authorization',\n );\n\n if (corsOptions.allowCredentials) {\n response.headers.set('Access-Control-Allow-Credentials', 'true');\n }\n\n if (corsOptions.maxAge) {\n response.headers.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n\n return response;\n }\n\n async function validateSecurity(securityOptions: SecurityOptions): Promise<Response | null> {\n const csrfResult = validateCsrf(securityOptions);\n if (csrfResult) return csrfResult;\n\n const headersResult = validateRequiredHeaders(securityOptions);\n if (headersResult) return headersResult;\n\n const userAgentResult = validateUserAgent(securityOptions);\n if (userAgentResult) return userAgentResult;\n\n return null;\n }\n\n function validateCsrf(securityOptions: SecurityOptions): Response | null {\n if (securityOptions.requireCSRF && origin && host && !origin.includes(host)) {\n const hasCSRFHeader = request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referer && host && referer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referer?.includes(allowedRef),\n );\n\n if (!isAllowedReferer) {\n return createApiErrorResponse('CSRF_PROTECTION', 'Access denied', 403);\n }\n }\n }\n return null;\n }\n\n function validateRequiredHeaders(securityOptions: SecurityOptions): Response | null {\n if (securityOptions.requiredHeaders) {\n for (const [headerName, expectedValue] of Object.entries(securityOptions.requiredHeaders)) {\n const actualValue = request.headers.get(headerName);\n if (actualValue !== expectedValue) {\n return createApiErrorResponse(\n 'INVALID_HEADERS',\n 'Required header missing or invalid',\n 400,\n );\n }\n }\n }\n return null;\n }\n\n function validateUserAgent(securityOptions: SecurityOptions): Response | null {\n if (securityOptions.userAgent?.block?.length) {\n const isBlocked = securityOptions.userAgent.block.some((blocked: string) =>\n userAgent.toLowerCase().includes(blocked.toLowerCase()),\n );\n\n if (isBlocked) {\n return createApiErrorResponse('USER_AGENT_BLOCKED', 'Access denied', 403);\n }\n }\n\n if (securityOptions.userAgent?.allow?.length) {\n const isAllowed = securityOptions.userAgent.allow.some((allowed: string) =>\n userAgent.toLowerCase().includes(allowed.toLowerCase()),\n );\n\n if (!isAllowed) {\n return createApiErrorResponse('USER_AGENT_NOT_ALLOWED', 'Access denied', 403);\n }\n }\n\n return null;\n }\n\n function validateCsrfToken(\n csrfToken: string,\n csrfCookieValue: string | undefined,\n ): Response | null {\n if (!csrfToken) {\n return createApiErrorResponse('INVALID_CSRF_TOKEN', 'CSRF token is required', 400);\n }\n\n if (!csrfCookieValue) {\n return createApiErrorResponse('CSRF_COOKIE_MISSING', 'CSRF token cookie not found', 403);\n }\n\n if (csrfToken !== csrfCookieValue) {\n return createApiErrorResponse('CSRF_TOKEN_MISMATCH', 'CSRF token mismatch', 403);\n }\n\n return null;\n }\n\n function validatePathStructure(): Response | null {\n if (pathSegments.length < 3) {\n return createApiErrorResponse(\n 'INVALID_ROUTE',\n 'Invalid route structure. Expected: /api/auth/{endpoint}',\n 404,\n );\n }\n return null;\n }\n\n function validateEndpoint(\n _endpoint: AuthEndpoint,\n endpointConfig: EndpointConfig,\n ): Response | null {\n if (!endpointConfig || !endpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (method !== 'OPTIONS' && !endpointConfig.methods.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n function validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n ): Response | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n async function validateSessionRequest(): Promise<{\n body: any;\n idToken?: string;\n csrfToken?: string;\n error?: Response;\n }> {\n try {\n const body = await request.json();\n return { body, idToken: body.idToken, csrfToken: body.csrfToken };\n } catch (error) {\n return {\n body: null,\n error: createApiErrorResponse('INVALID_REQUEST_FORMAT', 'Invalid request format', 400),\n };\n }\n }\n\n function validateIdToken(idToken: string | undefined): Response | null {\n if (!idToken) {\n return createApiErrorResponse(\n 'INVALID_TOKEN',\n 'ID token is required for creating session',\n 400,\n );\n }\n return null;\n }\n\n /**\n * Main validation orchestrator function\n * Runs all configured validations in the correct order\n */\n async function validateRequest(config: ValidationConfig): Promise<ComprehensiveValidationResult> {\n if (method === 'OPTIONS' && config.cors) {\n return {\n isValid: true,\n corsResponse: createCorsOptionsResponse(config.cors),\n };\n }\n const pathError = validatePathStructure();\n if (pathError) {\n return { isValid: false, error: pathError };\n }\n\n if (config.cors) {\n const corsError = await validateCors(config.cors);\n if (corsError) {\n return { isValid: false, error: corsError };\n }\n }\n\n if (config.security) {\n const securityError = await validateSecurity(config.security);\n if (securityError) {\n return { isValid: false, error: securityError };\n }\n }\n\n if (config.endpoint) {\n const endpointError = validateEndpoint(config.endpoint.name, config.endpoint.config);\n if (endpointError) {\n return { isValid: false, error: endpointError };\n }\n }\n\n if (config.subEndpoint) {\n const subEndpointError = validateSubEndpoint(\n config.subEndpoint.name,\n config.subEndpoint.config,\n );\n if (subEndpointError) {\n return { isValid: false, error: subEndpointError };\n }\n }\n\n let sessionData;\n if (method === 'POST' && (config.requireIdToken || config.requireCsrfToken)) {\n const sessionResult = await validateSessionRequest();\n if (sessionResult.error) {\n return { isValid: false, error: sessionResult.error };\n }\n\n sessionData = sessionResult;\n\n if (config.requireIdToken) {\n const idTokenError = validateIdToken(sessionData.idToken);\n if (idTokenError) {\n return { isValid: false, error: idTokenError };\n }\n }\n\n if (config.requireCsrfToken && sessionData.csrfToken) {\n const cookieStore = await cookies();\n const csrfCookieValue = cookieStore.get('csrfToken')?.value;\n const csrfError = validateCsrfToken(sessionData.csrfToken, csrfCookieValue);\n if (csrfError) {\n return { isValid: false, error: csrfError };\n }\n }\n }\n\n return {\n isValid: true,\n sessionData,\n };\n }\n\n /**\n * Convenience function for quick validation setup\n */\n function createValidationConfig(overrides: Partial<ValidationConfig> = {}): ValidationConfig {\n return {\n ...overrides,\n };\n }\n\n return {\n createValidationConfig,\n\n validateRequest,\n\n validateCors,\n validateSecurity,\n validatePathStructure,\n validateEndpoint,\n validateSubEndpoint,\n validateSessionRequest,\n validateIdToken,\n validateCsrfToken,\n\n createCorsOptionsResponse,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var handlerUtils_exports = {};
|
|
20
|
+
__export(handlerUtils_exports, {
|
|
21
|
+
RequestContextBuilder: () => RequestContextBuilder,
|
|
22
|
+
ValidationPipeline: () => ValidationPipeline
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(handlerUtils_exports);
|
|
25
|
+
var import_fnValidators = require("./fnValidators");
|
|
26
|
+
class RequestContextBuilder {
|
|
27
|
+
static create(request) {
|
|
28
|
+
const context = (0, import_fnValidators.createRequestContext)(request);
|
|
29
|
+
const { pathSegments } = context;
|
|
30
|
+
return {
|
|
31
|
+
request,
|
|
32
|
+
pathSegments,
|
|
33
|
+
endpoint: pathSegments[2],
|
|
34
|
+
subEndpoint: pathSegments[3],
|
|
35
|
+
method: request.method
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
class ValidationPipeline {
|
|
40
|
+
config;
|
|
41
|
+
context;
|
|
42
|
+
constructor(config, context) {
|
|
43
|
+
this.config = config;
|
|
44
|
+
this.context = context;
|
|
45
|
+
}
|
|
46
|
+
async execute() {
|
|
47
|
+
const validators = (0, import_fnValidators.createValidators)(this.context);
|
|
48
|
+
const corsError = await validators.validateCors(this.config.cors);
|
|
49
|
+
if (corsError) return corsError;
|
|
50
|
+
if (this.context.method === "OPTIONS") {
|
|
51
|
+
return validators.createCorsOptionsResponse(this.config.cors);
|
|
52
|
+
}
|
|
53
|
+
const securityError = await validators.validateSecurity(this.config.security);
|
|
54
|
+
if (securityError) return securityError;
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
59
|
+
0 && (module.exports = {
|
|
60
|
+
RequestContextBuilder,
|
|
61
|
+
ValidationPipeline
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=handlerUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/handlerUtils.ts"],"sourcesContent":["import type { RequestContext } from './fnValidators';\nimport { createRequestContext, createValidators } from './fnValidators';\nimport type {\n AuthEndpoint,\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n} from './types';\n\nexport interface HandlerContext {\n request: Request;\n pathSegments: string[];\n endpoint: AuthEndpoint;\n subEndpoint: SessionSubEndpoint | undefined;\n method: string;\n}\n\nexport class RequestContextBuilder {\n static create(request: Request): HandlerContext {\n const context = createRequestContext(request);\n const { pathSegments } = context;\n\n return {\n request,\n pathSegments,\n endpoint: pathSegments[2] as AuthEndpoint,\n subEndpoint: pathSegments[3] as SessionSubEndpoint | undefined,\n method: request.method,\n };\n }\n}\n\nexport class ValidationPipeline {\n private readonly config: Required<TernSecureHandlerOptions>;\n private readonly context: RequestContext;\n\n constructor(\n config: Required<TernSecureHandlerOptions>,\n context: RequestContext,\n ) {\n this.config = config;\n this.context = context;\n }\n\n async execute(): Promise<Response | null> {\n const validators = createValidators(this.context);\n\n const corsError = await validators.validateCors(this.config.cors);\n if (corsError) return corsError;\n\n if (this.context.method === 'OPTIONS') {\n return validators.createCorsOptionsResponse(this.config.cors);\n }\n\n const securityError = await validators.validateSecurity(this.config.security);\n if (securityError) return securityError;\n\n return null;\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAuD;AAehD,MAAM,sBAAsB;AAAA,EACjC,OAAO,OAAO,SAAkC;AAC9C,UAAM,cAAU,0CAAqB,OAAO;AAC5C,UAAM,EAAE,aAAa,IAAI;AAEzB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,aAAa,CAAC;AAAA,MACxB,aAAa,aAAa,CAAC;AAAA,MAC3B,QAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AACF;AAEO,MAAM,mBAAmB;AAAA,EACb;AAAA,EACA;AAAA,EAEjB,YACE,QACA,SACA;AACA,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,UAAoC;AACxC,UAAM,iBAAa,sCAAiB,KAAK,OAAO;AAEhD,UAAM,YAAY,MAAM,WAAW,aAAa,KAAK,OAAO,IAAI;AAChE,QAAI,UAAW,QAAO;AAEtB,QAAI,KAAK,QAAQ,WAAW,WAAW;AACrC,aAAO,WAAW,0BAA0B,KAAK,OAAO,IAAI;AAAA,IAC9D;AAEA,UAAM,gBAAgB,MAAM,WAAW,iBAAiB,KAAK,OAAO,QAAQ;AAC5E,QAAI,cAAe,QAAO;AAE1B,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -18,6 +18,9 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var admin_exports = {};
|
|
20
20
|
__export(admin_exports, {
|
|
21
|
+
EndpointRouter: () => import_endpointRouter.EndpointRouter,
|
|
22
|
+
RequestContextBuilder: () => import_handlerUtils.RequestContextBuilder,
|
|
23
|
+
ValidationPipeline: () => import_handlerUtils.ValidationPipeline,
|
|
21
24
|
clearNextSessionCookie: () => import_actions.clearNextSessionCookie,
|
|
22
25
|
clearSessionCookieServer: () => import_actions.clearSessionCookieServer,
|
|
23
26
|
createNextSessionCookie: () => import_actions.createNextSessionCookie,
|
|
@@ -29,8 +32,13 @@ __export(admin_exports, {
|
|
|
29
32
|
module.exports = __toCommonJS(admin_exports);
|
|
30
33
|
var import_ternsecureNextjsHandler = require("./ternsecureNextjsHandler");
|
|
31
34
|
var import_actions = require("./actions");
|
|
35
|
+
var import_endpointRouter = require("./endpointRouter");
|
|
36
|
+
var import_handlerUtils = require("./handlerUtils");
|
|
32
37
|
// Annotate the CommonJS export names for ESM import in node:
|
|
33
38
|
0 && (module.exports = {
|
|
39
|
+
EndpointRouter,
|
|
40
|
+
RequestContextBuilder,
|
|
41
|
+
ValidationPipeline,
|
|
34
42
|
clearNextSessionCookie,
|
|
35
43
|
clearSessionCookieServer,
|
|
36
44
|
createNextSessionCookie,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/index.ts"],"sourcesContent":["export { createTernSecureNextJsHandler } from './ternsecureNextjsHandler'\n\nexport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/index.ts"],"sourcesContent":["export { createTernSecureNextJsHandler } from './ternsecureNextjsHandler'\n\nexport {\n clearSessionCookieServer,\n clearNextSessionCookie,\n createSessionCookieServer,\n createNextSessionCookie,\n setNextServerSession,\n setNextServerToken\n} from './actions'\n\nexport { EndpointRouter } from './endpointRouter'\nexport { RequestContextBuilder, ValidationPipeline } from './handlerUtils'\nexport type { HandlerContext } from './handlerUtils'\n\nexport type { TernSecureHandlerOptions, TernSecureInternalHandlerConfig } from './types'"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAA8C;AAE9C,qBAOO;AAEP,4BAA+B;AAC/B,0BAA0D;","names":[]}
|
|
@@ -35,26 +35,28 @@ __export(sessionHandlers_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(sessionHandlers_exports);
|
|
36
36
|
var import_admin = require("@tern-secure/backend/admin");
|
|
37
37
|
var import_jwt = require("@tern-secure/backend/jwt");
|
|
38
|
+
var import_headers = require("next/headers");
|
|
38
39
|
var import_NextCookieAdapter = require("../../utils/NextCookieAdapter");
|
|
39
40
|
var import_responses = require("./responses");
|
|
40
41
|
var import_validators = require("./validators");
|
|
41
42
|
class SessionGetHandler {
|
|
42
|
-
static async handle(
|
|
43
|
+
static async handle(subEndpoint, _config) {
|
|
43
44
|
switch (subEndpoint) {
|
|
44
45
|
case "verify":
|
|
45
|
-
return this.handleVerify(
|
|
46
|
+
return this.handleVerify();
|
|
46
47
|
default:
|
|
47
48
|
return import_responses.HttpResponseHelper.createNotFoundResponse();
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
|
-
static async handleVerify(
|
|
51
|
+
static async handleVerify() {
|
|
51
52
|
try {
|
|
52
|
-
const
|
|
53
|
+
const cookieStore = await (0, import_headers.cookies)();
|
|
54
|
+
const sessionCookie = cookieStore.get("_session_cookie")?.value;
|
|
53
55
|
if (!sessionCookie) {
|
|
54
56
|
return import_responses.SessionResponseHelper.createUnauthorizedResponse();
|
|
55
57
|
}
|
|
56
|
-
const decodedSession = (0, import_jwt.ternDecodeJwtUnguarded)(sessionCookie);
|
|
57
|
-
if (
|
|
58
|
+
const { data: decodedSession, errors } = (0, import_jwt.ternDecodeJwtUnguarded)(sessionCookie);
|
|
59
|
+
if (errors) {
|
|
58
60
|
return import_responses.SessionResponseHelper.createUnauthorizedResponse();
|
|
59
61
|
}
|
|
60
62
|
return import_responses.SessionResponseHelper.createVerificationResponse(decodedSession);
|
|
@@ -68,8 +70,8 @@ class SessionPostHandler {
|
|
|
68
70
|
const cookieStore = new import_NextCookieAdapter.NextCookieStore();
|
|
69
71
|
const { idToken, csrfToken, error } = await import_validators.RequestValidator.validateSessionRequest(request);
|
|
70
72
|
if (error) return error;
|
|
71
|
-
const csrfCookieValue =
|
|
72
|
-
const csrfValidationError = import_validators.CsrfValidator.validate(csrfToken || "", csrfCookieValue);
|
|
73
|
+
const csrfCookieValue = await cookieStore.get("_session_terncf");
|
|
74
|
+
const csrfValidationError = import_validators.CsrfValidator.validate(csrfToken || "", csrfCookieValue.value);
|
|
73
75
|
if (csrfValidationError) return csrfValidationError;
|
|
74
76
|
const options = {
|
|
75
77
|
tenantId: _config.tenantId
|
|
@@ -78,7 +80,7 @@ class SessionPostHandler {
|
|
|
78
80
|
case "createsession":
|
|
79
81
|
return this.handleCreateSession(options, idToken, cookieStore);
|
|
80
82
|
case "refresh":
|
|
81
|
-
return this.handleRefreshSession(
|
|
83
|
+
return this.handleRefreshSession(cookieStore);
|
|
82
84
|
case "revoke":
|
|
83
85
|
return this.handleRevokeSession(cookieStore);
|
|
84
86
|
default:
|
|
@@ -98,13 +100,13 @@ class SessionPostHandler {
|
|
|
98
100
|
return (0, import_responses.createApiErrorResponse)("SESSION_CREATION_FAILED", "Session creation failed", 500);
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
|
-
static async handleRefreshSession(
|
|
102
|
-
const currentSessionCookie =
|
|
103
|
+
static async handleRefreshSession(cookieStore) {
|
|
104
|
+
const currentSessionCookie = await cookieStore.get("__session");
|
|
103
105
|
if (!currentSessionCookie) {
|
|
104
106
|
return (0, import_responses.createApiErrorResponse)("NO_SESSION", "No session to refresh", 401);
|
|
105
107
|
}
|
|
106
108
|
try {
|
|
107
|
-
const decodedSession = (0, import_jwt.ternDecodeJwtUnguarded)(currentSessionCookie);
|
|
109
|
+
const decodedSession = (0, import_jwt.ternDecodeJwtUnguarded)(currentSessionCookie.value || "");
|
|
108
110
|
if (decodedSession.errors) {
|
|
109
111
|
return (0, import_responses.createApiErrorResponse)("INVALID_SESSION", "Invalid session for refresh", 401);
|
|
110
112
|
}
|
|
@@ -138,7 +140,7 @@ class SessionEndpointHandler {
|
|
|
138
140
|
}
|
|
139
141
|
switch (method) {
|
|
140
142
|
case "GET":
|
|
141
|
-
return SessionGetHandler.handle(
|
|
143
|
+
return SessionGetHandler.handle(subEndpoint, config);
|
|
142
144
|
case "POST":
|
|
143
145
|
return SessionPostHandler.handle(request, subEndpoint, config);
|
|
144
146
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import type { RequestOptions } from '@tern-secure/backend';\nimport { clearSessionCookie, createSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import type { RequestOptions } from '@tern-secure/backend';\nimport { clearSessionCookie, createSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded} from '@tern-secure/backend/jwt';\nimport { cookies } from 'next/headers';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { createApiErrorResponse, HttpResponseHelper, SessionResponseHelper } from './responses';\nimport type {\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n TernSecureInternalHandlerConfig,\n} from './types';\nimport { CsrfValidator, RequestValidator } from './validators';\n\n/**\n * Session GET request handlers\n */\nexport class SessionGetHandler {\n static async handle(\n subEndpoint: SessionSubEndpoint,\n _config: Required<TernSecureHandlerOptions>,\n ): Promise<Response> {\n switch (subEndpoint) {\n case 'verify':\n return this.handleVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n }\n\n private static async handleVerify(): Promise<Response> {\n try {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get('_session_cookie')?.value;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n }\n}\n\n/**\n * Session POST request handlers\n */\nexport class SessionPostHandler {\n static async handle(\n request: Request,\n subEndpoint: SessionSubEndpoint,\n _config: TernSecureInternalHandlerConfig,\n ): Promise<Response> {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await RequestValidator.validateSessionRequest(request);\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get('_session_terncf');\n const csrfValidationError = CsrfValidator.validate(csrfToken || '', csrfCookieValue.value);\n if (csrfValidationError) return csrfValidationError;\n\n const options = {\n tenantId: _config.tenantId,\n };\n\n switch (subEndpoint) {\n case 'createsession':\n return this.handleCreateSession(options, idToken, cookieStore);\n case 'refresh':\n return this.handleRefreshSession(cookieStore);\n case 'revoke':\n return this.handleRevokeSession(cookieStore);\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n }\n\n private static async handleCreateSession(\n options: RequestOptions,\n idToken: string | undefined,\n cookieStore: NextCookieStore,\n ): Promise<Response> {\n const validationError = RequestValidator.validateIdToken(idToken);\n if (validationError) return validationError;\n if (!idToken) {\n return createApiErrorResponse('ID_TOKEN_REQUIRED', 'ID token is required', 400);\n }\n\n try {\n const res = await createSessionCookie(idToken, cookieStore, options);\n return SessionResponseHelper.createSessionCreationResponse(res);\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 500);\n }\n }\n\n private static async handleRefreshSession(\n cookieStore: NextCookieStore,\n ): Promise<Response> {\n const currentSessionCookie = await cookieStore.get('__session');\n if (!currentSessionCookie) {\n return createApiErrorResponse('NO_SESSION', 'No session to refresh', 401);\n }\n\n try {\n const decodedSession = ternDecodeJwtUnguarded(currentSessionCookie.value || '');\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await createSessionCookie(\n decodedSession.data?.payload?.sub || '',\n cookieStore,\n );\n\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 500);\n }\n }\n\n private static async handleRevokeSession(cookieStore: NextCookieStore): Promise<Response> {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n }\n}\n\n/**\n * Main session endpoint orchestrator\n */\nexport class SessionEndpointHandler {\n static async handle(\n request: Request,\n method: string,\n subEndpoint: SessionSubEndpoint | undefined,\n config: Required<TernSecureHandlerOptions>,\n ): Promise<Response> {\n const sessionsConfig = config.endpoints.sessions;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n const subEndpointValidation = this.validateSubEndpoint(subEndpoint, subEndpointConfig, method);\n if (subEndpointValidation) return subEndpointValidation;\n\n if (subEndpointConfig?.security) {\n const { SecurityValidator } = await import('./validators.js');\n const securityResult = await SecurityValidator.validate(request, subEndpointConfig.security);\n if (securityResult) return securityResult;\n }\n\n switch (method) {\n case 'GET':\n return SessionGetHandler.handle(subEndpoint, config);\n case 'POST':\n return SessionPostHandler.handle(request, subEndpoint, config);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n }\n\n private static validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n method: string,\n ): Response | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n}\n"],"mappings":"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","names":[]}
|