@tern-secure/nextjs 5.2.0-canary.v20251030165007 → 5.2.0-canary.v20251125170702

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 (137) hide show
  1. package/dist/cjs/app-router/admin/actions.js +5 -0
  2. package/dist/cjs/app-router/admin/actions.js.map +1 -1
  3. package/dist/cjs/app-router/admin/cookieOptionsHelper.js +28 -16
  4. package/dist/cjs/app-router/admin/cookieOptionsHelper.js.map +1 -1
  5. package/dist/cjs/app-router/admin/endpointRouter.js +10 -1
  6. package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -1
  7. package/dist/cjs/app-router/admin/request.js +6 -1
  8. package/dist/cjs/app-router/admin/request.js.map +1 -1
  9. package/dist/cjs/app-router/admin/sessionHandlers.js +79 -7
  10. package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
  11. package/dist/cjs/app-router/admin/signInCreateHandler.js +213 -0
  12. package/dist/cjs/app-router/admin/signInCreateHandler.js.map +1 -0
  13. package/dist/cjs/app-router/admin/types.js +33 -11
  14. package/dist/cjs/app-router/admin/types.js.map +1 -1
  15. package/dist/cjs/app-router/client/TernSecureProvider.js +5 -1
  16. package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
  17. package/dist/cjs/app-router/server/TernSecureProvider.js +1 -1
  18. package/dist/cjs/app-router/server/TernSecureProvider.js.map +1 -1
  19. package/dist/cjs/app-router/server/auth.js +1 -1
  20. package/dist/cjs/app-router/server/auth.js.map +1 -1
  21. package/dist/cjs/boundary/components.js +2 -12
  22. package/dist/cjs/boundary/components.js.map +1 -1
  23. package/dist/cjs/{app-router/server/auth_new.js → components/uiComponents.js} +18 -17
  24. package/dist/cjs/components/uiComponents.js.map +1 -0
  25. package/dist/cjs/index.js +9 -15
  26. package/dist/cjs/index.js.map +1 -1
  27. package/dist/cjs/server/data/getAuthDataFromRequest.js +15 -15
  28. package/dist/cjs/server/data/getAuthDataFromRequest.js.map +1 -1
  29. package/dist/cjs/server/index.js +3 -6
  30. package/dist/cjs/server/index.js.map +1 -1
  31. package/dist/cjs/server/{ternSecureEdgeMiddleware.js → ternSecureProxy.js} +32 -9
  32. package/dist/cjs/server/ternSecureProxy.js.map +1 -0
  33. package/dist/cjs/server/utils.js +1 -1
  34. package/dist/cjs/server/utils.js.map +1 -1
  35. package/dist/cjs/utils/allNextProviderProps.js +17 -3
  36. package/dist/cjs/utils/allNextProviderProps.js.map +1 -1
  37. package/dist/cjs/utils/config.js +1 -0
  38. package/dist/cjs/utils/config.js.map +1 -1
  39. package/dist/cjs/utils/tern-ui-script.js +72 -0
  40. package/dist/cjs/utils/tern-ui-script.js.map +1 -0
  41. package/dist/esm/app-router/admin/actions.js +5 -0
  42. package/dist/esm/app-router/admin/actions.js.map +1 -1
  43. package/dist/esm/app-router/admin/cookieOptionsHelper.js +26 -15
  44. package/dist/esm/app-router/admin/cookieOptionsHelper.js.map +1 -1
  45. package/dist/esm/app-router/admin/endpointRouter.js +11 -2
  46. package/dist/esm/app-router/admin/endpointRouter.js.map +1 -1
  47. package/dist/esm/app-router/admin/request.js +7 -2
  48. package/dist/esm/app-router/admin/request.js.map +1 -1
  49. package/dist/esm/app-router/admin/sessionHandlers.js +83 -7
  50. package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
  51. package/dist/esm/app-router/admin/signInCreateHandler.js +188 -0
  52. package/dist/esm/app-router/admin/signInCreateHandler.js.map +1 -0
  53. package/dist/esm/app-router/admin/types.js +30 -10
  54. package/dist/esm/app-router/admin/types.js.map +1 -1
  55. package/dist/esm/app-router/client/TernSecureProvider.js +6 -2
  56. package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
  57. package/dist/esm/app-router/server/TernSecureProvider.js +2 -2
  58. package/dist/esm/app-router/server/TernSecureProvider.js.map +1 -1
  59. package/dist/esm/app-router/server/auth.js +2 -2
  60. package/dist/esm/app-router/server/auth.js.map +1 -1
  61. package/dist/esm/boundary/components.js +1 -11
  62. package/dist/esm/boundary/components.js.map +1 -1
  63. package/dist/esm/components/uiComponents.js +21 -0
  64. package/dist/esm/components/uiComponents.js.map +1 -0
  65. package/dist/esm/index.js +10 -14
  66. package/dist/esm/index.js.map +1 -1
  67. package/dist/esm/server/data/getAuthDataFromRequest.js +21 -13
  68. package/dist/esm/server/data/getAuthDataFromRequest.js.map +1 -1
  69. package/dist/esm/server/index.js +2 -8
  70. package/dist/esm/server/index.js.map +1 -1
  71. package/dist/esm/server/{ternSecureEdgeMiddleware.js → ternSecureProxy.js} +30 -7
  72. package/dist/esm/server/ternSecureProxy.js.map +1 -0
  73. package/dist/esm/server/utils.js +1 -1
  74. package/dist/esm/server/utils.js.map +1 -1
  75. package/dist/esm/utils/allNextProviderProps.js +17 -3
  76. package/dist/esm/utils/allNextProviderProps.js.map +1 -1
  77. package/dist/esm/utils/config.js +1 -0
  78. package/dist/esm/utils/config.js.map +1 -1
  79. package/dist/esm/utils/tern-ui-script.js +38 -0
  80. package/dist/esm/utils/tern-ui-script.js.map +1 -0
  81. package/dist/types/app-router/admin/actions.d.ts +23 -0
  82. package/dist/types/app-router/admin/actions.d.ts.map +1 -1
  83. package/dist/types/app-router/admin/cookieOptionsHelper.d.ts +2 -10
  84. package/dist/types/app-router/admin/cookieOptionsHelper.d.ts.map +1 -1
  85. package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -1
  86. package/dist/types/app-router/admin/request.d.ts.map +1 -1
  87. package/dist/types/app-router/admin/sessionHandlers.d.ts +4 -3
  88. package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
  89. package/dist/types/app-router/admin/signInCreateHandler.d.ts +11 -0
  90. package/dist/types/app-router/admin/signInCreateHandler.d.ts.map +1 -0
  91. package/dist/types/app-router/admin/types.d.ts +5 -3
  92. package/dist/types/app-router/admin/types.d.ts.map +1 -1
  93. package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
  94. package/dist/types/app-router/server/auth.d.ts.map +1 -1
  95. package/dist/types/boundary/components.d.ts +1 -1
  96. package/dist/types/boundary/components.d.ts.map +1 -1
  97. package/dist/types/components/uiComponents.d.ts +6 -0
  98. package/dist/types/components/uiComponents.d.ts.map +1 -0
  99. package/dist/types/index.d.ts +3 -3
  100. package/dist/types/index.d.ts.map +1 -1
  101. package/dist/types/server/data/getAuthDataFromRequest.d.ts +6 -6
  102. package/dist/types/server/data/getAuthDataFromRequest.d.ts.map +1 -1
  103. package/dist/types/server/index.d.ts +1 -2
  104. package/dist/types/server/index.d.ts.map +1 -1
  105. package/dist/types/server/{ternSecureEdgeMiddleware.d.ts → ternSecureProxy.d.ts} +2 -2
  106. package/dist/types/server/ternSecureProxy.d.ts.map +1 -0
  107. package/dist/types/utils/allNextProviderProps.d.ts.map +1 -1
  108. package/dist/types/utils/config.d.ts.map +1 -1
  109. package/dist/types/utils/tern-ui-script.d.ts +8 -0
  110. package/dist/types/utils/tern-ui-script.d.ts.map +1 -0
  111. package/package.json +7 -9
  112. package/dist/cjs/app-router/server/TernSecureProviderNode.js +0 -92
  113. package/dist/cjs/app-router/server/TernSecureProviderNode.js.map +0 -1
  114. package/dist/cjs/app-router/server/auth_new.js.map +0 -1
  115. package/dist/cjs/server/ternSecureEdgeMiddleware.js.map +0 -1
  116. package/dist/cjs/utils/admin-init.js +0 -4
  117. package/dist/cjs/utils/admin-init.js.map +0 -1
  118. package/dist/cjs/utils/client-init.js +0 -4
  119. package/dist/cjs/utils/client-init.js.map +0 -1
  120. package/dist/esm/app-router/server/TernSecureProviderNode.js +0 -58
  121. package/dist/esm/app-router/server/TernSecureProviderNode.js.map +0 -1
  122. package/dist/esm/app-router/server/auth_new.js +0 -17
  123. package/dist/esm/app-router/server/auth_new.js.map +0 -1
  124. package/dist/esm/server/ternSecureEdgeMiddleware.js.map +0 -1
  125. package/dist/esm/utils/admin-init.js +0 -3
  126. package/dist/esm/utils/admin-init.js.map +0 -1
  127. package/dist/esm/utils/client-init.js +0 -3
  128. package/dist/esm/utils/client-init.js.map +0 -1
  129. package/dist/types/app-router/server/TernSecureProviderNode.d.ts +0 -4
  130. package/dist/types/app-router/server/TernSecureProviderNode.d.ts.map +0 -1
  131. package/dist/types/app-router/server/auth_new.d.ts +0 -14
  132. package/dist/types/app-router/server/auth_new.d.ts.map +0 -1
  133. package/dist/types/server/ternSecureEdgeMiddleware.d.ts.map +0 -1
  134. package/dist/types/utils/admin-init.d.ts +0 -2
  135. package/dist/types/utils/admin-init.d.ts.map +0 -1
  136. package/dist/types/utils/client-init.d.ts +0 -2
  137. package/dist/types/utils/client-init.d.ts.map +0 -1
