@tern-secure/nextjs 5.2.0-canary.v20251127235234 → 5.2.0-canary.v20251202164451

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.
Files changed (97) hide show
  1. package/dist/cjs/__tests__/gemini_fnTernSecureNextHandler.bench.js +2 -2
  2. package/dist/cjs/__tests__/gemini_fnTernSecureNextHandler.bench.js.map +1 -1
  3. package/dist/cjs/app-router/admin/actions.js.map +1 -1
  4. package/dist/cjs/app-router/admin/endpointRouter.js +4 -13
  5. package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -1
  6. package/dist/cjs/app-router/admin/{sessionHandlers.js → handlers.js} +16 -115
  7. package/dist/cjs/app-router/admin/handlers.js.map +1 -0
  8. package/dist/cjs/app-router/admin/index.js.map +1 -1
  9. package/dist/cjs/app-router/admin/request.js +1 -8
  10. package/dist/cjs/app-router/admin/request.js.map +1 -1
  11. package/dist/cjs/app-router/admin/signInCreateHandler.js.map +1 -1
  12. package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js +7 -17
  13. package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
  14. package/dist/cjs/app-router/admin/types.js +9 -0
  15. package/dist/cjs/app-router/admin/types.js.map +1 -1
  16. package/dist/cjs/app-router/admin/validators.js +96 -171
  17. package/dist/cjs/app-router/admin/validators.js.map +1 -1
  18. package/dist/cjs/app-router/server/TernSecureProvider.js +18 -0
  19. package/dist/cjs/app-router/server/TernSecureProvider.js.map +1 -1
  20. package/dist/cjs/server/constant.js +6 -0
  21. package/dist/cjs/server/constant.js.map +1 -1
  22. package/dist/cjs/server/data/getAuthDataFromRequest.js +16 -9
  23. package/dist/cjs/server/data/getAuthDataFromRequest.js.map +1 -1
  24. package/dist/cjs/server/headers-utils.js +3 -3
  25. package/dist/cjs/server/headers-utils.js.map +1 -1
  26. package/dist/cjs/server/proxy-storage.js +33 -0
  27. package/dist/cjs/server/proxy-storage.js.map +1 -0
  28. package/dist/cjs/server/ternSecureProxy.js +2 -13
  29. package/dist/cjs/server/ternSecureProxy.js.map +1 -1
  30. package/dist/cjs/server/utils.js +16 -4
  31. package/dist/cjs/server/utils.js.map +1 -1
  32. package/dist/esm/__tests__/gemini_fnTernSecureNextHandler.bench.js +1 -1
  33. package/dist/esm/__tests__/gemini_fnTernSecureNextHandler.bench.js.map +1 -1
  34. package/dist/esm/app-router/admin/actions.js.map +1 -1
  35. package/dist/esm/app-router/admin/endpointRouter.js +3 -12
  36. package/dist/esm/app-router/admin/endpointRouter.js.map +1 -1
  37. package/dist/esm/app-router/admin/{sessionHandlers.js → handlers.js} +18 -110
  38. package/dist/esm/app-router/admin/handlers.js.map +1 -0
  39. package/dist/esm/app-router/admin/index.js.map +1 -1
  40. package/dist/esm/app-router/admin/request.js +2 -14
  41. package/dist/esm/app-router/admin/request.js.map +1 -1
  42. package/dist/esm/app-router/admin/signInCreateHandler.js.map +1 -1
  43. package/dist/esm/app-router/admin/ternsecureNextjsHandler.js +9 -19
  44. package/dist/esm/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
  45. package/dist/esm/app-router/admin/types.js +8 -0
  46. package/dist/esm/app-router/admin/types.js.map +1 -1
  47. package/dist/esm/app-router/admin/validators.js +88 -166
  48. package/dist/esm/app-router/admin/validators.js.map +1 -1
  49. package/dist/esm/app-router/server/TernSecureProvider.js +19 -1
  50. package/dist/esm/app-router/server/TernSecureProvider.js.map +1 -1
  51. package/dist/esm/server/constant.js +4 -0
  52. package/dist/esm/server/constant.js.map +1 -1
  53. package/dist/esm/server/data/getAuthDataFromRequest.js +18 -11
  54. package/dist/esm/server/data/getAuthDataFromRequest.js.map +1 -1
  55. package/dist/esm/server/headers-utils.js +2 -2
  56. package/dist/esm/server/headers-utils.js.map +1 -1
  57. package/dist/esm/server/proxy-storage.js +8 -0
  58. package/dist/esm/server/proxy-storage.js.map +1 -0
  59. package/dist/esm/server/ternSecureProxy.js +7 -14
  60. package/dist/esm/server/ternSecureProxy.js.map +1 -1
  61. package/dist/esm/server/utils.js +16 -4
  62. package/dist/esm/server/utils.js.map +1 -1
  63. package/dist/types/app-router/admin/actions.d.ts +2 -2
  64. package/dist/types/app-router/admin/actions.d.ts.map +1 -1
  65. package/dist/types/app-router/admin/endpointRouter.d.ts +4 -4
  66. package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -1
  67. package/dist/types/app-router/admin/handlers.d.ts +5 -0
  68. package/dist/types/app-router/admin/handlers.d.ts.map +1 -0
  69. package/dist/types/app-router/admin/index.d.ts +1 -1
  70. package/dist/types/app-router/admin/index.d.ts.map +1 -1
  71. package/dist/types/app-router/admin/request.d.ts +2 -2
  72. package/dist/types/app-router/admin/request.d.ts.map +1 -1
  73. package/dist/types/app-router/admin/signInCreateHandler.d.ts +1 -1
  74. package/dist/types/app-router/admin/signInCreateHandler.d.ts.map +1 -1
  75. package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts +6 -2
  76. package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts.map +1 -1
  77. package/dist/types/app-router/admin/types.d.ts +24 -2
  78. package/dist/types/app-router/admin/types.d.ts.map +1 -1
  79. package/dist/types/app-router/admin/validators.d.ts +36 -33
  80. package/dist/types/app-router/admin/validators.d.ts.map +1 -1
  81. package/dist/types/app-router/server/TernSecureProvider.d.ts.map +1 -1
  82. package/dist/types/server/constant.d.ts +2 -0
  83. package/dist/types/server/constant.d.ts.map +1 -1
  84. package/dist/types/server/data/getAuthDataFromRequest.d.ts.map +1 -1
  85. package/dist/types/server/headers-utils.d.ts +1 -1
  86. package/dist/types/server/headers-utils.d.ts.map +1 -1
  87. package/dist/types/server/proxy-storage.d.ts +5 -0
  88. package/dist/types/server/proxy-storage.d.ts.map +1 -0
  89. package/dist/types/server/ternSecureProxy.d.ts +1 -3
  90. package/dist/types/server/ternSecureProxy.d.ts.map +1 -1
  91. package/dist/types/server/utils.d.ts +2 -2
  92. package/dist/types/server/utils.d.ts.map +1 -1
  93. package/package.json +5 -5
  94. package/dist/cjs/app-router/admin/sessionHandlers.js.map +0 -1
  95. package/dist/esm/app-router/admin/sessionHandlers.js.map +0 -1
  96. package/dist/types/app-router/admin/sessionHandlers.d.ts +0 -7
  97. package/dist/types/app-router/admin/sessionHandlers.d.ts.map +0 -1
