@tern-secure/nextjs 5.2.0-canary.v20251108045933 → 5.2.0-canary.v20251127221555
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/actions.js +5 -0
- package/dist/cjs/app-router/admin/actions.js.map +1 -1
- package/dist/cjs/app-router/admin/c-authenticateRequestProcessor.js +1 -0
- package/dist/cjs/app-router/admin/c-authenticateRequestProcessor.js.map +1 -1
- package/dist/cjs/app-router/admin/endpointRouter.js +10 -1
- package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -1
- package/dist/cjs/app-router/admin/fnValidators.js +7 -0
- package/dist/cjs/app-router/admin/fnValidators.js.map +1 -1
- package/dist/cjs/app-router/admin/request.js +5 -2
- package/dist/cjs/app-router/admin/request.js.map +1 -1
- package/dist/cjs/app-router/admin/sessionHandlers.js +92 -11
- package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/cjs/app-router/admin/signInCreateHandler.js +213 -0
- package/dist/cjs/app-router/admin/signInCreateHandler.js.map +1 -0
- package/dist/cjs/app-router/admin/types.js +14 -1
- package/dist/cjs/app-router/admin/types.js.map +1 -1
- package/dist/cjs/app-router/client/TernSecureProvider.js +5 -1
- package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/cjs/boundary/components.js +2 -12
- package/dist/cjs/boundary/components.js.map +1 -1
- package/dist/cjs/components/uiComponents.js +42 -0
- package/dist/cjs/components/uiComponents.js.map +1 -0
- package/dist/cjs/index.js +9 -12
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/data/getAuthDataFromRequest.js +8 -2
- package/dist/cjs/server/data/getAuthDataFromRequest.js.map +1 -1
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/server/ternSecureProxy.js +27 -3
- package/dist/cjs/server/ternSecureProxy.js.map +1 -1
- package/dist/cjs/server/utils.js +3 -2
- package/dist/cjs/server/utils.js.map +1 -1
- package/dist/cjs/utils/allNextProviderProps.js +16 -3
- package/dist/cjs/utils/allNextProviderProps.js.map +1 -1
- package/dist/cjs/utils/tern-ui-script.js +72 -0
- package/dist/cjs/utils/tern-ui-script.js.map +1 -0
- package/dist/esm/app-router/admin/actions.js +5 -0
- package/dist/esm/app-router/admin/actions.js.map +1 -1
- package/dist/esm/app-router/admin/c-authenticateRequestProcessor.js +1 -0
- package/dist/esm/app-router/admin/c-authenticateRequestProcessor.js.map +1 -1
- package/dist/esm/app-router/admin/endpointRouter.js +11 -2
- package/dist/esm/app-router/admin/endpointRouter.js.map +1 -1
- package/dist/esm/app-router/admin/fnValidators.js +7 -0
- package/dist/esm/app-router/admin/fnValidators.js.map +1 -1
- package/dist/esm/app-router/admin/request.js +5 -2
- package/dist/esm/app-router/admin/request.js.map +1 -1
- package/dist/esm/app-router/admin/sessionHandlers.js +96 -11
- package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/esm/app-router/admin/signInCreateHandler.js +188 -0
- package/dist/esm/app-router/admin/signInCreateHandler.js.map +1 -0
- package/dist/esm/app-router/admin/types.js +13 -1
- package/dist/esm/app-router/admin/types.js.map +1 -1
- package/dist/esm/app-router/client/TernSecureProvider.js +6 -2
- package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/esm/boundary/components.js +1 -11
- package/dist/esm/boundary/components.js.map +1 -1
- package/dist/esm/components/uiComponents.js +21 -0
- package/dist/esm/components/uiComponents.js.map +1 -0
- package/dist/esm/index.js +10 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/data/getAuthDataFromRequest.js +9 -3
- package/dist/esm/server/data/getAuthDataFromRequest.js.map +1 -1
- package/dist/esm/server/index.js +1 -3
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/server/ternSecureProxy.js +28 -4
- package/dist/esm/server/ternSecureProxy.js.map +1 -1
- package/dist/esm/server/utils.js +3 -2
- package/dist/esm/server/utils.js.map +1 -1
- package/dist/esm/utils/allNextProviderProps.js +16 -3
- package/dist/esm/utils/allNextProviderProps.js.map +1 -1
- package/dist/esm/utils/tern-ui-script.js +38 -0
- package/dist/esm/utils/tern-ui-script.js.map +1 -0
- package/dist/types/app-router/admin/actions.d.ts +23 -0
- package/dist/types/app-router/admin/actions.d.ts.map +1 -1
- package/dist/types/app-router/admin/c-authenticateRequestProcessor.d.ts +1 -0
- package/dist/types/app-router/admin/c-authenticateRequestProcessor.d.ts.map +1 -1
- package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -1
- package/dist/types/app-router/admin/fnValidators.d.ts.map +1 -1
- package/dist/types/app-router/admin/request.d.ts +1 -1
- package/dist/types/app-router/admin/request.d.ts.map +1 -1
- package/dist/types/app-router/admin/sessionHandlers.d.ts +4 -3
- package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
- package/dist/types/app-router/admin/signInCreateHandler.d.ts +11 -0
- package/dist/types/app-router/admin/signInCreateHandler.d.ts.map +1 -0
- package/dist/types/app-router/admin/types.d.ts +3 -2
- package/dist/types/app-router/admin/types.d.ts.map +1 -1
- package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
- package/dist/types/boundary/components.d.ts +1 -1
- package/dist/types/boundary/components.d.ts.map +1 -1
- package/dist/types/components/uiComponents.d.ts +6 -0
- package/dist/types/components/uiComponents.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/server/data/getAuthDataFromRequest.d.ts.map +1 -1
- package/dist/types/server/index.d.ts +1 -1
- package/dist/types/server/index.d.ts.map +1 -1
- package/dist/types/server/ternSecureProxy.d.ts.map +1 -1
- package/dist/types/server/utils.d.ts +1 -1
- package/dist/types/server/utils.d.ts.map +1 -1
- package/dist/types/utils/allNextProviderProps.d.ts.map +1 -1
- package/dist/types/utils/tern-ui-script.d.ts +8 -0
- package/dist/types/utils/tern-ui-script.d.ts.map +1 -0
- package/package.json +5 -5
|
@@ -19,6 +19,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
19
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
20
|
var actions_exports = {};
|
|
21
21
|
__export(actions_exports, {
|
|
22
|
+
RetrieveUser: () => RetrieveUser,
|
|
22
23
|
clearNextSessionCookie: () => clearNextSessionCookie,
|
|
23
24
|
clearSessionCookieServer: () => clearSessionCookieServer,
|
|
24
25
|
createNextSessionCookie: () => createNextSessionCookie,
|
|
@@ -56,8 +57,12 @@ async function createNextSessionCookie(idToken) {
|
|
|
56
57
|
async function verifyNextTernIdToken(idToken) {
|
|
57
58
|
return (0, import_admin.VerifyNextTernIdToken)(idToken);
|
|
58
59
|
}
|
|
60
|
+
function RetrieveUser() {
|
|
61
|
+
return (0, import_admin.RetrieveUser)(import_constants.TENANT_ID);
|
|
62
|
+
}
|
|
59
63
|
// Annotate the CommonJS export names for ESM import in node:
|
|
60
64
|
0 && (module.exports = {
|
|
65
|
+
RetrieveUser,
|
|
61
66
|
clearNextSessionCookie,
|
|
62
67
|
clearSessionCookieServer,
|
|
63
68
|
createNextSessionCookie,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/actions.ts"],"sourcesContent":["'use server';\n\nimport {\n ClearNextSessionCookie,\n clearSessionCookie,\n CreateNextSessionCookie,\n createSessionCookie,\n SetNextServerSession,\n SetNextServerToken,\n VerifyNextTernIdToken
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/actions.ts"],"sourcesContent":["'use server';\n\nimport {\n ClearNextSessionCookie,\n clearSessionCookie,\n CreateNextSessionCookie,\n createSessionCookie,\n RetrieveUser as RetrieveUserBackend,\n SetNextServerSession,\n SetNextServerToken,\n VerifyNextTernIdToken,\n} from '@tern-secure/backend/admin';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { TENANT_ID } from './constants';\nimport { getDeleteOptions } from './cookieOptionsHelper';\nimport type { TernSecureHandlerOptions } from './types';\n\nexport async function createSessionCookieServer(idToken: string) {\n const cookieStore = new NextCookieStore();\n return createSessionCookie(idToken, cookieStore);\n}\n\nexport async function clearSessionCookieServer() {\n const cookieStore = new NextCookieStore();\n return clearSessionCookie(cookieStore);\n}\n\nexport async function clearNextSessionCookie(options?: {\n cookies?: TernSecureHandlerOptions['cookies'];\n revokeRefreshTokensOnSignOut?: boolean;\n}) {\n const deleteOptions = getDeleteOptions(options);\n return ClearNextSessionCookie(TENANT_ID, deleteOptions);\n}\n\nexport async function setNextServerSession(idToken: string) {\n return SetNextServerSession(idToken);\n}\n\nexport async function setNextServerToken(token: string) {\n return SetNextServerToken(token);\n}\n\nexport async function createNextSessionCookie(idToken: string) {\n return CreateNextSessionCookie(idToken);\n}\n\nexport async function verifyNextTernIdToken(idToken: string) {\n return VerifyNextTernIdToken(idToken);\n}\n\nexport function RetrieveUser() {\n return RetrieveUserBackend(TENANT_ID);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBASO;AAEP,+BAAgC;AAChC,uBAA0B;AAC1B,iCAAiC;AAGjC,eAAsB,0BAA0B,SAAiB;AAC/D,QAAM,cAAc,IAAI,yCAAgB;AACxC,aAAO,kCAAoB,SAAS,WAAW;AACjD;AAEA,eAAsB,2BAA2B;AAC/C,QAAM,cAAc,IAAI,yCAAgB;AACxC,aAAO,iCAAmB,WAAW;AACvC;AAEA,eAAsB,uBAAuB,SAG1C;AACD,QAAM,oBAAgB,6CAAiB,OAAO;AAC9C,aAAO,qCAAuB,4BAAW,aAAa;AACxD;AAEA,eAAsB,qBAAqB,SAAiB;AAC1D,aAAO,mCAAqB,OAAO;AACrC;AAEA,eAAsB,mBAAmB,OAAe;AACtD,aAAO,iCAAmB,KAAK;AACjC;AAEA,eAAsB,wBAAwB,SAAiB;AAC7D,aAAO,sCAAwB,OAAO;AACxC;AAEA,eAAsB,sBAAsB,SAAiB;AAC3D,aAAO,oCAAsB,OAAO;AACtC;AAEO,SAAS,eAAe;AAC7B,aAAO,aAAAA,cAAoB,0BAAS;AACtC;","names":["RetrieveUserBackend"]}
|
|
@@ -47,6 +47,7 @@ class RequestProcessorContext {
|
|
|
47
47
|
this.userAgent = this.getHeader(import_backend.constants.Headers.UserAgent);
|
|
48
48
|
this.secFetchDest = this.getHeader(import_backend.constants.Headers.SecFetchDest);
|
|
49
49
|
this.accept = this.getHeader(import_backend.constants.Headers.Accept);
|
|
50
|
+
this.appCheckToken = this.getHeader(import_backend.constants.Headers.AppCheckToken);
|
|
50
51
|
}
|
|
51
52
|
initCookieValues() {
|
|
52
53
|
const isProduction = process.env.NODE_ENV === "production";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/c-authenticateRequestProcessor.ts"],"sourcesContent":["import type { TernSecureRequest } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\n\nimport type { AuthEndpoint, SessionSubEndpoint, 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 idTokenInCookie: string | undefined;\n refreshTokenInCookie: string | undefined;\n csrfTokenInCookie: string | undefined;\n sessionTokenInCookie?: string | undefined;\n customTokenInCookie?: string | undefined;\n\n method: string;\n pathSegments: string[];\n endpoint?: AuthEndpoint;\n subEndpoint?: SessionSubEndpoint;\n\n ternUrl: URL;\n instanceType: string;\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.initUrlValues();\n Object.assign(this, options);\n this.ternUrl = this.ternSecureRequest.ternUrl;\n }\n\n public get request(): TernSecureRequest {\n return this.ternSecureRequest;\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 const isProduction = process.env.NODE_ENV === 'production';\n const defaultPrefix = isProduction ? '__HOST-' : '__dev_';\n this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);\n\n // System-fixed cookies using backend constants\n this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);\n this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);\n this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);\n this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);\n }\n\n private initUrlValues() {\n this.method = this.ternSecureRequest.method;\n this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split('/').filter(Boolean);\n this.endpoint = this.pathSegments[2] as AuthEndpoint;\n this.subEndpoint = this.pathSegments[3] as SessionSubEndpoint;\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 = (\n ternSecureRequest: TernSecureRequest,\n options: TernSecureHandlerOptions,\n): RequestProcessorContext => {\n return new RequestProcessorContext(ternSecureRequest, options);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA0B;
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/c-authenticateRequestProcessor.ts"],"sourcesContent":["import type { TernSecureRequest } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\n\nimport type { AuthEndpoint, SessionSubEndpoint, 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 appCheckToken: string | undefined;\n\n // cookie-based values\n idTokenInCookie: string | undefined;\n refreshTokenInCookie: string | undefined;\n csrfTokenInCookie: string | undefined;\n sessionTokenInCookie?: string | undefined;\n customTokenInCookie?: string | undefined;\n\n method: string;\n pathSegments: string[];\n endpoint?: AuthEndpoint;\n subEndpoint?: SessionSubEndpoint;\n\n ternUrl: URL;\n instanceType: string;\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.initUrlValues();\n Object.assign(this, options);\n this.ternUrl = this.ternSecureRequest.ternUrl;\n }\n\n public get request(): TernSecureRequest {\n return this.ternSecureRequest;\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 this.appCheckToken = this.getHeader(constants.Headers.AppCheckToken);\n }\n\n private initCookieValues() {\n const isProduction = process.env.NODE_ENV === 'production';\n const defaultPrefix = isProduction ? '__HOST-' : '__dev_';\n this.sessionTokenInCookie = this.getCookie(constants.Cookies.Session);\n\n // System-fixed cookies using backend constants\n this.idTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.IdToken}`);\n this.refreshTokenInCookie = this.getCookie(`${defaultPrefix}${constants.Cookies.Refresh}`);\n this.csrfTokenInCookie = this.getCookie(constants.Cookies.CsrfToken);\n this.customTokenInCookie = this.getCookie(constants.Cookies.Custom);\n }\n\n private initUrlValues() {\n this.method = this.ternSecureRequest.method;\n this.pathSegments = this.ternSecureRequest.ternUrl.pathname.split('/').filter(Boolean);\n this.endpoint = this.pathSegments[2] as AuthEndpoint;\n this.subEndpoint = this.pathSegments[3] as SessionSubEndpoint;\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 = (\n ternSecureRequest: TernSecureRequest,\n options: TernSecureHandlerOptions,\n): RequestProcessorContext => {\n return new RequestProcessorContext(ternSecureRequest, options);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA0B;AAuC1B,MAAM,wBAA2D;AAAA,EACxD,YACG,mBACA,SACR;AAFQ;AACA;AAER,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,WAAO,OAAO,MAAM,OAAO;AAC3B,SAAK,UAAU,KAAK,kBAAkB;AAAA,EACxC;AAAA,EAEA,IAAW,UAA6B;AACtC,WAAO,KAAK;AAAA,EACd;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;AACrD,SAAK,gBAAgB,KAAK,UAAU,yBAAU,QAAQ,aAAa;AAAA,EACrE;AAAA,EAEQ,mBAAmB;AACzB,UAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,UAAM,gBAAgB,eAAe,YAAY;AACjD,SAAK,uBAAuB,KAAK,UAAU,yBAAU,QAAQ,OAAO;AAGpE,SAAK,kBAAkB,KAAK,UAAU,GAAG,aAAa,GAAG,yBAAU,QAAQ,OAAO,EAAE;AACpF,SAAK,uBAAuB,KAAK,UAAU,GAAG,aAAa,GAAG,yBAAU,QAAQ,OAAO,EAAE;AACzF,SAAK,oBAAoB,KAAK,UAAU,yBAAU,QAAQ,SAAS;AACnE,SAAK,sBAAsB,KAAK,UAAU,yBAAU,QAAQ,MAAM;AAAA,EACpE;AAAA,EAEQ,gBAAgB;AACtB,SAAK,SAAS,KAAK,kBAAkB;AACrC,SAAK,eAAe,KAAK,kBAAkB,QAAQ,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACrF,SAAK,WAAW,KAAK,aAAa,CAAC;AACnC,SAAK,cAAc,KAAK,aAAa,CAAC;AAAA,EACxC;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,CACpC,mBACA,YAC4B;AAC5B,SAAO,IAAI,wBAAwB,mBAAmB,OAAO;AAC/D;","names":[]}
|
|
@@ -49,11 +49,20 @@ class CookieHandler {
|
|
|
49
49
|
return await (0, import_sessionHandlers.cookieEndpointHandler)(context, config);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
class SignInsHandler {
|
|
53
|
+
canHandle(endpoint) {
|
|
54
|
+
return endpoint === "sign_ins";
|
|
55
|
+
}
|
|
56
|
+
async handle(context, config) {
|
|
57
|
+
return await (0, import_sessionHandlers.signInEndpointHandler)(context, config);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
52
60
|
class EndpointRouter {
|
|
53
61
|
static handlers = [
|
|
54
62
|
new SessionsHandler(),
|
|
55
63
|
new UsersHandler(),
|
|
56
|
-
new CookieHandler()
|
|
64
|
+
new CookieHandler(),
|
|
65
|
+
new SignInsHandler()
|
|
57
66
|
];
|
|
58
67
|
static async route(context, config) {
|
|
59
68
|
const { endpoint } = context;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/endpointRouter.ts"],"sourcesContent":["import type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createApiErrorResponse } from './responses';\nimport { cookieEndpointHandler, sessionEndpointHandler } from './sessionHandlers';\nimport type { AuthEndpoint, TernSecureHandlerOptions } from './types';\n\nexport interface EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean;\n handle(context: RequestProcessorContext, config: TernSecureHandlerOptions): Promise<Response>;\n}\n\nclass SessionsHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'sessions';\n }\n\n async handle(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n return await sessionEndpointHandler(context, config);\n }\n}\n\nclass UsersHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'users';\n }\n\n handle(_context: RequestProcessorContext, _config: TernSecureHandlerOptions): Promise<Response> {\n return Promise.resolve(\n createApiErrorResponse('ENDPOINT_NOT_IMPLEMENTED', 'Users endpoint not implemented', 501),\n );\n }\n}\n\nclass CookieHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'cookies';\n }\n\n async handle(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n return await cookieEndpointHandler(context, config);\n }\n}\n\nexport class EndpointRouter {\n private static readonly handlers: EndpointHandler[] = [\n new SessionsHandler(),\n new UsersHandler(),\n new CookieHandler(),\n ];\n\n static async route(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n const { endpoint } = context;\n\n if (!endpoint) {\n return createApiErrorResponse('ENDPOINT_REQUIRED', 'Endpoint is required', 400);\n }\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(context, 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}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAuC;AACvC,
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/endpointRouter.ts"],"sourcesContent":["import type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createApiErrorResponse } from './responses';\nimport { cookieEndpointHandler, sessionEndpointHandler, signInEndpointHandler } from './sessionHandlers';\nimport type { AuthEndpoint, TernSecureHandlerOptions } from './types';\n\nexport interface EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean;\n handle(context: RequestProcessorContext, config: TernSecureHandlerOptions): Promise<Response>;\n}\n\nclass SessionsHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'sessions';\n }\n\n async handle(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n return await sessionEndpointHandler(context, config);\n }\n}\n\nclass UsersHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'users';\n }\n\n handle(_context: RequestProcessorContext, _config: TernSecureHandlerOptions): Promise<Response> {\n return Promise.resolve(\n createApiErrorResponse('ENDPOINT_NOT_IMPLEMENTED', 'Users endpoint not implemented', 501),\n );\n }\n}\n\nclass CookieHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'cookies';\n }\n\n async handle(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n return await cookieEndpointHandler(context, config);\n }\n}\n\nclass SignInsHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'sign_ins';\n }\n\n async handle(context: RequestProcessorContext, config: TernSecureHandlerOptions): Promise<Response> {\n return await signInEndpointHandler(context, config);\n }\n}\n\nexport class EndpointRouter {\n private static readonly handlers: EndpointHandler[] = [\n new SessionsHandler(),\n new UsersHandler(),\n new CookieHandler(),\n new SignInsHandler(),\n ];\n\n static async route(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n ): Promise<Response> {\n const { endpoint } = context;\n\n if (!endpoint) {\n return createApiErrorResponse('ENDPOINT_REQUIRED', 'Endpoint is required', 400);\n }\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(context, 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}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,uBAAuC;AACvC,6BAAqF;AAQrF,MAAM,gBAA2C;AAAA,EAC/C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OACJ,SACA,QACmB;AACnB,WAAO,UAAM,+CAAuB,SAAS,MAAM;AAAA,EACrD;AACF;AAEA,MAAM,aAAwC;AAAA,EAC5C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,OAAO,UAAmC,SAAsD;AAC9F,WAAO,QAAQ;AAAA,UACb,yCAAuB,4BAA4B,kCAAkC,GAAG;AAAA,IAC1F;AAAA,EACF;AACF;AAEA,MAAM,cAAyC;AAAA,EAC7C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OACJ,SACA,QACmB;AACnB,WAAO,UAAM,8CAAsB,SAAS,MAAM;AAAA,EACpD;AACF;AAEA,MAAM,eAA0C;AAAA,EAC9C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OAAO,SAAkC,QAAqD;AAClG,WAAO,UAAM,8CAAsB,SAAS,MAAM;AAAA,EACpD;AACF;AAEO,MAAM,eAAe;AAAA,EAC1B,OAAwB,WAA8B;AAAA,IACpD,IAAI,gBAAgB;AAAA,IACpB,IAAI,aAAa;AAAA,IACjB,IAAI,cAAc;AAAA,IAClB,IAAI,eAAe;AAAA,EACrB;AAAA,EAEA,aAAa,MACX,SACA,QACmB;AACnB,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,CAAC,UAAU;AACb,iBAAO,yCAAuB,qBAAqB,wBAAwB,GAAG;AAAA,IAChF;AAEA,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,SAAS,MAAM;AAAA,EACvC;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":[]}
|
|
@@ -189,6 +189,13 @@ function createValidators(context) {
|
|
|
189
189
|
400
|
|
190
190
|
);
|
|
191
191
|
}
|
|
192
|
+
if (idToken.split(".").length !== 3) {
|
|
193
|
+
return (0, import_responses.createApiErrorResponse)(
|
|
194
|
+
"INVALID_TOKEN_FORMAT",
|
|
195
|
+
"ID token must be a valid JWT",
|
|
196
|
+
400
|
|
197
|
+
);
|
|
198
|
+
}
|
|
192
199
|
return null;
|
|
193
200
|
}
|
|
194
201
|
async function validateRequest(config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/fnValidators.ts"],"sourcesContent":["import { cookies } from 'next/headers';\n\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createApiErrorResponse } from './responses';\nimport type {\n AuthEndpoint,\n ComprehensiveValidationResult,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionSubEndpoint,\n ValidationConfig,\n} from './types';\n\n/**\n * Main validators factory function\n * Returns an object containing all validator functions and utilities\n */\nexport function createValidators(context: RequestProcessorContext) {\n const { origin, host, referrer, userAgent, method, pathSegments } = context;\n const request = context.request;\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 = context.request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referrer && host && referrer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferrer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referrer?.includes(allowedRef),\n );\n\n if (!isAllowedReferrer) {\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 = context.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 context.request.headers.get('user-agent')?.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 request.headers.get('user-agent')?.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":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/fnValidators.ts"],"sourcesContent":["import { cookies } from 'next/headers';\n\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createApiErrorResponse } from './responses';\nimport type {\n AuthEndpoint,\n ComprehensiveValidationResult,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionSubEndpoint,\n ValidationConfig,\n} from './types';\n\n/**\n * Main validators factory function\n * Returns an object containing all validator functions and utilities\n */\nexport function createValidators(context: RequestProcessorContext) {\n const { origin, host, referrer, userAgent, method, pathSegments } = context;\n const request = context.request;\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 = context.request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referrer && host && referrer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferrer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referrer?.includes(allowedRef),\n );\n\n if (!isAllowedReferrer) {\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 = context.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 context.request.headers.get('user-agent')?.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 request.headers.get('user-agent')?.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 if (idToken.split('.').length !== 3) {\n return createApiErrorResponse(\n 'INVALID_TOKEN_FORMAT',\n 'ID token must be a valid JWT',\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":[]}
|
|
@@ -27,7 +27,7 @@ var import_cookie = require("@tern-secure/shared/cookie");
|
|
|
27
27
|
var import_ternsecureClient = require("../../server/ternsecureClient");
|
|
28
28
|
var import_constants = require("./constants");
|
|
29
29
|
var import_cookieOptionsHelper = require("./cookieOptionsHelper");
|
|
30
|
-
async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer) {
|
|
30
|
+
async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer, appCheckToken) {
|
|
31
31
|
const backendClient = await (0, import_ternsecureClient.ternSecureBackendClient)();
|
|
32
32
|
const authOptions = {
|
|
33
33
|
tenantId: config?.tenantId || void 0,
|
|
@@ -43,7 +43,10 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer)
|
|
|
43
43
|
};
|
|
44
44
|
const COOKIE_OPTIONS = (0, import_cookieOptionsHelper.getIdTokenCookieOptions)();
|
|
45
45
|
const { createCustomIdAndRefreshToken } = (0, import_auth.getAuth)(authOptions);
|
|
46
|
-
const customTokens = await createCustomIdAndRefreshToken(idToken, {
|
|
46
|
+
const customTokens = await createCustomIdAndRefreshToken(idToken, {
|
|
47
|
+
referer: referrer,
|
|
48
|
+
appCheckToken
|
|
49
|
+
});
|
|
47
50
|
const cookiePrefix = (0, import_cookie.getCookiePrefix)();
|
|
48
51
|
const cookiePromises = [
|
|
49
52
|
cookieStore.set(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/request.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\nimport { getAuth } from '@tern-secure/backend/auth';\nimport { getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport type { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET,\n} from './constants';\nimport { getIdTokenCookieOptions } from './cookieOptionsHelper';\nimport type { TernSecureHandlerOptions } from './types';\n\nexport async function refreshCookieWithIdToken(\n idToken: string,\n cookieStore: NextCookieStore,\n config?: TernSecureHandlerOptions,\n referrer?: string,\n): Promise<void> {\n const backendClient = await ternSecureBackendClient();\n\n const authOptions: AuthenticateRequestOptions = {\n tenantId: config?.tenantId || undefined,\n firebaseConfig: {\n apiKey: FIREBASE_API_KEY,\n authDomain: FIREBASE_AUTH_DOMAIN,\n projectId: FIREBASE_PROJECT_ID,\n storageBucket: FIREBASE_STORAGE_BUCKET,\n messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,\n appId: FIREBASE_APP_ID,\n },\n apiClient: backendClient,\n };\n\n const COOKIE_OPTIONS = getIdTokenCookieOptions();\n\n const { createCustomIdAndRefreshToken } = getAuth(authOptions);\n\n const customTokens = await createCustomIdAndRefreshToken(idToken, {
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/request.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\nimport { getAuth } from '@tern-secure/backend/auth';\nimport { getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport type { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET,\n} from './constants';\nimport { getIdTokenCookieOptions } from './cookieOptionsHelper';\nimport type { TernSecureHandlerOptions } from './types';\n\nexport async function refreshCookieWithIdToken(\n idToken: string,\n cookieStore: NextCookieStore,\n config?: TernSecureHandlerOptions,\n referrer?: string,\n appCheckToken?: string,\n): Promise<void> {\n const backendClient = await ternSecureBackendClient();\n\n const authOptions: AuthenticateRequestOptions = {\n tenantId: config?.tenantId || undefined,\n firebaseConfig: {\n apiKey: FIREBASE_API_KEY,\n authDomain: FIREBASE_AUTH_DOMAIN,\n projectId: FIREBASE_PROJECT_ID,\n storageBucket: FIREBASE_STORAGE_BUCKET,\n messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,\n appId: FIREBASE_APP_ID,\n },\n apiClient: backendClient,\n };\n\n const COOKIE_OPTIONS = getIdTokenCookieOptions();\n\n const { createCustomIdAndRefreshToken } = getAuth(authOptions);\n\n\n const customTokens = await createCustomIdAndRefreshToken(idToken, {\n referer: referrer,\n appCheckToken,\n });\n\n\n const cookiePrefix = getCookiePrefix();\n\n const cookiePromises = [\n cookieStore.set(\n getCookieName(constants.Cookies.IdToken, cookiePrefix),\n customTokens.idToken,\n COOKIE_OPTIONS,\n ),\n cookieStore.set(\n getCookieName(constants.Cookies.Refresh, cookiePrefix),\n customTokens.refreshToken,\n COOKIE_OPTIONS,\n ),\n\n cookieStore.set(\n constants.Cookies.TernAut,\n customTokens.auth_time.toString(),\n { secure: true, maxAge: 365 * 24 * 60 * 60 }\n ),\n ];\n\n if (config?.enableCustomToken) {\n cookiePromises.push(\n cookieStore.set(constants.Cookies.Custom, customTokens.customToken, COOKIE_OPTIONS),\n );\n }\n\n await Promise.all(cookiePromises);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA0B;AAC1B,kBAAwB;AACxB,oBAA+C;AAE/C,8BAAwC;AAExC,uBAOO;AACP,iCAAwC;AAGxC,eAAsB,yBACpB,SACA,aACA,QACA,UACA,eACe;AACf,QAAM,gBAAgB,UAAM,iDAAwB;AAEpD,QAAM,cAA0C;AAAA,IAC9C,UAAU,QAAQ,YAAY;AAAA,IAC9B,gBAAgB;AAAA,MACd,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,OAAO;AAAA,IACT;AAAA,IACA,WAAW;AAAA,EACb;AAEA,QAAM,qBAAiB,oDAAwB;AAE/C,QAAM,EAAE,8BAA8B,QAAI,qBAAQ,WAAW;AAG7D,QAAM,eAAe,MAAM,8BAA8B,SAAS;AAAA,IAChE,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAGD,QAAM,mBAAe,+BAAgB;AAErC,QAAM,iBAAiB;AAAA,IACrB,YAAY;AAAA,UACV,6BAAc,yBAAU,QAAQ,SAAS,YAAY;AAAA,MACrD,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,YAAY;AAAA,UACV,6BAAc,yBAAU,QAAQ,SAAS,YAAY;AAAA,MACrD,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IAEA,YAAY;AAAA,MACV,yBAAU,QAAQ;AAAA,MAClB,aAAa,UAAU,SAAS;AAAA,MAChC,EAAE,QAAQ,MAAM,QAAQ,MAAM,KAAK,KAAK,GAAG;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,mBAAe;AAAA,MACb,YAAY,IAAI,yBAAU,QAAQ,QAAQ,aAAa,aAAa,cAAc;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,cAAc;AAClC;","names":[]}
|
|
@@ -19,17 +19,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var sessionHandlers_exports = {};
|
|
20
20
|
__export(sessionHandlers_exports, {
|
|
21
21
|
cookieEndpointHandler: () => cookieEndpointHandler,
|
|
22
|
-
sessionEndpointHandler: () => sessionEndpointHandler
|
|
22
|
+
sessionEndpointHandler: () => sessionEndpointHandler,
|
|
23
|
+
signInEndpointHandler: () => signInEndpointHandler
|
|
23
24
|
});
|
|
24
25
|
module.exports = __toCommonJS(sessionHandlers_exports);
|
|
25
26
|
var import_backend = require("@tern-secure/backend");
|
|
26
27
|
var import_admin = require("@tern-secure/backend/admin");
|
|
27
28
|
var import_jwt = require("@tern-secure/backend/jwt");
|
|
29
|
+
var import_ternsecureClient = require("../../server/ternsecureClient");
|
|
28
30
|
var import_NextCookieAdapter = require("../../utils/NextCookieAdapter");
|
|
31
|
+
var import_constants = require("./constants");
|
|
29
32
|
var import_fnValidators = require("./fnValidators");
|
|
30
33
|
var import_request = require("./request");
|
|
31
34
|
var import_responses = require("./responses");
|
|
32
|
-
|
|
35
|
+
var import_signInCreateHandler = require("./signInCreateHandler");
|
|
36
|
+
const sessionEndpointHandler = async (context, config) => {
|
|
33
37
|
const { subEndpoint, method, referrer } = context;
|
|
34
38
|
const validators = (0, import_fnValidators.createValidators)(context);
|
|
35
39
|
const {
|
|
@@ -79,13 +83,15 @@ async function sessionEndpointHandler(context, config) {
|
|
|
79
83
|
validateCsrfToken(csrfToken || "", csrfCookieValue.value);
|
|
80
84
|
const handleCreateSession = async (cookieStore2, idToken2) => {
|
|
81
85
|
try {
|
|
82
|
-
await (0, import_request.refreshCookieWithIdToken)(idToken2, cookieStore2, config, referrer);
|
|
86
|
+
await (0, import_request.refreshCookieWithIdToken)(idToken2, cookieStore2, config, referrer, context.appCheckToken);
|
|
83
87
|
return import_responses.SessionResponseHelper.createSessionCreationResponse({
|
|
84
88
|
success: true,
|
|
85
89
|
message: "Session created successfully"
|
|
86
90
|
});
|
|
87
91
|
} catch (error2) {
|
|
88
|
-
|
|
92
|
+
console.error("[SessionHandler - createsession] Error:", error2);
|
|
93
|
+
const errorMessage = error2 instanceof Error ? error2.message : "Session creation failed";
|
|
94
|
+
return (0, import_responses.createApiErrorResponse)("SESSION_CREATION_FAILED", errorMessage, 500);
|
|
89
95
|
}
|
|
90
96
|
};
|
|
91
97
|
const handleRefreshSession = async (cookieStore2, idToken2) => {
|
|
@@ -94,10 +100,17 @@ async function sessionEndpointHandler(context, config) {
|
|
|
94
100
|
if (decodedSession.errors) {
|
|
95
101
|
return (0, import_responses.createApiErrorResponse)("INVALID_SESSION", "Invalid session for refresh", 401);
|
|
96
102
|
}
|
|
97
|
-
const refreshRes = await (0, import_request.refreshCookieWithIdToken)(
|
|
103
|
+
const refreshRes = await (0, import_request.refreshCookieWithIdToken)(
|
|
104
|
+
idToken2,
|
|
105
|
+
cookieStore2,
|
|
106
|
+
config,
|
|
107
|
+
void 0,
|
|
108
|
+
context.appCheckToken
|
|
109
|
+
);
|
|
98
110
|
return import_responses.SessionResponseHelper.createRefreshResponse(refreshRes);
|
|
99
111
|
} catch (error2) {
|
|
100
|
-
|
|
112
|
+
const errorMessage = error2 instanceof Error ? error2.message : "Session refresh failed";
|
|
113
|
+
return (0, import_responses.createApiErrorResponse)("REFRESH_FAILED", errorMessage, 500);
|
|
101
114
|
}
|
|
102
115
|
};
|
|
103
116
|
const handleRevokeSession = async (cookieStore2) => {
|
|
@@ -106,7 +119,8 @@ async function sessionEndpointHandler(context, config) {
|
|
|
106
119
|
};
|
|
107
120
|
switch (subEndpoint2) {
|
|
108
121
|
case "createsession": {
|
|
109
|
-
validateIdToken(idToken);
|
|
122
|
+
const idTokenError = validateIdToken(idToken);
|
|
123
|
+
if (idTokenError) return idTokenError;
|
|
110
124
|
return handleCreateSession(cookieStore, idToken);
|
|
111
125
|
}
|
|
112
126
|
case "refresh":
|
|
@@ -125,8 +139,8 @@ async function sessionEndpointHandler(context, config) {
|
|
|
125
139
|
default:
|
|
126
140
|
return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
|
|
127
141
|
}
|
|
128
|
-
}
|
|
129
|
-
async
|
|
142
|
+
};
|
|
143
|
+
const cookieEndpointHandler = async (context, config) => {
|
|
130
144
|
const { subEndpoint, method } = context;
|
|
131
145
|
const validators = (0, import_fnValidators.createValidators)(context);
|
|
132
146
|
const { validateSecurity } = validators;
|
|
@@ -193,10 +207,77 @@ async function cookieEndpointHandler(context, config) {
|
|
|
193
207
|
default:
|
|
194
208
|
return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
|
|
195
209
|
}
|
|
196
|
-
}
|
|
210
|
+
};
|
|
211
|
+
const signInEndpointHandler = async (context, config) => {
|
|
212
|
+
const { subEndpoint, method } = context;
|
|
213
|
+
const validators = (0, import_fnValidators.createValidators)(context);
|
|
214
|
+
const {
|
|
215
|
+
validateSubEndpoint,
|
|
216
|
+
validateSecurity
|
|
217
|
+
} = validators;
|
|
218
|
+
if (!subEndpoint) {
|
|
219
|
+
return (0, import_responses.createApiErrorResponse)("SUB_ENDPOINT_REQUIRED", "Sign_ins sub-endpoint required", 400);
|
|
220
|
+
}
|
|
221
|
+
const signInsConfig = config.endpoints?.signIns;
|
|
222
|
+
const subEndpointConfig = signInsConfig?.subEndpoints?.[subEndpoint];
|
|
223
|
+
validateSubEndpoint(subEndpoint, subEndpointConfig);
|
|
224
|
+
if (subEndpointConfig?.security) {
|
|
225
|
+
await validateSecurity(subEndpointConfig.security);
|
|
226
|
+
}
|
|
227
|
+
const PostHandler = async (subEndpoint2) => {
|
|
228
|
+
const create = async () => {
|
|
229
|
+
return await (0, import_signInCreateHandler.processSignInCreate)(context);
|
|
230
|
+
};
|
|
231
|
+
const passwordResetEmail = async () => {
|
|
232
|
+
try {
|
|
233
|
+
const body = await context.request.json();
|
|
234
|
+
const { email } = body;
|
|
235
|
+
if (!email || typeof email !== "string") {
|
|
236
|
+
return (0, import_responses.createApiErrorResponse)("EMAIL_REQUIRED", "Email is required", 400);
|
|
237
|
+
}
|
|
238
|
+
const backendClient = await (0, import_ternsecureClient.ternSecureBackendClient)();
|
|
239
|
+
const response = await backendClient.signIn.resetPasswordEmail(import_constants.FIREBASE_API_KEY, {
|
|
240
|
+
email,
|
|
241
|
+
requestType: "PASSWORD_RESET"
|
|
242
|
+
});
|
|
243
|
+
if (!response) {
|
|
244
|
+
return (0, import_responses.createApiErrorResponse)(
|
|
245
|
+
"PASSWORD_RESET_FAILED",
|
|
246
|
+
"Failed to send password reset email",
|
|
247
|
+
500
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
return (0, import_responses.createApiSuccessResponse)({
|
|
251
|
+
email
|
|
252
|
+
});
|
|
253
|
+
} catch (error) {
|
|
254
|
+
return (0, import_responses.createApiErrorResponse)(
|
|
255
|
+
"PASSWORD_RESET_ERROR",
|
|
256
|
+
error instanceof Error ? error.message : "An error occurred while sending password reset email",
|
|
257
|
+
500
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
switch (subEndpoint2) {
|
|
262
|
+
case "create":
|
|
263
|
+
return create();
|
|
264
|
+
case "resetPasswordEmail":
|
|
265
|
+
return passwordResetEmail();
|
|
266
|
+
default:
|
|
267
|
+
return import_responses.HttpResponseHelper.createSubEndpointNotSupportedResponse();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
switch (method) {
|
|
271
|
+
case "POST":
|
|
272
|
+
return PostHandler(subEndpoint);
|
|
273
|
+
default:
|
|
274
|
+
return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
|
|
275
|
+
}
|
|
276
|
+
};
|
|
197
277
|
// Annotate the CommonJS export names for ESM import in node:
|
|
198
278
|
0 && (module.exports = {
|
|
199
279
|
cookieEndpointHandler,
|
|
200
|
-
sessionEndpointHandler
|
|
280
|
+
sessionEndpointHandler,
|
|
281
|
+
signInEndpointHandler
|
|
201
282
|
});
|
|
202
283
|
//# sourceMappingURL=sessionHandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import { constants } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\nimport type { CookieSubEndpoint } from '@tern-secure/types';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { type RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createValidators } from './fnValidators';\nimport { refreshCookieWithIdToken } from './request';\nimport { createApiErrorResponse, createApiSuccessResponse, HttpResponseHelper, SessionResponseHelper } from './responses';\nimport type { SessionSubEndpoint, TernSecureHandlerOptions } from './types';\n\nasync function sessionEndpointHandler(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> {\n const { subEndpoint, method, referrer } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n validateSessionRequest,\n validateCsrfToken,\n validateIdToken,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const sessionsConfig = config.endpoints?.sessions;\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\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 switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await validateSessionRequest();\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get(constants.Cookies.CsrfToken);\n validateCsrfToken(csrfToken || '', csrfCookieValue.value);\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(idToken, cookieStore, config);\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n validateIdToken(idToken);\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nasync function cookieEndpointHandler(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n const { validateSecurity } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Cookie sub-endpoint required', 400);\n }\n\n const cookiesConfig = config.endpoints?.cookies;\n const subEndpointConfig = cookiesConfig?.subEndpoints?.[subEndpoint as CookieSubEndpoint];\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Cookie endpoint not found or disabled', 404);\n }\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const CookieGetHandler = async (subEndpoint: CookieSubEndpoint): Promise<Response> => {\n const handleGetCookie = async (): Promise<Response> => {\n try {\n const url = new URL(context.ternUrl);\n const tokenName = url.searchParams.get('tokenName');\n\n if (!tokenName) {\n return createApiErrorResponse('TOKEN_NAME_REQUIRED', 'tokenName query parameter is required', 400);\n }\n\n let cookieValue: string | undefined;\n\n switch (tokenName) {\n case 'idToken':\n cookieValue = context.idTokenInCookie;\n break;\n case 'sessionToken':\n cookieValue = context.sessionTokenInCookie;\n break;\n case 'refreshToken':\n cookieValue = context.refreshTokenInCookie;\n break;\n case 'customToken':\n cookieValue = context.customTokenInCookie;\n break;\n default:\n return createApiErrorResponse('INVALID_TOKEN_NAME', 'Invalid token name. Must be one of: idToken, sessionToken, refreshToken, customToken', 400);\n }\n\n if (!cookieValue) {\n return createApiErrorResponse(\n 'TOKEN_NOT_FOUND',\n `${tokenName} not found in httpOnly cookies`,\n 404\n );\n }\n\n return createApiSuccessResponse({\n token: cookieValue,\n });\n } catch (error) {\n return createApiErrorResponse('COOKIE_RETRIEVAL_FAILED', 'Failed to retrieve cookie', 500);\n }\n };\n\n switch (subEndpoint) {\n case 'get':\n return handleGetCookie();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return CookieGetHandler(subEndpoint as CookieSubEndpoint);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nexport { sessionEndpointHandler, cookieEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import { constants } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\nimport type { CookieSubEndpoint } from '@tern-secure/types';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { type RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { FIREBASE_API_KEY } from './constants';\nimport { createValidators } from './fnValidators';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, TernSecureHandlerOptions } from './types';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n validateSessionRequest,\n validateCsrfToken,\n validateIdToken,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const sessionsConfig = config.endpoints?.sessions;\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\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 switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await validateSessionRequest();\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get(constants.Cookies.CsrfToken);\n validateCsrfToken(csrfToken || '', csrfCookieValue.value);\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer, context.appCheckToken);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n console.error('[SessionHandler - createsession] Error:', error);\n const errorMessage = error instanceof Error ? error.message : 'Session creation failed';\n return createApiErrorResponse('SESSION_CREATION_FAILED', errorMessage, 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(\n idToken,\n cookieStore,\n config,\n undefined,\n context.appCheckToken,\n );\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Session refresh failed';\n return createApiErrorResponse('REFRESH_FAILED', errorMessage, 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n const idTokenError = validateIdToken(idToken);\n if (idTokenError) return idTokenError;\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nconst cookieEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n const { validateSecurity } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Cookie sub-endpoint required', 400);\n }\n\n const cookiesConfig = config.endpoints?.cookies;\n const subEndpointConfig = cookiesConfig?.subEndpoints?.[subEndpoint as CookieSubEndpoint];\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Cookie endpoint not found or disabled', 404);\n }\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const CookieGetHandler = async (subEndpoint: CookieSubEndpoint): Promise<Response> => {\n const handleGetCookie = async (): Promise<Response> => {\n try {\n const url = new URL(context.ternUrl);\n const tokenName = url.searchParams.get('tokenName');\n\n if (!tokenName) {\n return createApiErrorResponse('TOKEN_NAME_REQUIRED', 'tokenName query parameter is required', 400);\n }\n\n let cookieValue: string | undefined;\n\n switch (tokenName) {\n case 'idToken':\n cookieValue = context.idTokenInCookie;\n break;\n case 'sessionToken':\n cookieValue = context.sessionTokenInCookie;\n break;\n case 'refreshToken':\n cookieValue = context.refreshTokenInCookie;\n break;\n case 'customToken':\n cookieValue = context.customTokenInCookie;\n break;\n default:\n return createApiErrorResponse('INVALID_TOKEN_NAME', 'Invalid token name. Must be one of: idToken, sessionToken, refreshToken, customToken', 400);\n }\n\n if (!cookieValue) {\n return createApiErrorResponse(\n 'TOKEN_NOT_FOUND',\n `${tokenName} not found in httpOnly cookies`,\n 404\n );\n }\n\n return createApiSuccessResponse({\n token: cookieValue,\n });\n } catch (error) {\n return createApiErrorResponse('COOKIE_RETRIEVAL_FAILED', 'Failed to retrieve cookie', 500);\n }\n };\n\n switch (subEndpoint) {\n case 'get':\n return handleGetCookie();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return CookieGetHandler(subEndpoint as CookieSubEndpoint);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Sign_ins sub-endpoint required', 400);\n }\n\n const signInsConfig = config.endpoints?.signIns;\n const subEndpointConfig = signInsConfig?.subEndpoints?.[subEndpoint as SignInSubEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const PostHandler = async (subEndpoint: SignInSubEndpoint): Promise<Response> => {\n const create = async (): Promise<Response> => {\n return await processSignInCreate(context);\n };\n\n const passwordResetEmail = async (): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { email } = body;\n\n if (!email || typeof email !== 'string') {\n return createApiErrorResponse('EMAIL_REQUIRED', 'Email is required', 400);\n }\n\n const backendClient = await ternSecureBackendClient();\n\n const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {\n email,\n requestType: 'PASSWORD_RESET',\n });\n\n if (!response) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_FAILED',\n 'Failed to send password reset email',\n 500,\n );\n }\n\n return createApiSuccessResponse({\n email,\n });\n } catch (error) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while sending password reset email',\n 500,\n );\n }\n };\n\n switch (subEndpoint) {\n case 'create':\n return create();\n case 'resetPasswordEmail':\n return passwordResetEmail();\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'POST':\n return PostHandler(subEndpoint as SignInSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n\n}\n\nexport { cookieEndpointHandler, sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
|