@@ -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\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"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAQO;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;","names":[]}
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"]}
@@ -18,34 +18,46 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var cookieOptionsHelper_exports = {};
20
20
  __export(cookieOptionsHelper_exports, {
21
- getCookieOptions: () => getCookieOptions,
22
- getDeleteOptions: () => getDeleteOptions
21
+ getDeleteOptions: () => getDeleteOptions,
22
+ getIdTokenCookieOptions: () => getIdTokenCookieOptions,
23
+ getSessionCookieOptions: () => getSessionCookieOptions
23
24
  });
24
25
  module.exports = __toCommonJS(cookieOptionsHelper_exports);
25
26
  var import_types = require("./types");
26
- function getCookieOptions(config) {
27
+ const ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60;
28
+ function getIdTokenCookieOptions() {
27
29
  return {
28
- path: config?.cookies?.path ?? import_types.DEFAULT_COOKIE_OPTIONS.path ?? "/",
29
- httpOnly: config?.cookies?.httpOnly ?? import_types.DEFAULT_COOKIE_OPTIONS.httpOnly ?? true,
30
- secure: config?.cookies?.secure ?? import_types.DEFAULT_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === "production",
31
- sameSite: config?.cookies?.sameSite ?? import_types.DEFAULT_COOKIE_OPTIONS.sameSite ?? "strict",
32
- maxAge: config?.cookies?.maxAge ?? import_types.DEFAULT_COOKIE_OPTIONS.maxAge,
33
- priority: config?.cookies?.priority ?? import_types.DEFAULT_COOKIE_OPTIONS.priority
30
+ path: "/",
31
+ httpOnly: true,
32
+ secure: process.env.NODE_ENV === "production",
33
+ sameSite: "strict",
34
+ maxAge: ONE_YEAR_IN_SECONDS,
35
+ priority: "high"
36
+ };
37
+ }
38
+ function getSessionCookieOptions(config) {
39
+ return {
40
+ path: config?.cookies?.path ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.path ?? "/",
41
+ httpOnly: config?.cookies?.httpOnly ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.httpOnly ?? true,
42
+ secure: config?.cookies?.secure ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === "production",
43
+ sameSite: config?.cookies?.sameSite ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.sameSite ?? "strict",
44
+ maxAge: config?.cookies?.maxAge ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.maxAge,
45
+ priority: config?.cookies?.priority ?? import_types.DEFAULT_SESSION_COOKIE_OPTIONS.priority
34
46
  };
35
47
  }
36
48
  function getDeleteOptions(options) {
37
49
  return {
38
- path: options?.cookies?.path ?? import_types.DEFAULT_COOKIE_OPTIONS.path ?? "/",
39
- httpOnly: options?.cookies?.httpOnly ?? import_types.DEFAULT_COOKIE_OPTIONS.httpOnly ?? true,
40
- secure: options?.cookies?.secure ?? import_types.DEFAULT_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === "production",
41
- sameSite: options?.cookies?.sameSite ?? import_types.DEFAULT_COOKIE_OPTIONS.sameSite ?? "strict",
50
+ path: options?.cookies?.path ?? import_types.DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.path ?? "/",
51
+ httpOnly: options?.cookies?.httpOnly ?? import_types.DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.httpOnly ?? true,
52
+ secure: options?.cookies?.secure ?? import_types.DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === "production",
53
+ sameSite: options?.cookies?.sameSite ?? import_types.DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.sameSite ?? "strict",
42
54
  revokeRefreshTokensOnSignOut: options?.revokeRefreshTokensOnSignOut ?? true
43
- // Domain is intentionally omitted to use current domain
44
55
  };
45
56
  }
46
57
  // Annotate the CommonJS export names for ESM import in node:
47
58
  0 && (module.exports = {
48
- getCookieOptions,
49
- getDeleteOptions
59
+ getDeleteOptions,
60
+ getIdTokenCookieOptions,
61
+ getSessionCookieOptions
50
62
  });
51
63
  //# sourceMappingURL=cookieOptionsHelper.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/cookieOptionsHelper.ts"],"sourcesContent":["import type { CookieOptions, TernSecureHandlerOptions } from '@tern-secure/types';\n\nimport { DEFAULT_COOKIE_OPTIONS } from './types';\n\n/**\n * Creates complete cookie options by merging config with defaults\n * Used for both setting and deleting cookies to ensure consistency\n */\nexport function getCookieOptions(\n config?: TernSecureHandlerOptions,\n): Required<Pick<CookieOptions, 'path' | 'httpOnly' | 'secure' | 'sameSite'>> &\n Pick<CookieOptions, 'maxAge' | 'priority'> {\n return {\n path: config?.cookies?.path ?? DEFAULT_COOKIE_OPTIONS.path ?? '/',\n httpOnly: config?.cookies?.httpOnly ?? DEFAULT_COOKIE_OPTIONS.httpOnly ?? true,\n secure:\n config?.cookies?.secure ?? DEFAULT_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === 'production',\n sameSite: config?.cookies?.sameSite ?? DEFAULT_COOKIE_OPTIONS.sameSite ?? 'strict',\n maxAge: config?.cookies?.maxAge ?? DEFAULT_COOKIE_OPTIONS.maxAge,\n priority: config?.cookies?.priority ?? DEFAULT_COOKIE_OPTIONS.priority,\n };\n}\n\n/**\n * Extracts options needed for cookie deletion\n * For __HOST- prefixed cookies, all security attributes must match\n * @param options - Object containing cookies config and revokeRefreshTokensOnSignOut flag\n */\nexport function getDeleteOptions(options?: {\n cookies?: TernSecureHandlerOptions['cookies'];\n revokeRefreshTokensOnSignOut?: boolean;\n}): {\n path: string;\n httpOnly?: boolean;\n secure?: boolean;\n domain?: string;\n sameSite?: 'lax' | 'strict' | 'none';\n revokeRefreshTokensOnSignOut?: boolean;\n} {\n return {\n path: options?.cookies?.path ?? DEFAULT_COOKIE_OPTIONS.path ?? '/',\n httpOnly: options?.cookies?.httpOnly ?? DEFAULT_COOKIE_OPTIONS.httpOnly ?? true,\n secure:\n options?.cookies?.secure ?? DEFAULT_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === 'production',\n sameSite: options?.cookies?.sameSite ?? DEFAULT_COOKIE_OPTIONS.sameSite ?? 'strict',\n revokeRefreshTokensOnSignOut: options?.revokeRefreshTokensOnSignOut ?? true,\n // Domain is intentionally omitted to use current domain\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAuC;AAMhC,SAAS,iBACd,QAE2C;AAC3C,SAAO;AAAA,IACL,MAAM,QAAQ,SAAS,QAAQ,oCAAuB,QAAQ;AAAA,IAC9D,UAAU,QAAQ,SAAS,YAAY,oCAAuB,YAAY;AAAA,IAC1E,QACE,QAAQ,SAAS,UAAU,oCAAuB,UAAU,QAAQ,IAAI,aAAa;AAAA,IACvF,UAAU,QAAQ,SAAS,YAAY,oCAAuB,YAAY;AAAA,IAC1E,QAAQ,QAAQ,SAAS,UAAU,oCAAuB;AAAA,IAC1D,UAAU,QAAQ,SAAS,YAAY,oCAAuB;AAAA,EAChE;AACF;AAOO,SAAS,iBAAiB,SAU/B;AACA,SAAO;AAAA,IACL,MAAM,SAAS,SAAS,QAAQ,oCAAuB,QAAQ;AAAA,IAC/D,UAAU,SAAS,SAAS,YAAY,oCAAuB,YAAY;AAAA,IAC3E,QACE,SAAS,SAAS,UAAU,oCAAuB,UAAU,QAAQ,IAAI,aAAa;AAAA,IACxF,UAAU,SAAS,SAAS,YAAY,oCAAuB,YAAY;AAAA,IAC3E,8BAA8B,SAAS,gCAAgC;AAAA;AAAA,EAEzE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/cookieOptionsHelper.ts"],"sourcesContent":["import type { CookieOptions, TernSecureHandlerOptions } from '@tern-secure/types';\n\nimport { DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS, DEFAULT_SESSION_COOKIE_OPTIONS } from './types';\n\nconst ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60;\n\n\nexport function getIdTokenCookieOptions(\n): Required<Pick<CookieOptions, 'path' | 'httpOnly' | 'secure' | 'sameSite'>> &\n Pick<CookieOptions, 'maxAge' | 'priority'> {\n return {\n path: '/',\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: ONE_YEAR_IN_SECONDS,\n priority: 'high',\n };\n}\n\nexport function getSessionCookieOptions(\n config?: TernSecureHandlerOptions,\n): Required<Pick<CookieOptions, 'path' | 'httpOnly' | 'secure' | 'sameSite'>> &\n Pick<CookieOptions, 'maxAge' | 'priority'> {\n return {\n path: config?.cookies?.path ?? DEFAULT_SESSION_COOKIE_OPTIONS.path ?? '/',\n httpOnly: config?.cookies?.httpOnly ?? DEFAULT_SESSION_COOKIE_OPTIONS.httpOnly ?? true,\n secure:\n config?.cookies?.secure ?? DEFAULT_SESSION_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === 'production',\n sameSite: config?.cookies?.sameSite ?? DEFAULT_SESSION_COOKIE_OPTIONS.sameSite ?? 'strict',\n maxAge: config?.cookies?.maxAge ?? DEFAULT_SESSION_COOKIE_OPTIONS.maxAge,\n priority: config?.cookies?.priority ?? DEFAULT_SESSION_COOKIE_OPTIONS.priority,\n };\n}\n\n\nexport function getDeleteOptions(options?: {\n cookies?: TernSecureHandlerOptions['cookies'];\n revokeRefreshTokensOnSignOut?: boolean;\n}): {\n path: string;\n httpOnly?: boolean;\n secure?: boolean;\n domain?: string;\n sameSite?: 'lax' | 'strict' | 'none';\n revokeRefreshTokensOnSignOut?: boolean;\n} {\n return {\n path: options?.cookies?.path ?? DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.path ?? '/',\n httpOnly: options?.cookies?.httpOnly ?? DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.httpOnly ?? true,\n secure:\n options?.cookies?.secure ?? DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.secure ?? process.env.NODE_ENV === 'production',\n sameSite: options?.cookies?.sameSite ?? DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS.sameSite ?? 'strict',\n revokeRefreshTokensOnSignOut: options?.revokeRefreshTokensOnSignOut ?? true,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAwF;AAExF,MAAM,sBAAsB,MAAM,KAAK,KAAK;AAGrC,SAAS,0BAE6B;AAC3C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEO,SAAS,wBACd,QAE2C;AAC3C,SAAO;AAAA,IACL,MAAM,QAAQ,SAAS,QAAQ,4CAA+B,QAAQ;AAAA,IACtE,UAAU,QAAQ,SAAS,YAAY,4CAA+B,YAAY;AAAA,IAClF,QACE,QAAQ,SAAS,UAAU,4CAA+B,UAAU,QAAQ,IAAI,aAAa;AAAA,IAC/F,UAAU,QAAQ,SAAS,YAAY,4CAA+B,YAAY;AAAA,IAClF,QAAQ,QAAQ,SAAS,UAAU,4CAA+B;AAAA,IAClE,UAAU,QAAQ,SAAS,YAAY,4CAA+B;AAAA,EACxE;AACF;AAGO,SAAS,iBAAiB,SAU/B;AACA,SAAO;AAAA,IACL,MAAM,SAAS,SAAS,QAAQ,qDAAwC,QAAQ;AAAA,IAChF,UAAU,SAAS,SAAS,YAAY,qDAAwC,YAAY;AAAA,IAC5F,QACE,SAAS,SAAS,UAAU,qDAAwC,UAAU,QAAQ,IAAI,aAAa;AAAA,IACzG,UAAU,SAAS,SAAS,YAAY,qDAAwC,YAAY;AAAA,IAC5F,8BAA8B,SAAS,gCAAgC;AAAA,EACzE;AACF;","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,6BAA8D;AAQ9D,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;AAEO,MAAM,eAAe;AAAA,EAC1B,OAAwB,WAA8B;AAAA,IACpD,IAAI,gBAAgB;AAAA,IACpB,IAAI,aAAa;AAAA,IACjB,IAAI,cAAc;AAAA,EACpB;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 { 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":[]}
@@ -41,7 +41,7 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer)
41
41
  },