@@ -2,7 +2,7 @@
2
2
  var import_vitest = require("vitest");
3
3
  var import_server = require("next/server");
4
4
  var import_gemini_fnTernSecureNextHandler = require("../../examples/gemini_fnTernSecureNextHandler");
5
- var import_sessionHandlers = require("../app-router/admin/sessionHandlers");
5
+ var import_handlers = require("../app-router/admin/handlers");
6
6
  import_vitest.vi.mock("../sessionHandlers", () => ({
7
7
  SessionEndpointHandler: {
8
8
  handle: import_vitest.vi.fn()
@@ -25,7 +25,7 @@ const authHandlerOptions = {
25
25
  method: "GET",
26
26
  headers: { origin: "http://localhost:3000" }
27
27
  });
28
- import_sessionHandlers.SessionEndpointHandler.handle.mockResolvedValue(new import_server.NextResponse(null, { status: 200 }));
28
+ import_handlers.SessionEndpointHandler.handle.mockResolvedValue(new import_server.NextResponse(null, { status: 200 }));
29
29
  await handler.GET(request);
30
30
  });
31
31
  //# sourceMappingURL=gemini_fnTernSecureNextHandler.bench.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/__tests__/gemini_fnTernSecureNextHandler.bench.ts"],"sourcesContent":["import { bench, vi } from 'vitest';\nimport { NextRequest, NextResponse } from 'next/server';\nimport { geminiCreateTernSecureNextJsHandlerFn } from '../../examples/gemini_fnTernSecureNextHandler';\nimport { SessionEndpointHandler } from '../app-router/admin/sessionHandlers';\n\nvi.mock('../sessionHandlers', () => ({\n SessionEndpointHandler: {\n handle: vi.fn(),\n },\n}));\n\nconst authHandlerOptions = {\n cors: {\n allowedOrigins: ['http://localhost:3000', 'https://ternsecure.com'],\n allowedMethods: ['GET', 'POST'],\n },\n security: {\n requireCSRF: true,\n allowedReferers: ['http://localhost:3000', 'https://ternsecure.com'],\n },\n debug: false,\n};\n\nbench('handler performance for a valid request', async () => {\n const handler = geminiCreateTernSecureNextJsHandlerFn(authHandlerOptions);\n const request = new NextRequest('http://localhost/api/auth/sessions/verify', {\n method: 'GET',\n headers: { origin: 'http://localhost:3000' },\n });\n (SessionEndpointHandler.handle as any).mockResolvedValue(new NextResponse(null, { status: 200 }));\n\n await handler.GET(request);\n});\n"],"mappings":";AAAA,oBAA0B;AAC1B,oBAA0C;AAC1C,4CAAsD;AACtD,6BAAuC;AAEvC,iBAAG,KAAK,sBAAsB,OAAO;AAAA,EACnC,wBAAwB;AAAA,IACtB,QAAQ,iBAAG,GAAG;AAAA,EAChB;AACF,EAAE;AAEF,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAAA,IACJ,gBAAgB,CAAC,yBAAyB,wBAAwB;AAAA,IAClE,gBAAgB,CAAC,OAAO,MAAM;AAAA,EAChC;AAAA,EACA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,iBAAiB,CAAC,yBAAyB,wBAAwB;AAAA,EACrE;AAAA,EACA,OAAO;AACT;AAAA,IAEA,qBAAM,2CAA2C,YAAY;AAC3D,QAAM,cAAU,6EAAsC,kBAAkB;AACxE,QAAM,UAAU,IAAI,0BAAY,6CAA6C;AAAA,IAC3E,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,wBAAwB;AAAA,EAC7C,CAAC;AACD,EAAC,8CAAuB,OAAe,kBAAkB,IAAI,2BAAa,MAAM,EAAE,QAAQ,IAAI,CAAC,CAAC;AAEhG,QAAM,QAAQ,IAAI,OAAO;AAC3B,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/__tests__/gemini_fnTernSecureNextHandler.bench.ts"],"sourcesContent":["import { bench, vi } from 'vitest';\nimport { NextRequest, NextResponse } from 'next/server';\nimport { geminiCreateTernSecureNextJsHandlerFn } from '../../examples/gemini_fnTernSecureNextHandler';\nimport { SessionEndpointHandler } from '../app-router/admin/handlers';\n\nvi.mock('../sessionHandlers', () => ({\n SessionEndpointHandler: {\n handle: vi.fn(),\n },\n}));\n\nconst authHandlerOptions = {\n cors: {\n allowedOrigins: ['http://localhost:3000', 'https://ternsecure.com'],\n allowedMethods: ['GET', 'POST'],\n },\n security: {\n requireCSRF: true,\n allowedReferers: ['http://localhost:3000', 'https://ternsecure.com'],\n },\n debug: false,\n};\n\nbench('handler performance for a valid request', async () => {\n const handler = geminiCreateTernSecureNextJsHandlerFn(authHandlerOptions);\n const request = new NextRequest('http://localhost/api/auth/sessions/verify', {\n method: 'GET',\n headers: { origin: 'http://localhost:3000' },\n });\n (SessionEndpointHandler.handle as any).mockResolvedValue(new NextResponse(null, { status: 200 }));\n\n await handler.GET(request);\n});\n"],"mappings":";AAAA,oBAA0B;AAC1B,oBAA0C;AAC1C,4CAAsD;AACtD,sBAAuC;AAEvC,iBAAG,KAAK,sBAAsB,OAAO;AAAA,EACnC,wBAAwB;AAAA,IACtB,QAAQ,iBAAG,GAAG;AAAA,EAChB;AACF,EAAE;AAEF,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAAA,IACJ,gBAAgB,CAAC,yBAAyB,wBAAwB;AAAA,IAClE,gBAAgB,CAAC,OAAO,MAAM;AAAA,EAChC;AAAA,EACA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,iBAAiB,CAAC,yBAAyB,wBAAwB;AAAA,EACrE;AAAA,EACA,OAAO;AACT;AAAA,IAEA,qBAAM,2CAA2C,YAAY;AAC3D,QAAM,cAAU,6EAAsC,kBAAkB;AACxE,QAAM,UAAU,IAAI,0BAAY,6CAA6C;AAAA,IAC3E,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,wBAAwB;AAAA,EAC7C,CAAC;AACD,EAAC,uCAAuB,OAAe,kBAAkB,IAAI,2BAAa,MAAM,EAAE,QAAQ,IAAI,CAAC,CAAC;AAEhG,QAAM,QAAQ,IAAI,OAAO;AAC3B,CAAC;","names":[]}
@@ -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 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"]}
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 { ApiHandlerOptions } 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?: ApiHandlerOptions['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"]}
@@ -21,14 +21,14 @@ __export(endpointRouter_exports, {
21
21
  EndpointRouter: () => EndpointRouter
22
22
  });
23
23
  module.exports = __toCommonJS(endpointRouter_exports);
24
+ var import_handlers = require("./handlers");
24
25
  var import_responses = require("./responses");
25
- var import_sessionHandlers = require("./sessionHandlers");
26
26
  class SessionsHandler {
27
27
  canHandle(endpoint) {
28
28
  return endpoint === "sessions";
29
29
  }
30
30
  async handle(context, config) {
31
- return await (0, import_sessionHandlers.sessionEndpointHandler)(context, config);
31
+ return await (0, import_handlers.sessionEndpointHandler)(context, config);
32
32
  }
33
33
  }
34
34
  class UsersHandler {
@@ -41,27 +41,18 @@ class UsersHandler {
41
41
  );
42
42
  }
43
43
  }
44
- class CookieHandler {
45
- canHandle(endpoint) {
46
- return endpoint === "cookies";
47
- }
48
- async handle(context, config) {
49
- return await (0, import_sessionHandlers.cookieEndpointHandler)(context, config);
50
- }
51
- }
52
44
  class SignInsHandler {
53
45
  canHandle(endpoint) {
54
46
  return endpoint === "sign_ins";
55
47
  }
56
- async handle(context, config) {
57
- return await (0, import_sessionHandlers.signInEndpointHandler)(context, config);
48
+ async handle(context) {
49
+ return await (0, import_handlers.signInEndpointHandler)(context);
58
50
  }
59
51
  }
60
52
  class EndpointRouter {
61
53
  static handlers = [
62
54
  new SessionsHandler(),
63
55
  new UsersHandler(),
64
- new CookieHandler(),
65
56
  new SignInsHandler()
66
57
  ];
67
58
  static async route(context, config) {
@@ -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, 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":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/endpointRouter.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport type { AuthEndpoint } from '@tern-secure/types';\n\nimport { sessionEndpointHandler, signInEndpointHandler } from './handlers';\nimport { createApiErrorResponse } from './responses';\n\nexport interface EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean;\n handle(context: RequestProcessorContext, config: AuthenticateRequestOptions): 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: AuthenticateRequestOptions,\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: AuthenticateRequestOptions): Promise<Response> {\n return Promise.resolve(\n createApiErrorResponse('ENDPOINT_NOT_IMPLEMENTED', 'Users endpoint not implemented', 501),\n );\n }\n}\n\n\nclass SignInsHandler implements EndpointHandler {\n canHandle(endpoint: AuthEndpoint): boolean {\n return endpoint === 'sign_ins';\n }\n\n async handle(context: RequestProcessorContext): Promise<Response> {\n return await signInEndpointHandler(context);\n }\n}\n\nexport class EndpointRouter {\n private static readonly handlers: EndpointHandler[] = [\n new SessionsHandler(),\n new UsersHandler(),\n new SignInsHandler(),\n ];\n\n static async route(\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\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;AAGA,sBAA8D;AAC9D,uBAAuC;AAOvC,MAAM,gBAA2C;AAAA,EAC/C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OACJ,SACA,QACmB;AACnB,WAAO,UAAM,wCAAuB,SAAS,MAAM;AAAA,EACrD;AACF;AAEA,MAAM,aAAwC;AAAA,EAC5C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,OAAO,UAAmC,SAAwD;AAChG,WAAO,QAAQ;AAAA,UACb,yCAAuB,4BAA4B,kCAAkC,GAAG;AAAA,IAC1F;AAAA,EACF;AACF;AAGA,MAAM,eAA0C;AAAA,EAC9C,UAAU,UAAiC;AACzC,WAAO,aAAa;AAAA,EACtB;AAAA,EAEA,MAAM,OAAO,SAAqD;AAChE,WAAO,UAAM,uCAAsB,OAAO;AAAA,EAC5C;AACF;AAEO,MAAM,eAAe;AAAA,EAC1B,OAAwB,WAA8B;AAAA,IACpD,IAAI,gBAAgB;AAAA,IACpB,IAAI,aAAa;AAAA,IACjB,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":[]}
@@ -16,42 +16,25 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var sessionHandlers_exports = {};
20
- __export(sessionHandlers_exports, {
21
- cookieEndpointHandler: () => cookieEndpointHandler,
19
+ var handlers_exports = {};
20
+ __export(handlers_exports, {
22
21
  sessionEndpointHandler: () => sessionEndpointHandler,
23
22
  signInEndpointHandler: () => signInEndpointHandler
24
23
  });
25
- module.exports = __toCommonJS(sessionHandlers_exports);
26
- var import_backend = require("@tern-secure/backend");
24
+ module.exports = __toCommonJS(handlers_exports);
27
25
  var import_admin = require("@tern-secure/backend/admin");
28
26
  var import_jwt = require("@tern-secure/backend/jwt");
29
27
  var import_ternsecureClient = require("../../server/ternsecureClient");
30
28
  var import_NextCookieAdapter = require("../../utils/NextCookieAdapter");
31
29
  var import_constants = require("./constants");
32
- var import_fnValidators = require("./fnValidators");
33
30
  var import_request = require("./request");
34
31
  var import_responses = require("./responses");
35
32
  var import_signInCreateHandler = require("./signInCreateHandler");
33
+ var import_validators = require("./validators");
36
34
  const sessionEndpointHandler = async (context, config) => {
37
35
  const { subEndpoint, method, referrer } = context;
38
- const validators = (0, import_fnValidators.createValidators)(context);
39
- const {
40
- validateSubEndpoint,
41
- validateSecurity,
42
- validateSessionRequest,
43
- validateCsrfToken,
44
- validateIdToken
45
- } = validators;
46
- if (!subEndpoint) {
47
- return (0, import_responses.createApiErrorResponse)("SUB_ENDPOINT_REQUIRED", "Session sub-endpoint required", 400);
48
- }
49
- const sessionsConfig = config.endpoints?.sessions;
50
- const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];
51
- validateSubEndpoint(subEndpoint, subEndpointConfig);
52
- if (subEndpointConfig?.security) {
53
- await validateSecurity(subEndpointConfig.security);
54
- }
36
+ const subEndpointError = (0, import_validators.validateSubEndpointPresent)(context, "Session");
37
+ if (subEndpointError) return subEndpointError;
55
38
  const SessionGetHandler = async (subEndpoint2) => {
56
39
  const handleSessionVerify = async () => {
57
40
  try {
@@ -77,10 +60,10 @@ const sessionEndpointHandler = async (context, config) => {
77
60
  };
78
61
  const SessionPostHandler = async (subEndpoint2) => {
79
62
  const cookieStore = new import_NextCookieAdapter.NextCookieStore();
80
- const { idToken, csrfToken, error } = await validateSessionRequest();
63
+ const { idToken, csrfToken, error } = await (0, import_validators.extractSessionRequestData)(context.request);
81
64
  if (error) return error;
82
- const csrfCookieValue = await cookieStore.get(import_backend.constants.Cookies.CsrfToken);
83
- validateCsrfToken(csrfToken || "", csrfCookieValue.value);
65
+ const csrfError = await (0, import_validators.validateCsrfToken)(csrfToken);
66
+ if (csrfError) return csrfError;
84
67
  const handleCreateSession = async (cookieStore2, idToken2) => {
85
68
  try {
86
69
  await (0, import_request.refreshCookieWithIdToken)(idToken2, cookieStore2, config, referrer, context.appCheckToken);
@@ -119,7 +102,7 @@ const sessionEndpointHandler = async (context, config) => {
119
102
  };
120
103
  switch (subEndpoint2) {
121
104
  case "createsession": {
122
- const idTokenError = validateIdToken(idToken);
105
+ const idTokenError = (0, import_validators.validateIdToken)(idToken);
123
106
  if (idTokenError) return idTokenError;
124
107
  return handleCreateSession(cookieStore, idToken);
125
108
  }
@@ -140,90 +123,10 @@ const sessionEndpointHandler = async (context, config) => {
140
123
  return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
141
124
  }
142
125
  };
143
- const cookieEndpointHandler = async (context, config) => {
126
+ const signInEndpointHandler = async (context) => {
144
127
  const { subEndpoint, method } = context;
145
- const validators = (0, import_fnValidators.createValidators)(context);
146
- const { validateSecurity } = validators;
147
- if (!subEndpoint) {
148
- return (0, import_responses.createApiErrorResponse)("SUB_ENDPOINT_REQUIRED", "Cookie sub-endpoint required", 400);
149
- }
150
- const cookiesConfig = config.endpoints?.cookies;
151
- const subEndpointConfig = cookiesConfig?.subEndpoints?.[subEndpoint];
152
- if (!subEndpointConfig || !subEndpointConfig.enabled) {
153
- return (0, import_responses.createApiErrorResponse)("ENDPOINT_NOT_FOUND", "Cookie endpoint not found or disabled", 404);
154
- }
155
- if (subEndpointConfig?.security) {
156
- await validateSecurity(subEndpointConfig.security);
157
- }
158
- const CookieGetHandler = async (subEndpoint2) => {
159
- const handleGetCookie = async () => {
160
- try {
161
- const url = new URL(context.ternUrl);
162
- const tokenName = url.searchParams.get("tokenName");
163
- if (!tokenName) {
164
- return (0, import_responses.createApiErrorResponse)("TOKEN_NAME_REQUIRED", "tokenName query parameter is required", 400);
165
- }
166
- let cookieValue;
167
- switch (tokenName) {
168
- case "idToken":
169
- cookieValue = context.idTokenInCookie;
170
- break;
171
- case "sessionToken":
172
- cookieValue = context.sessionTokenInCookie;
173
- break;
174
- case "refreshToken":
175
- cookieValue = context.refreshTokenInCookie;
176
- break;
177
- case "customToken":
178
- cookieValue = context.customTokenInCookie;
179
- break;
180
- default:
181
- return (0, import_responses.createApiErrorResponse)("INVALID_TOKEN_NAME", "Invalid token name. Must be one of: idToken, sessionToken, refreshToken, customToken", 400);
182
- }
183
- if (!cookieValue) {
184
- return (0, import_responses.createApiErrorResponse)(
185
- "TOKEN_NOT_FOUND",
186
- `${tokenName} not found in httpOnly cookies`,
187
- 404
188
- );
189
- }
190
- return (0, import_responses.createApiSuccessResponse)({
191
- token: cookieValue
192
- });
193
- } catch (error) {
194
- return (0, import_responses.createApiErrorResponse)("COOKIE_RETRIEVAL_FAILED", "Failed to retrieve cookie", 500);
195
- }
196
- };
197
- switch (subEndpoint2) {
198
- case "get":
199
- return handleGetCookie();
200
- default:
201
- return import_responses.HttpResponseHelper.createNotFoundResponse();
202
- }
203
- };
204
- switch (method) {
205
- case "GET":
206
- return CookieGetHandler(subEndpoint);
207
- default:
208
- return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
209
- }
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
- }
128
+ const subEndpointError = (0, import_validators.validateSubEndpointPresent)(context, "Sign_ins");
129
+ if (subEndpointError) return subEndpointError;
227
130
  const PostHandler = async (subEndpoint2) => {
228
131
  const create = async () => {
229
132
  return await (0, import_signInCreateHandler.processSignInCreate)(context);
@@ -232,9 +135,8 @@ const signInEndpointHandler = async (context, config) => {
232
135
  try {
233
136
  const body = await context.request.json();
234
137
  const { email } = body;
235
- if (!email || typeof email !== "string") {
236
- return (0, import_responses.createApiErrorResponse)("EMAIL_REQUIRED", "Email is required", 400);
237
- }
138
+ const emailError = (0, import_validators.validateEmail)(email);
139
+ if (emailError) return emailError;
238
140
  const backendClient = await (0, import_ternsecureClient.ternSecureBackendClient)();
239
141
  const response = await backendClient.signIn.resetPasswordEmail(import_constants.FIREBASE_API_KEY, {
240
142
  email,
@@ -276,8 +178,7 @@ const signInEndpointHandler = async (context, config) => {
276
178
  };
277
179
  // Annotate the CommonJS export names for ESM import in node:
278
180
  0 && (module.exports = {
279
- cookieEndpointHandler,
280
181
  sessionEndpointHandler,
281
182
  signInEndpointHandler
282
183
  });
283
- //# sourceMappingURL=sessionHandlers.js.map
184
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app-router/admin/handlers.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { FIREBASE_API_KEY } from './constants';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, } from './types';\nimport {\n extractSessionRequestData,\n validateCsrfToken,\n validateEmail,\n validateIdToken,\n validateSubEndpointPresent,\n} from './validators';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Session');\n if (subEndpointError) return subEndpointError;\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 extractSessionRequestData(context.request);\n if (error) return error;\n\n const csrfError = await validateCsrfToken(csrfToken);\n if (csrfError) return csrfError;\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 as SessionSubEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint as SessionSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Sign_ins');\n if (subEndpointError) return subEndpointError;\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 const emailError = validateEmail(email);\n if (emailError) return emailError;\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 { sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
@@ -1 +1 @@
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'\n\nexport type { TernSecureHandlerOptions } from './types'"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAA8C;AAE9C,qBAOO;AAEP,4BAA+B;","names":[]}
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'\n\nexport type { ApiHandlerOptions, TernSecureHandlerOptions } from './types'"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAA8C;AAE9C,qBAOO;AAEP,4BAA+B;","names":[]}
@@ -31,14 +31,7 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer,
31
31
  const backendClient = await (0, import_ternsecureClient.ternSecureBackendClient)();
32
32
  const authOptions = {
33
33
  tenantId: config?.tenantId || void 0,
34
- firebaseConfig: {
35
- apiKey: import_constants.FIREBASE_API_KEY,
36
- authDomain: import_constants.FIREBASE_AUTH_DOMAIN,
37
- projectId: import_constants.FIREBASE_PROJECT_ID,
38
- storageBucket: import_constants.FIREBASE_STORAGE_BUCKET,
39
- messagingSenderId: import_constants.FIREBASE_MESSAGING_SENDER_ID,
40
- appId: import_constants.FIREBASE_APP_ID
41
- },
34
+ apiKey: import_constants.FIREBASE_API_KEY,
42
35
  apiClient: backendClient
43
36
  };
44
37
  const COOKIE_OPTIONS = (0, import_cookieOptionsHelper.getIdTokenCookieOptions)();
@@ -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 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":[]}
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} from './constants';\nimport { getIdTokenCookieOptions } from './cookieOptionsHelper';\nimport type { ApiHandlerOptions } from './types';\n\nexport async function refreshCookieWithIdToken(\n idToken: string,\n cookieStore: NextCookieStore,\n config: ApiHandlerOptions,\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 apiKey: FIREBASE_API_KEY,\n apiClient: backendClient,\n };\n\n const COOKIE_OPTIONS = getIdTokenCookieOptions();\n\n const { createCustomIdAndRefreshToken } = getAuth(authOptions);\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,uBAEO;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,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAEA,QAAM,qBAAiB,oDAAwB;AAE/C,QAAM,EAAE,8BAA8B,QAAI,qBAAQ,WAAW;AAE7D,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":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/signInCreateHandler.ts"],"sourcesContent":["import type { SignInCreateParams } from '@tern-secure/types';\n\nimport { RetrieveUser } from './actions';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n} from './responses';\n\n\nexport const processSignInCreate = async (\n context: RequestProcessorContext\n): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { strategy, identifier } = body as SignInCreateParams & { identifier?: string; password?: string };\n\n if (!strategy) {\n return createApiErrorResponse(\n 'STRATEGY_REQUIRED',\n 'Authentication strategy is required',\n 400\n );\n }\n\n if (!identifier) {\n return createApiSuccessResponse({\n status: 'needs_identifier',\n strategy,\n message: 'Identifier is required to continue',\n });\n }\n\n if (strategy === 'email_code') {\n return await processEmailCodeStrategy(identifier);\n }\n\n if (strategy === 'password') {\n return await processPasswordStrategy(identifier);\n }\n\n if (strategy === 'phone_code') {\n return processPhoneCodeStrategy(identifier);\n }\n\n if (strategy === 'reset_password_email_code' || strategy === 'reset_password_phone_code') {\n return await processResetPasswordStrategy(strategy, identifier);\n }\n\n return createApiErrorResponse(\n 'INVALID_STRATEGY',\n `Unsupported authentication strategy: ${strategy}`,\n 400\n );\n } catch (error) {\n return createApiErrorResponse(\n 'SIGN_IN_CREATE_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while creating sign-in',\n 500\n );\n }\n};\n\n/**\n * Processes email_code strategy\n * Verifies if user exists by email and returns needs_first_factor status\n */\nexport const processEmailCodeStrategy = async (email: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(email);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n if (!user.emailVerified) {\n return createApiSuccessResponse({\n status: 'needs_email_verification',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'Email verification required',\n });\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'User verified. Proceed with first factor authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this email address',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'EMAIL_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify email',\n 500\n );\n }\n};\n\n\nexport const processPasswordStrategy = async (identifier: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n supportedFirstFactors: [{ strategy: 'password' }],\n userId: user.uid,\n message: 'User verified. Proceed with password authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this identifier',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'USER_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify user',\n 500\n );\n }\n};\n\n\nexport const processPhoneCodeStrategy = async (phoneNumber: string): Promise<Response> => {\n try {\n //const retrieveUser = RetrieveUser();\n //const { data: user, error } = await retrieveUser.getUserByPhoneNumber(phoneNumber);\n\n //if (error) {\n // return createApiErrorResponse(\n // error.code,\n // error.message,\n // 400\n // );\n // }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: phoneNumber,\n supportedFirstFactors: [{ strategy: 'phone_code' }],\n //userId: user.uid,\n message: 'User verified. Proceed with phone authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this phone number',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'PHONE_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify phone number',\n 500\n );\n }\n};\n\n\nexport const processResetPasswordStrategy = async (\n strategy: 'reset_password_email_code' | 'reset_password_phone_code',\n identifier: string\n): Promise<Response> => {\n try {\n if (strategy === 'reset_password_email_code') {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n strategy,\n userId: user.uid,\n message: 'User verified. Proceed with password reset',\n });\n }\n\n return createApiErrorResponse(\n 'NOT_IMPLEMENTED',\n 'Phone reset password strategy not yet implemented',\n 501\n );\n } catch (error) {\n return createApiErrorResponse(\n 'RESET_PASSWORD_ERROR',\n error instanceof Error ? error.message : 'Failed to process password reset',\n 500\n );\n }\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/signInCreateHandler.ts"],"sourcesContent":["import type { RequestProcessorContext } from '@tern-secure/backend';\nimport type { SignInCreateParams } from '@tern-secure/types';\n\nimport { RetrieveUser } from './actions';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n} from './responses';\n\n\nexport const processSignInCreate = async (\n context: RequestProcessorContext\n): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { strategy, identifier } = body as SignInCreateParams & { identifier?: string; password?: string };\n\n if (!strategy) {\n return createApiErrorResponse(\n 'STRATEGY_REQUIRED',\n 'Authentication strategy is required',\n 400\n );\n }\n\n if (!identifier) {\n return createApiSuccessResponse({\n status: 'needs_identifier',\n strategy,\n message: 'Identifier is required to continue',\n });\n }\n\n if (strategy === 'email_code') {\n return await processEmailCodeStrategy(identifier);\n }\n\n if (strategy === 'password') {\n return await processPasswordStrategy(identifier);\n }\n\n if (strategy === 'phone_code') {\n return processPhoneCodeStrategy(identifier);\n }\n\n if (strategy === 'reset_password_email_code' || strategy === 'reset_password_phone_code') {\n return await processResetPasswordStrategy(strategy, identifier);\n }\n\n return createApiErrorResponse(\n 'INVALID_STRATEGY',\n `Unsupported authentication strategy: ${strategy}`,\n 400\n );\n } catch (error) {\n return createApiErrorResponse(\n 'SIGN_IN_CREATE_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while creating sign-in',\n 500\n );\n }\n};\n\n/**\n * Processes email_code strategy\n * Verifies if user exists by email and returns needs_first_factor status\n */\nexport const processEmailCodeStrategy = async (email: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(email);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n if (!user.emailVerified) {\n return createApiSuccessResponse({\n status: 'needs_email_verification',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'Email verification required',\n });\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'User verified. Proceed with first factor authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this email address',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'EMAIL_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify email',\n 500\n );\n }\n};\n\n\nexport const processPasswordStrategy = async (identifier: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n supportedFirstFactors: [{ strategy: 'password' }],\n userId: user.uid,\n message: 'User verified. Proceed with password authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this identifier',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'USER_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify user',\n 500\n );\n }\n};\n\n\nexport const processPhoneCodeStrategy = async (phoneNumber: string): Promise<Response> => {\n try {\n //const retrieveUser = RetrieveUser();\n //const { data: user, error } = await retrieveUser.getUserByPhoneNumber(phoneNumber);\n\n //if (error) {\n // return createApiErrorResponse(\n // error.code,\n // error.message,\n // 400\n // );\n // }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: phoneNumber,\n supportedFirstFactors: [{ strategy: 'phone_code' }],\n //userId: user.uid,\n message: 'User verified. Proceed with phone authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this phone number',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'PHONE_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify phone number',\n 500\n );\n }\n};\n\n\nexport const processResetPasswordStrategy = async (\n strategy: 'reset_password_email_code' | 'reset_password_phone_code',\n identifier: string\n): Promise<Response> => {\n try {\n if (strategy === 'reset_password_email_code') {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n strategy,\n userId: user.uid,\n message: 'User verified. Proceed with password reset',\n });\n }\n\n return createApiErrorResponse(\n 'NOT_IMPLEMENTED',\n 'Phone reset password strategy not yet implemented',\n 501\n );\n } catch (error) {\n return createApiErrorResponse(\n 'RESET_PASSWORD_ERROR',\n error instanceof Error ? error.message : 'Failed to process password reset',\n 500\n );\n }\n};\n"],"mappings":"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","names":[]}
@@ -22,30 +22,20 @@ __export(ternsecureNextjsHandler_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(ternsecureNextjsHandler_exports);
24
24
  var import_backend = require("@tern-secure/backend");
25
- var import_c_authenticateRequestProcessor = require("./c-authenticateRequestProcessor");
26
25
  var import_constants = require("./constants");
27
26
  var import_endpointRouter = require("./endpointRouter");
28
- var import_fnValidators = require("./fnValidators");
29
27
  var import_responses = require("./responses");
30
28
  var import_types = require("./types");
31
- var import_utils = require("./utils");
32
- function createHandlerConfig(options) {
33
- const baseConfig = import_utils.ConfigUtils.mergeWithDefaults(
34
- import_types.DEFAULT_HANDLER_OPTIONS,
35
- options
36
- );
37
- return {
38
- ...baseConfig,
39
- tenantId: import_constants.TENANT_ID
40
- };
41
- }
42
29
  function createTernSecureNextJsHandler(options) {
43
- const config = createHandlerConfig(options);
30
+ const config = {
31
+ ...import_types.DEFAULT_API_HANDLER_OPTIONS,
32
+ ...options,
33
+ tenantId: options?.tenantId || import_constants.TENANT_ID
34
+ };
44
35
  const handler = async (request) => {
45
36
  try {
46
- const context = (0, import_c_authenticateRequestProcessor.createRequestProcessor)((0, import_backend.createTernSecureRequest)(request), options);
47
- const { validateSecurity } = (0, import_fnValidators.createValidators)(context);
48
- await validateSecurity(options.security || {});
37
+ const ternRequest = (0, import_backend.createTernSecureRequest)(request);
38
+ const context = (0, import_backend.createRequestProcessor)(ternRequest, config);
49
39
  if (!context.endpoint) {
50
40
  return (0, import_responses.createApiErrorResponse)("ENDPOINT_REQUIRED", "Endpoint is required", 400);
51
41
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/ternsecureNextjsHandler.ts"],"sourcesContent":["import { createTernSecureRequest } from '@tern-secure/backend';\n\nimport { createRequestProcessor } from './c-authenticateRequestProcessor';\nimport { TENANT_ID } from './constants';\nimport { EndpointRouter } from './endpointRouter';\nimport { createValidators } from './fnValidators';\nimport { createApiErrorResponse } from './responses';\nimport type { TernSecureHandlerOptions } from './types';\nimport { DEFAULT_HANDLER_OPTIONS } from './types';\nimport { ConfigUtils } from './utils';\n\nfunction createHandlerConfig(options?: TernSecureHandlerOptions): TernSecureHandlerOptions {\n const baseConfig: Required<TernSecureHandlerOptions> = ConfigUtils.mergeWithDefaults(\n DEFAULT_HANDLER_OPTIONS,\n options,\n );\n\n return {\n ...baseConfig,\n tenantId: TENANT_ID,\n };\n}\n\nexport function createTernSecureNextJsHandler(options: TernSecureHandlerOptions) {\n const config = createHandlerConfig(options);\n\n const handler = async (request: Request): Promise<Response> => {\n try {\n const context = createRequestProcessor(createTernSecureRequest(request), options);\n\n const { validateSecurity } = createValidators(context);\n await validateSecurity(options.security || {});\n\n if (!context.endpoint) {\n return createApiErrorResponse('ENDPOINT_REQUIRED', 'Endpoint is required', 400);\n }\n\n return await EndpointRouter.route(context, config);\n } catch (error) {\n return createApiErrorResponse('INTERNAL_SERVER_ERROR', 'Internal server error', 500);\n }\n };\n\n return {\n GET: handler,\n POST: handler,\n } as const;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwC;AAExC,4CAAuC;AACvC,uBAA0B;AAC1B,4BAA+B;AAC/B,0BAAiC;AACjC,uBAAuC;AAEvC,mBAAwC;AACxC,mBAA4B;AAE5B,SAAS,oBAAoB,SAA8D;AACzF,QAAM,aAAiD,yBAAY;AAAA,IACjE;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,EACZ;AACF;AAEO,SAAS,8BAA8B,SAAmC;AAC/E,QAAM,SAAS,oBAAoB,OAAO;AAE1C,QAAM,UAAU,OAAO,YAAwC;AAC7D,QAAI;AACF,YAAM,cAAU,kEAAuB,wCAAwB,OAAO,GAAG,OAAO;AAEhF,YAAM,EAAE,iBAAiB,QAAI,sCAAiB,OAAO;AACrD,YAAM,iBAAiB,QAAQ,YAAY,CAAC,CAAC;AAE7C,UAAI,CAAC,QAAQ,UAAU;AACrB,mBAAO,yCAAuB,qBAAqB,wBAAwB,GAAG;AAAA,MAChF;AAEA,aAAO,MAAM,qCAAe,MAAM,SAAS,MAAM;AAAA,IACnD,SAAS,OAAO;AACd,iBAAO,yCAAuB,yBAAyB,yBAAyB,GAAG;AAAA,IACrF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/ternsecureNextjsHandler.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport { createRequestProcessor, createTernSecureRequest } from '@tern-secure/backend';\n\nimport { TENANT_ID } from './constants';\nimport { EndpointRouter } from './endpointRouter';\nimport { createApiErrorResponse } from './responses';\nimport { DEFAULT_API_HANDLER_OPTIONS } from './types';\n\n/**\n * Create API route handlers with unified options\n * Uses the same AuthenticateRequestOptions as middleware\n */\nexport function createTernSecureNextJsHandler(options?: AuthenticateRequestOptions) {\n const config: AuthenticateRequestOptions = {\n ...DEFAULT_API_HANDLER_OPTIONS,\n ...options,\n tenantId: options?.tenantId || TENANT_ID,\n };\n\n const handler = async (request: Request): Promise<Response> => {\n try {\n \n const ternRequest = createTernSecureRequest(request);\n const context = createRequestProcessor(ternRequest, config);\n\n if (!context.endpoint) {\n return createApiErrorResponse('ENDPOINT_REQUIRED', 'Endpoint is required', 400);\n }\n\n return await EndpointRouter.route(context, config);\n } catch (error) {\n return createApiErrorResponse('INTERNAL_SERVER_ERROR', 'Internal server error', 500);\n }\n };\n\n return {\n GET: handler,\n POST: handler,\n } as const;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAAgE;AAEhE,uBAA0B;AAC1B,4BAA+B;AAC/B,uBAAuC;AACvC,mBAA4C;AAMrC,SAAS,8BAA8B,SAAsC;AAClF,QAAM,SAAqC;AAAA,IACzC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,UAAU,SAAS,YAAY;AAAA,EACjC;AAEA,QAAM,UAAU,OAAO,YAAwC;AAC7D,QAAI;AAEF,YAAM,kBAAc,wCAAwB,OAAO;AACnD,YAAM,cAAU,uCAAuB,aAAa,MAAM;AAE1D,UAAI,CAAC,QAAQ,UAAU;AACrB,mBAAO,yCAAuB,qBAAqB,wBAAwB,GAAG;AAAA,MAChF;AAEA,aAAO,MAAM,qCAAe,MAAM,SAAS,MAAM;AAAA,IACnD,SAAS,OAAO;AACd,iBAAO,yCAAuB,yBAAyB,yBAAyB,GAAG;AAAA,IACrF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;","names":[]}
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var types_exports = {};
20
20
  __export(types_exports, {
21
21
  CookieUtils: () => CookieUtils,
22
+ DEFAULT_API_HANDLER_OPTIONS: () => DEFAULT_API_HANDLER_OPTIONS,
22
23
  DEFAULT_COOKIE_REQUEST_CONFIG: () => DEFAULT_COOKIE_REQUEST_CONFIG,
23
24
  DEFAULT_CORS_OPTIONS: () => DEFAULT_CORS_OPTIONS,
24
25
  DEFAULT_ENDPOINT_CONFIG: () => DEFAULT_ENDPOINT_CONFIG,
@@ -224,9 +225,17 @@ class CookieUtils {
224
225
  return maxAge >= minAge && maxAge <= maxAgeLimit;
225
226
  }
226
227
  }
228
+ const DEFAULT_API_HANDLER_OPTIONS = {
229
+ tenantId: void 0,
230
+ cookies: DEFAULT_SESSION_COOKIE_OPTIONS,
231
+ enableCustomToken: false,
232
+ debug: false,
233
+ revokeRefreshTokensOnSignOut: true
234
+ };
227
235
  // Annotate the CommonJS export names for ESM import in node:
228
236
  0 && (module.exports = {
229
237
  CookieUtils,
238
+ DEFAULT_API_HANDLER_OPTIONS,
230
239
  DEFAULT_COOKIE_REQUEST_CONFIG,
231
240
  DEFAULT_CORS_OPTIONS,
232
241
  DEFAULT_ENDPOINT_CONFIG,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import type {\n AuthEndpoint,\n CookieEndpointConfig,\n CookieOpts as CookieOptions,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionEndpointConfig,\n SessionSubEndpoint,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n TokenCookieConfig\n} from '@tern-secure/types';\nimport { type NextResponse } from 'next/server';\n\nexport const DEFAULT_CORS_OPTIONS: CorsOptions = {\n allowedOrigins: [],\n allowedMethods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n allowCredentials: true,\n maxAge: 86400, // 24 hours\n};\n\nexport const DEFAULT_SESSION_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\nexport const DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\n\nexport const FIXED_TOKEN_CONFIGS = {\n id: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600, // 1 hour\n },\n refresh: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 30, // 30 days (changes when user events occur)\n },\n signature: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n custom: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n} as const;\n\nexport const DEFAULT_SECURITY_OPTIONS: SecurityOptions = {\n requireCSRF: true,\n allowedReferers: [],\n requiredHeaders: {},\n ipWhitelist: [],\n userAgent: {\n block: [],\n allow: [],\n },\n};\n\nexport const DEFAULT_ENDPOINT_CONFIG: EndpointConfig = {\n enabled: true,\n methods: ['GET', 'POST'],\n requireAuth: false,\n security: DEFAULT_SECURITY_OPTIONS,\n};\n\nexport const DEFAULT_COOKIE_REQUEST_CONFIG: CookieEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n get: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n },\n};\n\nexport const DEFAULT_SESSIONS_CONFIG: SessionEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n verify: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n createsession: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n },\n },\n refresh: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n revoke: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n },\n};\n\nexport const DEFAULT_SIGNINS_CONFIG: SignInEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n resetPasswordEmail: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false\n },\n },\n};\n\nexport const DEFAULT_HANDLER_OPTIONS: Required<TernSecureHandlerOptions> & {\n endpoints: Required<NonNullable<TernSecureHandlerOptions['endpoints']>>;\n} = {\n cors: DEFAULT_CORS_OPTIONS,\n cookies: DEFAULT_SESSION_COOKIE_OPTIONS,\n rateLimit: {\n windowMs: 15 * 60 * 1000, // 15 minutes\n maxRequests: 100,\n skipSuccessful: false,\n skipFailedRequests: false,\n },\n security: DEFAULT_SECURITY_OPTIONS,\n endpoints: {\n cookies: DEFAULT_COOKIE_REQUEST_CONFIG,\n sessions: DEFAULT_SESSIONS_CONFIG,\n signIns: DEFAULT_SIGNINS_CONFIG,\n },\n tenantId: '',\n revokeRefreshTokensOnSignOut: true,\n enableCustomToken: false,\n debug: false,\n environment: 'production',\n basePath: '/api/auth',\n};\n\nexport interface ValidationResult {\n error?: NextResponse;\n data?: any;\n}\n\nexport interface ValidationConfig {\n cors?: CorsOptions;\n security?: SecurityOptions;\n endpoint?: {\n name: AuthEndpoint;\n config: EndpointConfig;\n };\n subEndpoint?: {\n name: SessionSubEndpoint;\n config: EndpointConfig;\n };\n requireIdToken?: boolean;\n requireCsrfToken?: boolean;\n}\n\nexport interface ComprehensiveValidationResult {\n isValid: boolean;\n error?: Response;\n corsResponse?: Response;\n sessionData?: {\n body: any;\n idToken?: string;\n csrfToken?: string;\n };\n}\n\nexport type suffix = 'session' | 'id' | 'refresh' | 'signature' | 'custom';\n\nexport class CookieUtils {\n static getCookieName(namePrefix: string, tokenType: suffix): string {\n return `${namePrefix}.${tokenType}`;\n }\n\n static getCookieNames(namePrefix: string) {\n return {\n session: this.getCookieName(namePrefix, 'session'),\n id: this.getCookieName(namePrefix, 'id'),\n refresh: this.getCookieName(namePrefix, 'refresh'),\n signature: this.getCookieName(namePrefix, 'signature'),\n custom: this.getCookieName(namePrefix, 'custom'),\n };\n }\n\n static getSessionConfig(cookieOptions: CookieOptions): TokenCookieConfig {\n return {\n path: cookieOptions.path ?? '/',\n httpOnly: cookieOptions.httpOnly ?? true,\n sameSite: cookieOptions.sameSite ?? 'lax',\n maxAge: cookieOptions.maxAge ?? 3600 * 24 * 7,\n };\n }\n\n static getFixedTokenConfig(\n tokenType: Exclude<suffix, 'session'>,\n ): TokenCookieConfig {\n const fixedConfig = FIXED_TOKEN_CONFIGS[tokenType];\n\n return {\n path: fixedConfig.path,\n httpOnly: fixedConfig.httpOnly,\n sameSite: fixedConfig.sameSite,\n maxAge: fixedConfig.maxAge,\n };\n }\n\n static validateSessionMaxAge(maxAge: number): boolean {\n const minAge = 300; // 5 minutes\n const maxAgeLimit = 3600 * 24 * 14; // 2 weeks\n return maxAge >= minAge && maxAge <= maxAgeLimit;\n }\n}\n\nexport {\n AuthEndpoint,\n CookieOptions,\n CorsOptions,\n SecurityOptions,\n SessionSubEndpoint,\n EndpointConfig,\n SessionEndpointConfig,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport type {\n AuthEndpoint,\n AuthSubEndpoint,\n CookieEndpointConfig,\n CookieOpts as CookieOptions,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionEndpointConfig,\n SessionSubEndpoint,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n TokenCookieConfig\n} from '@tern-secure/types';\nimport { type NextResponse } from 'next/server';\n\n\n\nexport const DEFAULT_CORS_OPTIONS: CorsOptions = {\n allowedOrigins: [],\n allowedMethods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n allowCredentials: true,\n maxAge: 86400, // 24 hours\n};\n\nexport const DEFAULT_SESSION_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\nexport const DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\n\nexport const FIXED_TOKEN_CONFIGS = {\n id: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600, // 1 hour\n },\n refresh: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 30, // 30 days (changes when user events occur)\n },\n signature: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n custom: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n} as const;\n\nexport const DEFAULT_SECURITY_OPTIONS: SecurityOptions = {\n requireCSRF: true,\n allowedReferers: [],\n requiredHeaders: {},\n ipWhitelist: [],\n userAgent: {\n block: [],\n allow: [],\n },\n};\n\nexport const DEFAULT_ENDPOINT_CONFIG: EndpointConfig = {\n enabled: true,\n methods: ['GET', 'POST'],\n requireAuth: false,\n security: DEFAULT_SECURITY_OPTIONS,\n};\n\nexport const DEFAULT_COOKIE_REQUEST_CONFIG: CookieEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n get: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n },\n};\n\nexport const DEFAULT_SESSIONS_CONFIG: SessionEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n verify: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n createsession: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n },\n },\n refresh: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n revoke: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n },\n};\n\nexport const DEFAULT_SIGNINS_CONFIG: SignInEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n resetPasswordEmail: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false\n },\n },\n};\n\nexport const DEFAULT_HANDLER_OPTIONS: Required<TernSecureHandlerOptions> & {\n endpoints: Required<NonNullable<TernSecureHandlerOptions['endpoints']>>;\n} = {\n cors: DEFAULT_CORS_OPTIONS,\n cookies: DEFAULT_SESSION_COOKIE_OPTIONS,\n rateLimit: {\n windowMs: 15 * 60 * 1000, // 15 minutes\n maxRequests: 100,\n skipSuccessful: false,\n skipFailedRequests: false,\n },\n security: DEFAULT_SECURITY_OPTIONS,\n endpoints: {\n cookies: DEFAULT_COOKIE_REQUEST_CONFIG,\n sessions: DEFAULT_SESSIONS_CONFIG,\n signIns: DEFAULT_SIGNINS_CONFIG,\n },\n tenantId: '',\n revokeRefreshTokensOnSignOut: true,\n enableCustomToken: false,\n debug: false,\n environment: 'production',\n basePath: '/api/auth',\n};\n\nexport interface ValidationResult {\n error?: NextResponse;\n data?: any;\n}\n\nexport interface ValidationConfig {\n cors?: CorsOptions;\n security?: SecurityOptions;\n endpoint?: {\n name: AuthEndpoint;\n config: EndpointConfig;\n };\n subEndpoint?: {\n name: SessionSubEndpoint;\n config: EndpointConfig;\n };\n requireIdToken?: boolean;\n requireCsrfToken?: boolean;\n}\n\nexport interface ComprehensiveValidationResult {\n isValid: boolean;\n error?: Response;\n corsResponse?: Response;\n sessionData?: {\n body: any;\n idToken?: string;\n csrfToken?: string;\n };\n}\n\nexport type suffix = 'session' | 'id' | 'refresh' | 'signature' | 'custom';\n\nexport class CookieUtils {\n static getCookieName(namePrefix: string, tokenType: suffix): string {\n return `${namePrefix}.${tokenType}`;\n }\n\n static getCookieNames(namePrefix: string) {\n return {\n session: this.getCookieName(namePrefix, 'session'),\n id: this.getCookieName(namePrefix, 'id'),\n refresh: this.getCookieName(namePrefix, 'refresh'),\n signature: this.getCookieName(namePrefix, 'signature'),\n custom: this.getCookieName(namePrefix, 'custom'),\n };\n }\n\n static getSessionConfig(cookieOptions: CookieOptions): TokenCookieConfig {\n return {\n path: cookieOptions.path ?? '/',\n httpOnly: cookieOptions.httpOnly ?? true,\n sameSite: cookieOptions.sameSite ?? 'lax',\n maxAge: cookieOptions.maxAge ?? 3600 * 24 * 7,\n };\n }\n\n static getFixedTokenConfig(\n tokenType: Exclude<suffix, 'session'>,\n ): TokenCookieConfig {\n const fixedConfig = FIXED_TOKEN_CONFIGS[tokenType];\n\n return {\n path: fixedConfig.path,\n httpOnly: fixedConfig.httpOnly,\n sameSite: fixedConfig.sameSite,\n maxAge: fixedConfig.maxAge,\n };\n }\n\n static validateSessionMaxAge(maxAge: number): boolean {\n const minAge = 300; // 5 minutes\n const maxAgeLimit = 3600 * 24 * 14; // 2 weeks\n return maxAge >= minAge && maxAge <= maxAgeLimit;\n }\n}\n\n/**\n * API Handler Options - Unified with Middleware\n * \n * Since API routes are protected by middleware, they use the same\n * AuthenticateRequestOptions type. No separate config needed.\n * \n * Key fields used by API handlers:\n * - tenantId: Multi-tenant support\n * - enableCustomToken: Whether to create custom token cookie\n * - debug: Debug logging\n * - revokeRefreshTokensOnSignOut: Token revocation behavior\n * \n * Fields handled by middleware (not needed in API):\n * - firebaseConfig: Used for authentication\n * - firebaseAdminConfig: Server-side Firebase admin\n * - checkRevoked: Token revocation checking\n */\nexport type ApiHandlerOptions = AuthenticateRequestOptions & {\n cookies?: CookieOptions;\n};\n\nexport const DEFAULT_API_HANDLER_OPTIONS: Partial<ApiHandlerOptions> = {\n tenantId: undefined,\n cookies: DEFAULT_SESSION_COOKIE_OPTIONS,\n enableCustomToken: false,\n debug: false,\n revokeRefreshTokensOnSignOut: true,\n};\n\nexport {\n AuthEndpoint,\n AuthSubEndpoint,\n CookieOptions,\n CorsOptions,\n SecurityOptions,\n SessionSubEndpoint,\n EndpointConfig,\n SessionEndpointConfig,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n};\n"],"mappings":"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","names":[]}