42
42
  apiClient: backendClient
43
43
  };
44
- const COOKIE_OPTIONS = (0, import_cookieOptionsHelper.getCookieOptions)(config);
44
+ const COOKIE_OPTIONS = (0, import_cookieOptionsHelper.getIdTokenCookieOptions)();
45
45
  const { createCustomIdAndRefreshToken } = (0, import_auth.getAuth)(authOptions);
46
46
  const customTokens = await createCustomIdAndRefreshToken(idToken, { referer: referrer });
47
47
  const cookiePrefix = (0, import_cookie.getCookiePrefix)();
@@ -55,6 +55,11 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer)
55
55
  (0, import_cookie.getCookieName)(import_backend.constants.Cookies.Refresh, cookiePrefix),
56
56
  customTokens.refreshToken,
57
57
  COOKIE_OPTIONS
58
+ ),
59
+ cookieStore.set(
60
+ import_backend.constants.Cookies.TernAut,
61
+ customTokens.auth_time.toString(),
62
+ { secure: true, maxAge: 365 * 24 * 60 * 60 }
58
63
  )
59
64
  ];
60
65
  if (config?.enableCustomToken) {
@@ -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 { getCookieOptions } 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 = getCookieOptions(config);\n\n const { createCustomIdAndRefreshToken } = getAuth(authOptions);\n\n const customTokens = await createCustomIdAndRefreshToken(idToken, { referer: referrer });\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\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,iCAAiC;AAGjC,eAAsB,yBACpB,SACA,aACA,QACA,UACe;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,6CAAiB,MAAM;AAE9C,QAAM,EAAE,8BAA8B,QAAI,qBAAQ,WAAW;AAE7D,QAAM,eAAe,MAAM,8BAA8B,SAAS,EAAE,SAAS,SAAS,CAAC;AAEvF,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,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 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, { referer: referrer });\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,UACe;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;AAE7D,QAAM,eAAe,MAAM,8BAA8B,SAAS,EAAE,SAAS,SAAS,CAAC;AAEvF,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,16 +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);
26
+ var import_backend = require("@tern-secure/backend");
25
27
  var import_admin = require("@tern-secure/backend/admin");
26
28
  var import_jwt = require("@tern-secure/backend/jwt");
29
+ var import_ternsecureClient = require("../../server/ternsecureClient");
27
30
  var import_NextCookieAdapter = require("../../utils/NextCookieAdapter");
31
+ var import_constants = require("./constants");
28
32
  var import_fnValidators = require("./fnValidators");
29
33
  var import_request = require("./request");
30
34
  var import_responses = require("./responses");
31
- async function sessionEndpointHandler(context, config) {
35
+ var import_signInCreateHandler = require("./signInCreateHandler");
36
+ const sessionEndpointHandler = async (context, config) => {
32
37
  const { subEndpoint, method, referrer } = context;
33
38
  const validators = (0, import_fnValidators.createValidators)(context);
34
39
  const {
@@ -74,7 +79,7 @@ async function sessionEndpointHandler(context, config) {
74
79
  const cookieStore = new import_NextCookieAdapter.NextCookieStore();
75
80
  const { idToken, csrfToken, error } = await validateSessionRequest();
76
81
  if (error) return error;
77
- const csrfCookieValue = await cookieStore.get("_session_terncf");
82
+ const csrfCookieValue = await cookieStore.get(import_backend.constants.Cookies.CsrfToken);
78
83
  validateCsrfToken(csrfToken || "", csrfCookieValue.value);
79
84
  const handleCreateSession = async (cookieStore2, idToken2) => {
80
85
  try {
@@ -124,8 +129,8 @@ async function sessionEndpointHandler(context, config) {
124
129
  default:
125
130
  return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
126
131
  }
127
- }
128
- async function cookieEndpointHandler(context, config) {
132
+ };
133
+ const cookieEndpointHandler = async (context, config) => {
129
134
  const { subEndpoint, method } = context;
130
135
  const validators = (0, import_fnValidators.createValidators)(context);
131
136
  const { validateSecurity } = validators;
@@ -192,10 +197,77 @@ async function cookieEndpointHandler(context, config) {
192
197
  default:
193
198
  return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
194
199
  }
195
- }
200
+ };
201
+ const signInEndpointHandler = async (context, config) => {
202
+ const { subEndpoint, method } = context;
203
+ const validators = (0, import_fnValidators.createValidators)(context);
204
+ const {
205
+ validateSubEndpoint,
206
+ validateSecurity
207
+ } = validators;
208
+ if (!subEndpoint) {
209
+ return (0, import_responses.createApiErrorResponse)("SUB_ENDPOINT_REQUIRED", "Sign_ins sub-endpoint required", 400);
210
+ }
211
+ const signInsConfig = config.endpoints?.signIns;
212
+ const subEndpointConfig = signInsConfig?.subEndpoints?.[subEndpoint];
213
+ validateSubEndpoint(subEndpoint, subEndpointConfig);
214
+ if (subEndpointConfig?.security) {
215
+ await validateSecurity(subEndpointConfig.security);
216
+ }
217
+ const PostHandler = async (subEndpoint2) => {
218
+ const create = async () => {
219
+ return await (0, import_signInCreateHandler.processSignInCreate)(context);
220
+ };
221
+ const passwordResetEmail = async () => {
222
+ try {
223
+ const body = await context.request.json();
224
+ const { email } = body;
225
+ if (!email || typeof email !== "string") {
226
+ return (0, import_responses.createApiErrorResponse)("EMAIL_REQUIRED", "Email is required", 400);
227
+ }
228
+ const backendClient = await (0, import_ternsecureClient.ternSecureBackendClient)();
229
+ const response = await backendClient.signIn.resetPasswordEmail(import_constants.FIREBASE_API_KEY, {
230
+ email,
231
+ requestType: "PASSWORD_RESET"
232
+ });
233
+ if (!response) {
234
+ return (0, import_responses.createApiErrorResponse)(
235
+ "PASSWORD_RESET_FAILED",
236
+ "Failed to send password reset email",
237
+ 500
238
+ );
239
+ }
240
+ return (0, import_responses.createApiSuccessResponse)({
241
+ email
242
+ });
243
+ } catch (error) {
244
+ return (0, import_responses.createApiErrorResponse)(
245
+ "PASSWORD_RESET_ERROR",
246
+ error instanceof Error ? error.message : "An error occurred while sending password reset email",
247
+ 500
248
+ );
249
+ }
250
+ };
251
+ switch (subEndpoint2) {
252
+ case "create":
253
+ return create();
254
+ case "resetPasswordEmail":
255
+ return passwordResetEmail();
256
+ default:
257
+ return import_responses.HttpResponseHelper.createSubEndpointNotSupportedResponse();
258
+ }
259
+ };
260
+ switch (method) {
261
+ case "POST":
262
+ return PostHandler(subEndpoint);
263
+ default:
264
+ return import_responses.HttpResponseHelper.createMethodNotAllowedResponse();
265
+ }
266
+ };
196
267
  // Annotate the CommonJS export names for ESM import in node:
197
268
  0 && (module.exports = {
198
269
  cookieEndpointHandler,
199
- sessionEndpointHandler
270
+ sessionEndpointHandler,
271
+ signInEndpointHandler
200
272
  });
201
273
  //# sourceMappingURL=sessionHandlers.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import { 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('_session_terncf');\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);\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\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"]}
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var signInCreateHandler_exports = {};
20
+ __export(signInCreateHandler_exports, {
21
+ processEmailCodeStrategy: () => processEmailCodeStrategy,
22
+ processPasswordStrategy: () => processPasswordStrategy,
23
+ processPhoneCodeStrategy: () => processPhoneCodeStrategy,
24
+ processResetPasswordStrategy: () => processResetPasswordStrategy,
25
+ processSignInCreate: () => processSignInCreate
26
+ });
27
+ module.exports = __toCommonJS(signInCreateHandler_exports);
28
+ var import_actions = require("./actions");
29
+ var import_responses = require("./responses");
30
+ const processSignInCreate = async (context) => {
31
+ try {
32
+ const body = await context.request.json();
33
+ const { strategy, identifier } = body;
34
+ if (!strategy) {
35
+ return (0, import_responses.createApiErrorResponse)(
36
+ "STRATEGY_REQUIRED",
37
+ "Authentication strategy is required",
38
+ 400
39
+ );
40
+ }
41
+ if (!identifier) {
42
+ return (0, import_responses.createApiSuccessResponse)({
43
+ status: "needs_identifier",
44
+ strategy,
45
+ message: "Identifier is required to continue"
46
+ });
47
+ }
48
+ if (strategy === "email_code") {
49
+ return await processEmailCodeStrategy(identifier);
50
+ }
51
+ if (strategy === "password") {
52
+ return await processPasswordStrategy(identifier);
53
+ }
54
+ if (strategy === "phone_code") {
55
+ return processPhoneCodeStrategy(identifier);
56
+ }
57
+ if (strategy === "reset_password_email_code" || strategy === "reset_password_phone_code") {
58
+ return await processResetPasswordStrategy(strategy, identifier);
59
+ }
60
+ return (0, import_responses.createApiErrorResponse)(
61
+ "INVALID_STRATEGY",
62
+ `Unsupported authentication strategy: ${strategy}`,
63
+ 400
64
+ );
65
+ } catch (error) {
66
+ return (0, import_responses.createApiErrorResponse)(
67
+ "SIGN_IN_CREATE_ERROR",
68
+ error instanceof Error ? error.message : "An error occurred while creating sign-in",
69
+ 500
70
+ );
71
+ }
72
+ };
73
+ const processEmailCodeStrategy = async (email) => {
74
+ try {
75
+ const retrieveUser = (0, import_actions.RetrieveUser)();
76
+ const { data: user, error } = await retrieveUser.getUserByEmail(email);
77
+ if (error) {
78
+ return (0, import_responses.createApiErrorResponse)(
79
+ error.code,
80
+ error.message,
81
+ 400
82
+ );
83
+ }
84
+ if (!user.emailVerified) {
85
+ return (0, import_responses.createApiSuccessResponse)({
86
+ status: "needs_email_verification",
87
+ identifier: email,
88
+ supportedFirstFactors: [{ strategy: "email_code" }],
89
+ userId: user.uid,
90
+ message: "Email verification required"
91
+ });
92
+ }
93
+ return (0, import_responses.createApiSuccessResponse)({
94
+ status: "needs_first_factor",
95
+ identifier: email,
96
+ supportedFirstFactors: [{ strategy: "email_code" }],
97
+ userId: user.uid,
98
+ message: "User verified. Proceed with first factor authentication"
99
+ });
100
+ } catch (error) {
101
+ if (error instanceof Error && error.message.includes("no user record")) {
102
+ return (0, import_responses.createApiErrorResponse)(
103
+ "USER_NOT_FOUND",
104
+ "No user found with this email address",
105
+ 404
106
+ );
107
+ }
108
+ return (0, import_responses.createApiErrorResponse)(
109
+ "EMAIL_VERIFICATION_ERROR",
110
+ error instanceof Error ? error.message : "Failed to verify email",
111
+ 500
112
+ );
113
+ }
114
+ };
115
+ const processPasswordStrategy = async (identifier) => {
116
+ try {
117
+ const retrieveUser = (0, import_actions.RetrieveUser)();
118
+ const { data: user, error } = await retrieveUser.getUserByEmail(identifier);
119
+ if (error) {
120
+ return (0, import_responses.createApiErrorResponse)(
121
+ error.code,
122
+ error.message,
123
+ 400
124
+ );
125
+ }
126
+ return (0, import_responses.createApiSuccessResponse)({
127
+ status: "needs_first_factor",
128
+ identifier,
129
+ supportedFirstFactors: [{ strategy: "password" }],
130
+ userId: user.uid,
131
+ message: "User verified. Proceed with password authentication"
132
+ });
133
+ } catch (error) {
134
+ if (error instanceof Error && error.message.includes("no user record")) {
135
+ return (0, import_responses.createApiErrorResponse)(
136
+ "USER_NOT_FOUND",
137
+ "No user found with this identifier",
138
+ 404
139
+ );
140
+ }
141
+ return (0, import_responses.createApiErrorResponse)(
142
+ "USER_VERIFICATION_ERROR",
143
+ error instanceof Error ? error.message : "Failed to verify user",
144
+ 500
145
+ );
146
+ }
147
+ };
148
+ const processPhoneCodeStrategy = async (phoneNumber) => {
149
+ try {
150
+ return (0, import_responses.createApiSuccessResponse)({
151
+ status: "needs_first_factor",
152
+ identifier: phoneNumber,
153
+ supportedFirstFactors: [{ strategy: "phone_code" }],
154
+ //userId: user.uid,
155
+ message: "User verified. Proceed with phone authentication"
156
+ });
157
+ } catch (error) {
158
+ if (error instanceof Error && error.message.includes("no user record")) {
159
+ return (0, import_responses.createApiErrorResponse)(
160
+ "USER_NOT_FOUND",
161
+ "No user found with this phone number",
162
+ 404
163
+ );
164
+ }
165
+ return (0, import_responses.createApiErrorResponse)(
166
+ "PHONE_VERIFICATION_ERROR",
167
+ error instanceof Error ? error.message : "Failed to verify phone number",
168
+ 500
169
+ );
170
+ }
171
+ };
172
+ const processResetPasswordStrategy = async (strategy, identifier) => {
173
+ try {
174
+ if (strategy === "reset_password_email_code") {
175
+ const retrieveUser = (0, import_actions.RetrieveUser)();
176
+ const { data: user, error } = await retrieveUser.getUserByEmail(identifier);
177
+ if (error) {
178
+ return (0, import_responses.createApiErrorResponse)(
179
+ error.code,
180
+ error.message,
181
+ 400
182
+ );
183
+ }
184
+ return (0, import_responses.createApiSuccessResponse)({
185
+ status: "needs_first_factor",
186
+ identifier,
187
+ strategy,
188
+ userId: user.uid,
189
+ message: "User verified. Proceed with password reset"
190
+ });
191
+ }
192
+ return (0, import_responses.createApiErrorResponse)(
193
+ "NOT_IMPLEMENTED",
194
+ "Phone reset password strategy not yet implemented",
195
+ 501
196
+ );
197
+ } catch (error) {
198
+ return (0, import_responses.createApiErrorResponse)(
199
+ "RESET_PASSWORD_ERROR",
200
+ error instanceof Error ? error.message : "Failed to process password reset",
201
+ 500
202
+ );
203
+ }
204
+ };
205
+ // Annotate the CommonJS export names for ESM import in node:
206
+ 0 && (module.exports = {
207
+ processEmailCodeStrategy,
208
+ processPasswordStrategy,
209
+ processPhoneCodeStrategy,
210
+ processResetPasswordStrategy,
211
+ processSignInCreate
212
+ });
213
+ //# sourceMappingURL=signInCreateHandler.js.map
@@ -0,0 +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":[]}