@tern-secure/nextjs 5.2.0-canary.v20251108045933 → 5.2.0-canary.v20251127221555

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) 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/c-authenticateRequestProcessor.js +1 -0
  4. package/dist/cjs/app-router/admin/c-authenticateRequestProcessor.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/fnValidators.js +7 -0
  8. package/dist/cjs/app-router/admin/fnValidators.js.map +1 -1
  9. package/dist/cjs/app-router/admin/request.js +5 -2
  10. package/dist/cjs/app-router/admin/request.js.map +1 -1
  11. package/dist/cjs/app-router/admin/sessionHandlers.js +92 -11
  12. package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
  13. package/dist/cjs/app-router/admin/signInCreateHandler.js +213 -0
  14. package/dist/cjs/app-router/admin/signInCreateHandler.js.map +1 -0
  15. package/dist/cjs/app-router/admin/types.js +14 -1
  16. package/dist/cjs/app-router/admin/types.js.map +1 -1
  17. package/dist/cjs/app-router/client/TernSecureProvider.js +5 -1
  18. package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
  19. package/dist/cjs/boundary/components.js +2 -12
  20. package/dist/cjs/boundary/components.js.map +1 -1
  21. package/dist/cjs/components/uiComponents.js +42 -0
  22. package/dist/cjs/components/uiComponents.js.map +1 -0
  23. package/dist/cjs/index.js +9 -12
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/cjs/server/data/getAuthDataFromRequest.js +8 -2
  26. package/dist/cjs/server/data/getAuthDataFromRequest.js.map +1 -1
  27. package/dist/cjs/server/index.js.map +1 -1
  28. package/dist/cjs/server/ternSecureProxy.js +27 -3
  29. package/dist/cjs/server/ternSecureProxy.js.map +1 -1
  30. package/dist/cjs/server/utils.js +3 -2
  31. package/dist/cjs/server/utils.js.map +1 -1
  32. package/dist/cjs/utils/allNextProviderProps.js +16 -3
  33. package/dist/cjs/utils/allNextProviderProps.js.map +1 -1
  34. package/dist/cjs/utils/tern-ui-script.js +72 -0
  35. package/dist/cjs/utils/tern-ui-script.js.map +1 -0
  36. package/dist/esm/app-router/admin/actions.js +5 -0
  37. package/dist/esm/app-router/admin/actions.js.map +1 -1
  38. package/dist/esm/app-router/admin/c-authenticateRequestProcessor.js +1 -0
  39. package/dist/esm/app-router/admin/c-authenticateRequestProcessor.js.map +1 -1
  40. package/dist/esm/app-router/admin/endpointRouter.js +11 -2
  41. package/dist/esm/app-router/admin/endpointRouter.js.map +1 -1
  42. package/dist/esm/app-router/admin/fnValidators.js +7 -0
  43. package/dist/esm/app-router/admin/fnValidators.js.map +1 -1
  44. package/dist/esm/app-router/admin/request.js +5 -2
  45. package/dist/esm/app-router/admin/request.js.map +1 -1
  46. package/dist/esm/app-router/admin/sessionHandlers.js +96 -11
  47. package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
  48. package/dist/esm/app-router/admin/signInCreateHandler.js +188 -0
  49. package/dist/esm/app-router/admin/signInCreateHandler.js.map +1 -0
  50. package/dist/esm/app-router/admin/types.js +13 -1
  51. package/dist/esm/app-router/admin/types.js.map +1 -1
  52. package/dist/esm/app-router/client/TernSecureProvider.js +6 -2
  53. package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
  54. package/dist/esm/boundary/components.js +1 -11
  55. package/dist/esm/boundary/components.js.map +1 -1
  56. package/dist/esm/components/uiComponents.js +21 -0
  57. package/dist/esm/components/uiComponents.js.map +1 -0
  58. package/dist/esm/index.js +10 -12
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/server/data/getAuthDataFromRequest.js +9 -3
  61. package/dist/esm/server/data/getAuthDataFromRequest.js.map +1 -1
  62. package/dist/esm/server/index.js +1 -3
  63. package/dist/esm/server/index.js.map +1 -1
  64. package/dist/esm/server/ternSecureProxy.js +28 -4
  65. package/dist/esm/server/ternSecureProxy.js.map +1 -1
  66. package/dist/esm/server/utils.js +3 -2
  67. package/dist/esm/server/utils.js.map +1 -1
  68. package/dist/esm/utils/allNextProviderProps.js +16 -3
  69. package/dist/esm/utils/allNextProviderProps.js.map +1 -1
  70. package/dist/esm/utils/tern-ui-script.js +38 -0
  71. package/dist/esm/utils/tern-ui-script.js.map +1 -0
  72. package/dist/types/app-router/admin/actions.d.ts +23 -0
  73. package/dist/types/app-router/admin/actions.d.ts.map +1 -1
  74. package/dist/types/app-router/admin/c-authenticateRequestProcessor.d.ts +1 -0
  75. package/dist/types/app-router/admin/c-authenticateRequestProcessor.d.ts.map +1 -1
  76. package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -1
  77. package/dist/types/app-router/admin/fnValidators.d.ts.map +1 -1
  78. package/dist/types/app-router/admin/request.d.ts +1 -1
  79. package/dist/types/app-router/admin/request.d.ts.map +1 -1
  80. package/dist/types/app-router/admin/sessionHandlers.d.ts +4 -3
  81. package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
  82. package/dist/types/app-router/admin/signInCreateHandler.d.ts +11 -0
  83. package/dist/types/app-router/admin/signInCreateHandler.d.ts.map +1 -0
  84. package/dist/types/app-router/admin/types.d.ts +3 -2
  85. package/dist/types/app-router/admin/types.d.ts.map +1 -1
  86. package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
  87. package/dist/types/boundary/components.d.ts +1 -1
  88. package/dist/types/boundary/components.d.ts.map +1 -1
  89. package/dist/types/components/uiComponents.d.ts +6 -0
  90. package/dist/types/components/uiComponents.d.ts.map +1 -0
  91. package/dist/types/index.d.ts +2 -1
  92. package/dist/types/index.d.ts.map +1 -1
  93. package/dist/types/server/data/getAuthDataFromRequest.d.ts.map +1 -1
  94. package/dist/types/server/index.d.ts +1 -1
  95. package/dist/types/server/index.d.ts.map +1 -1
  96. package/dist/types/server/ternSecureProxy.d.ts.map +1 -1
  97. package/dist/types/server/utils.d.ts +1 -1
  98. package/dist/types/server/utils.d.ts.map +1 -1
  99. package/dist/types/utils/allNextProviderProps.d.ts.map +1 -1
  100. package/dist/types/utils/tern-ui-script.d.ts +8 -0
  101. package/dist/types/utils/tern-ui-script.d.ts.map +1 -0
  102. package/package.json +5 -5
@@ -1,8 +1,9 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { TernSecureProvider as TernSecureReactProvider } from "@tern-secure/react";
4
4
  import { TernNextOptionsProvider, useTernNextOptions } from "../../boundary/NextOptionsCtx";
5
5
  import { allNextProviderPropsWithEnv } from "../../utils/allNextProviderProps";
6
+ import { TernUIScript } from "../../utils/tern-ui-script";
6
7
  import { useAwaitablePush } from "./useAwaitablePush";
7
8
  import { useAwaitableReplace } from "./useAwaitableReplace";
8
9
  const NextClientProvider = (props) => {
@@ -20,7 +21,10 @@ const NextClientProvider = (props) => {
20
21
  // @ts-expect-error Error because of the stricter types of internal `replace`
21
22
  routerReplace: replace
22
23
  });
23
- return /* @__PURE__ */ jsx(TernNextOptionsProvider, { options: providerProps, children: /* @__PURE__ */ jsx(TernSecureReactProvider, { ...providerProps, children }) });
24
+ return /* @__PURE__ */ jsx(TernNextOptionsProvider, { options: providerProps, children: /* @__PURE__ */ jsxs(TernSecureReactProvider, { ...providerProps, children: [
25
+ children,
26
+ /* @__PURE__ */ jsx(TernUIScript, { router: "app" })
27
+ ] }) });
24
28
  };
25
29
  const ClientTernSecureProvider = (props) => {
26
30
  const { children, ...rest } = props;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { TernSecureProvider as TernSecureReactProvider } from '@tern-secure/react';\r\n\r\nimport { TernNextOptionsProvider, useTernNextOptions } from '../../boundary/NextOptionsCtx';\r\nimport type { TernSecureNextProps } from '../../types';\r\nimport { allNextProviderPropsWithEnv } from '../../utils/allNextProviderProps';\r\nimport { useAwaitablePush } from './useAwaitablePush';\r\nimport { useAwaitableReplace } from './useAwaitableReplace';\r\n\r\nconst NextClientProvider = (props: TernSecureNextProps) => {\r\n const { children } = props;\r\n\r\n const push = useAwaitablePush();\r\n const replace = useAwaitableReplace();\r\n\r\n const isNested = Boolean(useTernNextOptions());\r\n if (isNested) {\r\n return props.children;\r\n }\r\n\r\n const providerProps = allNextProviderPropsWithEnv({\r\n ...props,\r\n // @ts-expect-error Error because of the stricter types of internal `push`\r\n routerPush: push,\r\n // @ts-expect-error Error because of the stricter types of internal `replace`\r\n routerReplace: replace,\r\n });\r\n return (\r\n <TernNextOptionsProvider options={providerProps}>\r\n <TernSecureReactProvider {...providerProps}>{children}</TernSecureReactProvider>\r\n </TernNextOptionsProvider>\r\n );\r\n};\r\n\r\nexport const ClientTernSecureProvider = (props: TernSecureNextProps) => {\r\n const { children, ...rest } = props;\r\n return <NextClientProvider {...rest}>{children}</NextClientProvider>;\r\n};\r\n"],"mappings":";AA8BM;AA5BN,SAAS,sBAAsB,+BAA+B;AAE9D,SAAS,yBAAyB,0BAA0B;AAE5D,SAAS,mCAAmC;AAC5C,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AAEpC,MAAM,qBAAqB,CAAC,UAA+B;AACzD,QAAM,EAAE,SAAS,IAAI;AAErB,QAAM,OAAO,iBAAiB;AAC9B,QAAM,UAAU,oBAAoB;AAEpC,QAAM,WAAW,QAAQ,mBAAmB,CAAC;AAC7C,MAAI,UAAU;AACZ,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,GAAG;AAAA;AAAA,IAEH,YAAY;AAAA;AAAA,IAEZ,eAAe;AAAA,EACjB,CAAC;AACD,SACE,oBAAC,2BAAwB,SAAS,eAChC,8BAAC,2BAAyB,GAAG,eAAgB,UAAS,GACxD;AAEJ;AAEO,MAAM,2BAA2B,CAAC,UAA+B;AACtE,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,SAAO,oBAAC,sBAAoB,GAAG,MAAO,UAAS;AACjD;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { TernSecureProvider as TernSecureReactProvider } from '@tern-secure/react';\r\n\r\nimport { TernNextOptionsProvider, useTernNextOptions } from '../../boundary/NextOptionsCtx';\r\nimport type { TernSecureNextProps } from '../../types';\r\nimport { allNextProviderPropsWithEnv } from '../../utils/allNextProviderProps';\r\nimport { TernUIScript } from '../../utils/tern-ui-script';\r\nimport { useAwaitablePush } from './useAwaitablePush';\r\nimport { useAwaitableReplace } from './useAwaitableReplace';\r\n\r\nconst NextClientProvider = (props: TernSecureNextProps) => {\r\n const { children } = props;\r\n\r\n const push = useAwaitablePush();\r\n const replace = useAwaitableReplace();\r\n\r\n const isNested = Boolean(useTernNextOptions());\r\n if (isNested) {\r\n return props.children;\r\n }\r\n\r\n const providerProps = allNextProviderPropsWithEnv({\r\n ...props,\r\n // @ts-expect-error Error because of the stricter types of internal `push`\r\n routerPush: push,\r\n // @ts-expect-error Error because of the stricter types of internal `replace`\r\n routerReplace: replace,\r\n });\r\n return (\r\n <TernNextOptionsProvider options={providerProps}>\r\n <TernSecureReactProvider {...providerProps}>\r\n {children}\r\n <TernUIScript router=\"app\" />\r\n </TernSecureReactProvider>\r\n </TernNextOptionsProvider>\r\n );\r\n};\r\n\r\nexport const ClientTernSecureProvider = (props: TernSecureNextProps) => {\r\n const { children, ...rest } = props;\r\n return <NextClientProvider {...rest}>{children}</NextClientProvider>;\r\n};\r\n"],"mappings":";AA+BM,SAEE,KAFF;AA7BN,SAAS,sBAAsB,+BAA+B;AAE9D,SAAS,yBAAyB,0BAA0B;AAE5D,SAAS,mCAAmC;AAC5C,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AAEpC,MAAM,qBAAqB,CAAC,UAA+B;AACzD,QAAM,EAAE,SAAS,IAAI;AAErB,QAAM,OAAO,iBAAiB;AAC9B,QAAM,UAAU,oBAAoB;AAEpC,QAAM,WAAW,QAAQ,mBAAmB,CAAC;AAC7C,MAAI,UAAU;AACZ,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,GAAG;AAAA;AAAA,IAEH,YAAY;AAAA;AAAA,IAEZ,eAAe;AAAA,EACjB,CAAC;AACD,SACE,oBAAC,2BAAwB,SAAS,eAChC,+BAAC,2BAAyB,GAAG,eAC1B;AAAA;AAAA,IACD,oBAAC,gBAAa,QAAO,OAAM;AAAA,KAC7B,GACF;AAEJ;AAEO,MAAM,2BAA2B,CAAC,UAA+B;AACtE,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,SAAO,oBAAC,sBAAoB,GAAG,MAAO,UAAS;AACjD;","names":[]}
@@ -3,25 +3,15 @@ import {
3
3
  useSession,
4
4
  useSignIn,
5
5
  useSignUp,
6
- useSignInContext,
7
- useSignUpContext,
8
- useTernSecure,
9
- SignInProvider,
10
- SignUpProvider,
11
6
  signIn
12
7
  } from "@tern-secure/react";
13
8
  import { usePromiseAuth } from "./PromiseAuthProvider";
14
9
  export {
15
- SignInProvider,
16
- SignUpProvider,
17
10
  signIn,
18
11
  usePromiseAuth as useAuth,
19
12
  useIdToken,
20
13
  useSession,
21
14
  useSignIn,
22
- useSignInContext,
23
- useSignUp,
24
- useSignUpContext,
25
- useTernSecure
15
+ useSignUp
26
16
  };
27
17
  //# sourceMappingURL=components.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/boundary/components.ts"],"sourcesContent":["export { \n useIdToken,\n useSession,\n useSignIn,\n useSignUp,\n useSignInContext,\n useSignUpContext,\n useTernSecure,\n SignInProvider,\n SignUpProvider,\n signIn,\n} from '@tern-secure/react';\n\nexport { usePromiseAuth as useAuth } from './PromiseAuthProvider';"],"mappings":"AAAA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,SAA2B,sBAAe;","names":[]}
1
+ {"version":3,"sources":["../../../src/boundary/components.ts"],"sourcesContent":["export { \n useIdToken,\n useSession,\n useSignIn,\n useSignUp,\n signIn,\n} from '@tern-secure/react';\n\nexport { usePromiseAuth as useAuth } from './PromiseAuthProvider';"],"mappings":"AAAA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAEP,SAA2B,sBAAe;","names":[]}
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import {
4
+ SignIn as BaseSignIn,
5
+ SignUp as BaseSignUp
6
+ } from "@tern-secure/react";
7
+ import {
8
+ UserButton
9
+ } from "@tern-secure/react";
10
+ const SignIn = (props) => {
11
+ return /* @__PURE__ */ jsx(BaseSignIn, { ...props });
12
+ };
13
+ const SignUp = (props) => {
14
+ return /* @__PURE__ */ jsx(BaseSignUp, { ...props });
15
+ };
16
+ export {
17
+ SignIn,
18
+ SignUp,
19
+ UserButton
20
+ };
21
+ //# sourceMappingURL=uiComponents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/uiComponents.tsx"],"sourcesContent":["'use client'\n\nimport { \n SignIn as BaseSignIn,\n SignUp as BaseSignUp,\n} from '@tern-secure/react'\nimport type { ComponentProps } from 'react';\n\nexport {\n UserButton\n} from '@tern-secure/react';\n\nexport const SignIn = (props: ComponentProps<typeof BaseSignIn>) => {\n return <BaseSignIn {...props} />;\n};\n\nexport const SignUp = (props: ComponentProps<typeof BaseSignUp>) => {\n return <BaseSignUp {...props} />; \n};"],"mappings":";AAaS;AAXT;AAAA,EACI,UAAU;AAAA,EACV,UAAU;AAAA,OACP;AAGP;AAAA,EACE;AAAA,OACK;AAEA,MAAM,SAAS,CAAC,UAA6C;AAClE,SAAO,oBAAC,cAAY,GAAG,OAAO;AAChC;AAEO,MAAM,SAAS,CAAC,UAA6C;AAClE,SAAO,oBAAC,cAAY,GAAG,OAAO;AAChC;","names":[]}
package/dist/esm/index.js CHANGED
@@ -5,25 +5,23 @@ import {
5
5
  useSession,
6
6
  useSignIn,
7
7
  useSignUp,
8
- signIn,
9
- useSignInContext,
10
- useSignUpContext,
11
- useTernSecure,
12
- SignInProvider,
13
- SignUpProvider
8
+ signIn
14
9
  } from "./boundary/components";
10
+ import {
11
+ SignIn,
12
+ SignUp,
13
+ UserButton
14
+ } from "./components/uiComponents";
15
15
  export {
16
- SignInProvider,
17
- SignUpProvider,
16
+ SignIn,
17
+ SignUp,
18
18
  TernSecureProvider,
19
+ UserButton,
19
20
  signIn,
20
21
  useAuth,
21
22
  useIdToken,
22
23
  useSession,
23
24
  useSignIn,
24
- useSignInContext,
25
- useSignUp,
26
- useSignUpContext,
27
- useTernSecure
25
+ useSignUp
28
26
  };
29
27
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureProvider } from './app-router/server/TernSecureProvider';\r\nexport {\r\n useAuth,\r\n useIdToken,\r\n useSession,\r\n useSignIn,\r\n useSignUp,\r\n signIn,\r\n useSignInContext,\r\n useSignUpContext,\r\n useTernSecure,\r\n SignInProvider,\r\n SignUpProvider,\r\n} from './boundary/components';\r\n\r\nexport type {\r\n TernSecureUser,\r\n SignInResponse,\r\n SignUpResponse,\r\n SocialProviderOptions,\r\n} from '@tern-secure/types';\r\n\r\nexport type { UserInfo, SessionResult } from './types';\r\n"],"mappings":"AAAA,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export { TernSecureProvider } from './app-router/server/TernSecureProvider';\r\nexport {\r\n useAuth,\r\n useIdToken,\r\n useSession,\r\n useSignIn,\r\n useSignUp,\r\n signIn,\r\n} from './boundary/components';\r\n\r\nexport {\r\n SignIn,\r\n SignUp,\r\n UserButton,\r\n} from './components/uiComponents'\r\n\r\nexport type {\r\n TernSecureUser,\r\n SignInResponse,\r\n SignUpResponse,\r\n SocialProviderOptions,\r\n} from '@tern-secure/types';\r\n\r\nexport type { UserInfo, SessionResult } from './types';\r\n"],"mappings":"AAAA,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
@@ -2,7 +2,7 @@ import { AuthStatus, signedInAuthObject, signedOutAuthObject } from "@tern-secur
2
2
  import { ternDecodeJwt } from "@tern-secure/backend/jwt";
3
3
  import { initializeServerApp } from "firebase/app";
4
4
  import { getAuth } from "firebase/auth";
5
- import { getAuthKeyFromRequest } from "../../server/headers-utils";
5
+ import { getAuthKeyFromRequest, getHeader } from "../../server/headers-utils";
6
6
  import {
7
7
  FIREBASE_API_KEY,
8
8
  FIREBASE_APP_ID,
@@ -45,6 +45,7 @@ async function getTernSecureAuthData(req, initialState = {}) {
45
45
  async function getAuthDataFromRequest(req) {
46
46
  const authStatus = getAuthKeyFromRequest(req, "AuthStatus");
47
47
  const authToken = getAuthKeyFromRequest(req, "AuthToken");
48
+ const appCheckToken = getHeader(req, "X-Firebase-AppCheck");
48
49
  if (!authStatus || authStatus !== AuthStatus.SignedIn) {
49
50
  return {
50
51
  ...signedOutAuthObject(),
@@ -52,7 +53,11 @@ async function getAuthDataFromRequest(req) {
52
53
  userId: null
53
54
  };
54
55
  }
55
- const firebaseUser = await authenticateRequest(authToken, req);
56
+ const firebaseUser = await authenticateRequest(
57
+ authToken,
58
+ req,
59
+ appCheckToken
60
+ );
56
61
  if (!firebaseUser || !firebaseUser.claims) {
57
62
  return {
58
63
  ...signedOutAuthObject(),
@@ -67,7 +72,7 @@ async function getAuthDataFromRequest(req) {
67
72
  user: user || null
68
73
  };
69
74
  }
70
- const authenticateRequest = async (token, request) => {
75
+ const authenticateRequest = async (token, request, appCheckToken) => {
71
76
  try {
72
77
  const origin = new URL(request.url).origin;
73
78
  const requestHeaders = new Headers(request.headers);
@@ -89,6 +94,7 @@ const authenticateRequest = async (token, request) => {
89
94
  config,
90
95
  {
91
96
  authIdToken: token,
97
+ appCheckToken,
92
98
  releaseOnDeref: mockRequest
93
99
  }
94
100
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/server/data/getAuthDataFromRequest.ts"],"sourcesContent":["import type { AuthObject } from '@tern-secure/backend';\nimport { AuthStatus, signedInAuthObject, signedOutAuthObject } from '@tern-secure/backend';\nimport { ternDecodeJwt } from '@tern-secure/backend/jwt';\nimport type { ParsedToken, TernSecureConfig, TernSecureUser } from '@tern-secure/types';\nimport type { FirebaseServerApp } from \"firebase/app\";\nimport { initializeServerApp } from \"firebase/app\";\nimport type { Auth } from \"firebase/auth\";\nimport { getAuth } from \"firebase/auth\";\n\nimport { getAuthKeyFromRequest } from '../../server/headers-utils';\nimport type { RequestLike } from '../../server/types';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MEASUREMENT_ID,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET\n} from \"../constant\";\n\n\n/**\n * Auth objects moving through the server -> client boundary need to be serializable\n * as we need to ensure that they can be transferred via the network as pure strings.\n * Some frameworks like Remix or Next (/pages dir only) handle this serialization by simply\n * ignoring any non-serializable keys, however Nextjs /app directory is stricter and\n * throws an error if a non-serializable value is found.\n * @internal\n */\nexport const authObjectToSerializableJwt = <T extends Record<string, unknown>>(obj: T): T => {\n // remove any non-serializable props from the returned object\n\n const { require, ...rest } = obj as unknown as AuthObject;\n return rest as unknown as T;\n};\n\nexport function getTernSecureAuthDataJwt(req: RequestLike, initialState = {}) {\n const authObject = getAuthDataFromRequestJwt(req);\n return authObjectToSerializable({ ...initialState, ...authObject });\n}\n\nexport function getAuthDataFromRequestJwt(req: RequestLike): AuthObject {\n const authStatus = getAuthKeyFromRequest(req, 'AuthStatus');\n const authToken = getAuthKeyFromRequest(req, 'AuthToken');\n const authSignature = getAuthKeyFromRequest(req, 'AuthSignature');\n const authReason = getAuthKeyFromRequest(req, 'AuthReason');\n\n let authObject;\n if (!authStatus || authStatus !== AuthStatus.SignedIn) {\n authObject = signedOutAuthObject();\n } else {\n const jwt = ternDecodeJwt(authToken as string);\n\n authObject = signedInAuthObject(jwt.raw.text, jwt.payload);\n }\n return authObject;\n}\n\n\nexport type SerializableTernSecureUser = Omit<TernSecureUser, 'delete' | 'getIdToken' | 'getIdTokenResult' | 'reload' | 'toJSON'>;\n\nexport type Aobj = {\n user: SerializableTernSecureUser | null\n userId: string | null\n}\n\n\n// Serializable auth object type\n/**\n * Auth objects moving through the server -> client boundary need to be serializable\n * as we need to ensure that they can be transferred via the network as pure strings.\n * Some frameworks like Remix or Next (/pages dir only) handle this serialization by simply\n * ignoring any non-serializable keys, however Nextjs /app directory is stricter and\n * throws an error if a non-serializable value is found.\n * @internal\n */\nexport const authObjectToSerializable = <T extends Record<string, unknown>>(\n obj: T\n): T => {\n // remove any non-serializable props from the returned object\n\n const { require, ...rest } = obj as unknown as AuthObject;\n return rest as unknown as T;\n};\n\nexport async function getTernSecureAuthData(\n req: RequestLike,\n initialState = {}\n) {\n const authObject = await getAuthDataFromRequest(req);\n return authObjectToSerializable({ ...initialState, ...authObject });\n}\n\nexport async function getAuthDataFromRequest(req: RequestLike): Promise<AuthObject & Aobj> {\n const authStatus = getAuthKeyFromRequest(req, \"AuthStatus\");\n const authToken = getAuthKeyFromRequest(req, \"AuthToken\");\n\n if (!authStatus || authStatus !== AuthStatus.SignedIn) {\n return {\n ...signedOutAuthObject(),\n user: null,\n userId: null\n }\n }\n\n const firebaseUser = await authenticateRequest(authToken as string, req as any);\n if (!firebaseUser || !firebaseUser.claims) {\n return {\n ...signedOutAuthObject(),\n user: null,\n userId: null\n }\n }\n const { user, claims } = firebaseUser;\n const authObject = signedInAuthObject(authToken as string, claims as any);\n return {\n ...authObject,\n user: user || null,\n };\n}\n\nconst authenticateRequest = async (\n token: string,\n request: Request\n): Promise<{ user: SerializableTernSecureUser; claims: ParsedToken } | null> => {\n try {\n const origin = new URL(request.url).origin;\n\n const requestHeaders = new Headers(request.headers);\n requestHeaders.set(\"referer\", origin);\n requestHeaders.set(\"Referer\", origin);\n\n const mockRequest = {\n headers: requestHeaders,\n };\n\n const config: TernSecureConfig = {\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 measurementId: FIREBASE_MEASUREMENT_ID,\n };\n\n const firebaseServerApp: FirebaseServerApp = initializeServerApp(\n config,\n {\n authIdToken: token,\n releaseOnDeref: mockRequest,\n }\n );\n\n const auth: Auth = getAuth(firebaseServerApp);\n await auth.authStateReady();\n\n if (auth.currentUser) {\n const idTokenResult = await auth.currentUser.getIdTokenResult();\n const claims = idTokenResult.claims;\n\n const userObj: SerializableTernSecureUser = {\n uid: auth.currentUser.uid,\n email: auth.currentUser.email,\n emailVerified: auth.currentUser.emailVerified,\n displayName: auth.currentUser.displayName,\n isAnonymous: auth.currentUser.isAnonymous,\n phoneNumber: auth.currentUser.phoneNumber,\n photoURL: auth.currentUser.photoURL,\n providerId: auth.currentUser.providerId,\n tenantId: auth.currentUser.tenantId,\n refreshToken: auth.currentUser.refreshToken,\n metadata: {\n creationTime: auth.currentUser.metadata.creationTime,\n lastSignInTime: auth.currentUser.metadata.lastSignInTime,\n },\n providerData: auth.currentUser.providerData.map((provider) => ({\n uid: provider.uid,\n displayName: provider.displayName,\n email: provider.email,\n phoneNumber: provider.phoneNumber,\n photoURL: provider.photoURL,\n providerId: provider.providerId,\n })),\n };\n\n return { user: userObj, claims };\n }\n\n return null;\n } catch (error) {\n return null;\n }\n};\n\nexport { TernSecureUser }\n"],"mappings":"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","names":["require"]}
1
+ {"version":3,"sources":["../../../../src/server/data/getAuthDataFromRequest.ts"],"sourcesContent":["import type { AuthObject } from '@tern-secure/backend';\nimport { AuthStatus, signedInAuthObject, signedOutAuthObject } from '@tern-secure/backend';\nimport { ternDecodeJwt } from '@tern-secure/backend/jwt';\nimport type { ParsedToken, TernSecureConfig, TernSecureUser } from '@tern-secure/types';\nimport type { FirebaseServerApp } from \"firebase/app\";\nimport { initializeServerApp } from \"firebase/app\";\nimport type { Auth } from \"firebase/auth\";\nimport { getAuth } from \"firebase/auth\";\n\nimport { getAuthKeyFromRequest, getHeader } from '../../server/headers-utils';\nimport type { RequestLike } from '../../server/types';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MEASUREMENT_ID,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET\n} from \"../constant\";\n\n\n/**\n * Auth objects moving through the server -> client boundary need to be serializable\n * as we need to ensure that they can be transferred via the network as pure strings.\n * Some frameworks like Remix or Next (/pages dir only) handle this serialization by simply\n * ignoring any non-serializable keys, however Nextjs /app directory is stricter and\n * throws an error if a non-serializable value is found.\n * @internal\n */\nexport const authObjectToSerializableJwt = <T extends Record<string, unknown>>(obj: T): T => {\n // remove any non-serializable props from the returned object\n\n const { require, ...rest } = obj as unknown as AuthObject;\n return rest as unknown as T;\n};\n\nexport function getTernSecureAuthDataJwt(req: RequestLike, initialState = {}) {\n const authObject = getAuthDataFromRequestJwt(req);\n return authObjectToSerializable({ ...initialState, ...authObject });\n}\n\nexport function getAuthDataFromRequestJwt(req: RequestLike): AuthObject {\n const authStatus = getAuthKeyFromRequest(req, 'AuthStatus');\n const authToken = getAuthKeyFromRequest(req, 'AuthToken');\n const authSignature = getAuthKeyFromRequest(req, 'AuthSignature');\n const authReason = getAuthKeyFromRequest(req, 'AuthReason');\n\n let authObject;\n if (!authStatus || authStatus !== AuthStatus.SignedIn) {\n authObject = signedOutAuthObject();\n } else {\n const jwt = ternDecodeJwt(authToken as string);\n\n authObject = signedInAuthObject(jwt.raw.text, jwt.payload);\n }\n return authObject;\n}\n\n\nexport type SerializableTernSecureUser = Omit<TernSecureUser, 'delete' | 'getIdToken' | 'getIdTokenResult' | 'reload' | 'toJSON'>;\n\nexport type Aobj = {\n user: SerializableTernSecureUser | null\n userId: string | null\n}\n\n\n// Serializable auth object type\n/**\n * Auth objects moving through the server -> client boundary need to be serializable\n * as we need to ensure that they can be transferred via the network as pure strings.\n * Some frameworks like Remix or Next (/pages dir only) handle this serialization by simply\n * ignoring any non-serializable keys, however Nextjs /app directory is stricter and\n * throws an error if a non-serializable value is found.\n * @internal\n */\nexport const authObjectToSerializable = <T extends Record<string, unknown>>(\n obj: T\n): T => {\n // remove any non-serializable props from the returned object\n\n const { require, ...rest } = obj as unknown as AuthObject;\n return rest as unknown as T;\n};\n\nexport async function getTernSecureAuthData(\n req: RequestLike,\n initialState = {}\n) {\n const authObject = await getAuthDataFromRequest(req);\n return authObjectToSerializable({ ...initialState, ...authObject });\n}\n\nexport async function getAuthDataFromRequest(req: RequestLike): Promise<AuthObject & Aobj> {\n const authStatus = getAuthKeyFromRequest(req, \"AuthStatus\");\n const authToken = getAuthKeyFromRequest(req, \"AuthToken\");\n const appCheckToken = getHeader(req, \"X-Firebase-AppCheck\");\n\n if (!authStatus || authStatus !== AuthStatus.SignedIn) {\n return {\n ...signedOutAuthObject(),\n user: null,\n userId: null\n }\n }\n\n const firebaseUser = await authenticateRequest(\n authToken as string, \n req as any, \n appCheckToken as string | undefined\n );\n if (!firebaseUser || !firebaseUser.claims) {\n return {\n ...signedOutAuthObject(),\n user: null,\n userId: null\n }\n }\n const { user, claims } = firebaseUser;\n const authObject = signedInAuthObject(authToken as string, claims as any);\n return {\n ...authObject,\n user: user || null,\n };\n}\n\nconst authenticateRequest = async (\n token: string,\n request: Request,\n appCheckToken?: string\n): Promise<{ user: SerializableTernSecureUser; claims: ParsedToken } | null> => {\n try {\n //console.log(\"[getAuthDataFromRequest] App Check Token:\", appCheckToken);\n const origin = new URL(request.url).origin;\n\n const requestHeaders = new Headers(request.headers);\n requestHeaders.set(\"referer\", origin);\n requestHeaders.set(\"Referer\", origin);\n\n const mockRequest = {\n headers: requestHeaders,\n };\n\n const config: TernSecureConfig = {\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 measurementId: FIREBASE_MEASUREMENT_ID,\n };\n\n const firebaseServerApp: FirebaseServerApp = initializeServerApp(\n config,\n {\n authIdToken: token,\n appCheckToken: appCheckToken,\n releaseOnDeref: mockRequest,\n }\n );\n\n const auth: Auth = getAuth(firebaseServerApp);\n await auth.authStateReady();\n\n if (auth.currentUser) {\n const idTokenResult = await auth.currentUser.getIdTokenResult();\n const claims = idTokenResult.claims;\n\n const userObj: SerializableTernSecureUser = {\n uid: auth.currentUser.uid,\n email: auth.currentUser.email,\n emailVerified: auth.currentUser.emailVerified,\n displayName: auth.currentUser.displayName,\n isAnonymous: auth.currentUser.isAnonymous,\n phoneNumber: auth.currentUser.phoneNumber,\n photoURL: auth.currentUser.photoURL,\n providerId: auth.currentUser.providerId,\n tenantId: auth.currentUser.tenantId,\n refreshToken: auth.currentUser.refreshToken,\n metadata: {\n creationTime: auth.currentUser.metadata.creationTime,\n lastSignInTime: auth.currentUser.metadata.lastSignInTime,\n },\n providerData: auth.currentUser.providerData.map((provider) => ({\n uid: provider.uid,\n displayName: provider.displayName,\n email: provider.email,\n phoneNumber: provider.phoneNumber,\n photoURL: provider.photoURL,\n providerId: provider.providerId,\n })),\n };\n\n return { user: userObj, claims };\n }\n\n return null;\n } catch (error) {\n return null;\n }\n};\n\nexport { TernSecureUser }\n"],"mappings":"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","names":["require"]}
@@ -1,6 +1,4 @@
1
- import {
2
- ternSecureProxy
3
- } from "./ternSecureProxy";
1
+ import { ternSecureProxy } from "./ternSecureProxy";
4
2
  import { ternSecureInstrumentation } from "./instrumentation";
5
3
  import { createRouteMatcher } from "./routeMatcher";
6
4
  import { ternSecureBackendClient } from "./ternsecureClient";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/index.ts"],"sourcesContent":["export {\r\n ternSecureProxy,\r\n} from \"./ternSecureProxy\";\r\nexport { ternSecureInstrumentation } from \"./instrumentation\";\r\nexport { createRouteMatcher } from \"./routeMatcher\";\r\nexport { ternSecureBackendClient } from \"./ternsecureClient\";\r\nexport {\r\n auth\r\n} from \"../app-router/server/auth\";\r\nexport type { AuthResult } from \"../app-router/server/auth\";\r\nexport type { BaseUser, SessionResult } from \"./types\";\r\nexport { NextCookieStore } from \"../utils/NextCookieAdapter\";\r\n"],"mappings":"AAAA;AAAA,EACE;AAAA,OACK;AACP,SAAS,iCAAiC;AAC1C,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC;AAAA,EACE;AAAA,OACK;AAGP,SAAS,uBAAuB;","names":[]}
1
+ {"version":3,"sources":["../../../src/server/index.ts"],"sourcesContent":["export { ternSecureProxy } from \"./ternSecureProxy\";\r\nexport { ternSecureInstrumentation } from \"./instrumentation\";\r\nexport { createRouteMatcher } from \"./routeMatcher\";\r\nexport { ternSecureBackendClient } from \"./ternsecureClient\";\r\nexport {\r\n auth\r\n} from \"../app-router/server/auth\";\r\nexport type { AuthResult } from \"../app-router/server/auth\";\r\nexport type { BaseUser, SessionResult } from \"./types\";\r\nexport { NextCookieStore } from \"../utils/NextCookieAdapter\";\r\n"],"mappings":"AAAA,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC;AAAA,EACE;AAAA,OACK;AAGP,SAAS,uBAAuB;","names":[]}
@@ -3,7 +3,7 @@ import { notFound as nextjsNotFound } from "next/navigation";
3
3
  import { NextResponse } from "next/server";
4
4
  import { isRedirect, setHeader } from "../utils/response";
5
5
  import { serverRedirectWithAuth } from "../utils/serverRedirectAuth";
6
- import { FIREBASE_API_KEY, SIGN_IN_URL, SIGN_UP_URL } from "./constant";
6
+ import { FIREBASE_API_KEY, FIREBASE_APP_ID, FIREBASE_PROJECT_ID, SIGN_IN_URL, SIGN_UP_URL } from "./constant";
7
7
  import {
8
8
  isNextjsNotFoundError,
9
9
  isNextjsRedirectError,
@@ -25,10 +25,20 @@ const ternSecureProxy = (...args) => {
25
25
  const signInUrl = resolvedParams.signInUrl || SIGN_IN_URL;
26
26
  const signUpUrl = resolvedParams.signUpUrl || SIGN_UP_URL;
27
27
  const apiKey = resolvedParams.apiKey || FIREBASE_API_KEY;
28
+ const appId = FIREBASE_APP_ID;
29
+ const projectId = FIREBASE_PROJECT_ID;
30
+ const firebaseConfig = resolvedParams.firebaseConfig || {
31
+ apiKey,
32
+ appId,
33
+ projectId
34
+ };
35
+ const firebaseAdminConfig = resolvedParams.firebaseAdminConfig;
28
36
  const options = {
29
37
  signInUrl,
30
38
  signUpUrl,
31
39
  apiKey,
40
+ firebaseConfig,
41
+ firebaseAdminConfig,
32
42
  ...resolvedParams
33
43
  };
34
44
  const reqBackendClient = await ternSecureBackendClient();
@@ -38,6 +48,8 @@ const ternSecureProxy = (...args) => {
38
48
  options
39
49
  );
40
50
  const locationHeader = requestStateClient.headers.get(constants.Headers.Location);
51
+ const appCheckToken = requestStateClient.headers.get(constants.Headers.AppCheckToken);
52
+ console.log("[ternSecureProxy] App Check Token in Proxy:", appCheckToken);
41
53
  if (locationHeader) {
42
54
  return new Response(null, {
43
55
  status: 307,
@@ -47,8 +59,8 @@ const ternSecureProxy = (...args) => {
47
59
  throw new Error("TernSecure: handshake status without redirect is not supported.");
48
60
  }
49
61
  const authObjectClient = requestStateClient.auth();
50
- const { redirectToSignIn } = createMiddlewareRedirects(ternSecureRequest);
51
- const { redirectToSignUp } = createMiddlewareRedirects(ternSecureRequest);
62
+ const redirectToSignIn = createProxyRedirectToSignIn(ternSecureRequest);
63
+ const redirectToSignUp = createProxyRedirectToSignUp(ternSecureRequest);
52
64
  const protect = await createMiddlewareProtect(
53
65
  ternSecureRequest,
54
66
  authObjectClient,
@@ -75,7 +87,7 @@ const ternSecureProxy = (...args) => {
75
87
  if (isRedirect(handlerResult)) {
76
88
  return serverRedirectWithAuth(ternSecureRequest, handlerResult);
77
89
  }
78
- decorateRequest(ternSecureRequest, handlerResult, requestStateClient);
90
+ decorateRequest(ternSecureRequest, handlerResult, requestStateClient, appCheckToken || void 0);
79
91
  return handlerResult;
80
92
  };
81
93
  const nextMiddleware = async (request2, event2) => {
@@ -100,6 +112,18 @@ const parseHandlerAndOptions = (args) => {
100
112
  (args.length === 2 ? args[1] : typeof args[0] === "function" ? {} : args[0]) || {}
101
113
  ];
102
114
  };
115
+ const createProxyRedirectToSignIn = (ternSecureRequest) => {
116
+ return (opts = {}) => {
117
+ const url = ternSecureRequest.ternUrl.toString();
118
+ redirectToSignInError(url, opts.returnBackUrl);
119
+ };
120
+ };
121
+ const createProxyRedirectToSignUp = (ternSecureRequest) => {
122
+ return (opts = {}) => {
123
+ const url = ternSecureRequest.ternUrl.toString();
124
+ redirectToSignUpError(url, opts.returnBackUrl);
125
+ };
126
+ };
103
127
  const createMiddlewareRedirects = (ternSecureRequest) => {
104
128
  const redirectToSignIn = (opts = {}) => {
105
129
  const url = ternSecureRequest.ternUrl.toString();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/ternSecureProxy.ts"],"sourcesContent":["import type {\r\n AuthenticateRequestOptions,\r\n AuthObject,\r\n RedirectFun,\r\n RequestState,\r\n TernSecureRequest,\r\n} from '@tern-secure/backend';\r\nimport { AuthStatus, constants, createRedirect, createTernSecureRequest} from '@tern-secure/backend';\r\nimport { notFound as nextjsNotFound } from 'next/navigation';\r\nimport type { NextMiddleware, NextRequest } from 'next/server';\r\nimport { NextResponse } from 'next/server';\r\n\r\nimport { isRedirect, setHeader } from '../utils/response';\r\nimport { serverRedirectWithAuth } from '../utils/serverRedirectAuth';\r\nimport {FIREBASE_API_KEY, SIGN_IN_URL, SIGN_UP_URL } from './constant';\r\nimport {\r\n isNextjsNotFoundError,\r\n isNextjsRedirectError,\r\n isRedirectToSignInError,\r\n isRedirectToSignUpError,\r\n nextjsRedirectError,\r\n redirectToSignInError,\r\n redirectToSignUpError,\r\n} from './nextErrors';\r\nimport { type AuthProtect, createProtect } from './protect';\r\nimport { ternSecureBackendClient } from './ternsecureClient';\r\nimport type {\r\n NextMiddlewareEvtParam,\r\n NextMiddlewareRequestParam,\r\n NextMiddlewareReturn,\r\n} from './types';\r\nimport { decorateRequest } from './utils';\r\n\r\nexport type MiddlewareAuthObject = AuthObject & {\r\n redirectToSignIn: RedirectFun<Response>;\r\n redirectToSignUp: RedirectFun<Response>;\r\n};\r\n\r\nexport interface MiddlewareAuth {\r\n (): Promise<MiddlewareAuthObject>;\r\n\r\n protect: AuthProtect;\r\n}\r\n\r\ntype MiddlewareHandler = (\r\n auth: MiddlewareAuth,\r\n request: NextMiddlewareRequestParam,\r\n event: NextMiddlewareEvtParam,\r\n) => NextMiddlewareReturn;\r\n\r\nexport interface MiddlewareOptions extends AuthenticateRequestOptions {\r\n debug?: boolean;\r\n}\r\ntype MiddlewareOptionsCallback = (\r\n req: NextRequest,\r\n) => MiddlewareOptions | Promise<MiddlewareOptions>;\r\n\r\ninterface TernSecureMiddleware {\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware((auth, request, event) => { ... }, options);\r\n */\r\n (handler: MiddlewareHandler, options?: MiddlewareOptions): NextMiddleware;\r\n\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware((auth, request, event) => { ... }, (req) => options);\r\n */\r\n (handler: MiddlewareHandler, options?: MiddlewareOptionsCallback): NextMiddleware;\r\n\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware(options);\r\n */\r\n (options?: MiddlewareOptions): NextMiddleware;\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware;\r\n */\r\n (request: NextMiddlewareRequestParam, event: NextMiddlewareEvtParam): NextMiddlewareReturn;\r\n}\r\n\r\nexport const ternSecureProxy= ((\r\n ...args: unknown[]\r\n): NextMiddleware | NextMiddlewareReturn => {\r\n const [request, event] = parseRequestAndEvent(args);\r\n const [handler, params] = parseHandlerAndOptions(args);\r\n\r\n const middleware = () => {\r\n const withAuthNextMiddleware: NextMiddleware = async (request, event) => {\r\n const resolvedParams = typeof params === 'function' ? await params(request) : params;\r\n\r\n const signInUrl = resolvedParams.signInUrl || SIGN_IN_URL;\r\n const signUpUrl = resolvedParams.signUpUrl || SIGN_UP_URL;\r\n const apiKey = resolvedParams.apiKey || FIREBASE_API_KEY;\r\n\r\n const options = {\r\n signInUrl,\r\n signUpUrl,\r\n apiKey,\r\n ...resolvedParams,\r\n };\r\n\r\n const reqBackendClient = await ternSecureBackendClient();\r\n\r\n const ternSecureRequest = createTernSecureRequest(request);\r\n\r\n const requestStateClient = await reqBackendClient.authenticateRequest(\r\n ternSecureRequest,\r\n options,\r\n );\r\n\r\n const locationHeader = requestStateClient.headers.get(constants.Headers.Location);\r\n if (locationHeader) {\r\n return new Response(null, {\r\n status: 307,\r\n headers: requestStateClient.headers,\r\n });\r\n } else if (requestStateClient.status === AuthStatus.Handshake) {\r\n throw new Error('TernSecure: handshake status without redirect is not supported.');\r\n }\r\n\r\n const authObjectClient = requestStateClient.auth();\r\n\r\n const { redirectToSignIn } = createMiddlewareRedirects(ternSecureRequest);\r\n\r\n const { redirectToSignUp } = createMiddlewareRedirects(ternSecureRequest);\r\n\r\n const protect = await createMiddlewareProtect(\r\n ternSecureRequest,\r\n authObjectClient,\r\n redirectToSignIn,\r\n );\r\n\r\n const authObj: MiddlewareAuthObject = Object.assign(authObjectClient, {\r\n redirectToSignIn,\r\n redirectToSignUp,\r\n });\r\n\r\n const authHandler = () => Promise.resolve(authObj);\r\n authHandler.protect = protect;\r\n\r\n let handlerResult: Response = NextResponse.next();\r\n\r\n try {\r\n const userHandlerResult = await handler?.(authHandler, request, event);\r\n handlerResult = userHandlerResult || handlerResult;\r\n } catch (error: any) {\r\n handlerResult = handleControlError(error, ternSecureRequest, request, requestStateClient);\r\n }\r\n\r\n if (requestStateClient.headers) {\r\n requestStateClient.headers.forEach((value, key) => {\r\n handlerResult.headers.append(key, value);\r\n });\r\n }\r\n\r\n if (isRedirect(handlerResult)) {\r\n return serverRedirectWithAuth(ternSecureRequest, handlerResult);\r\n }\r\n\r\n decorateRequest(ternSecureRequest, handlerResult, requestStateClient);\r\n return handlerResult;\r\n };\r\n\r\n const nextMiddleware: NextMiddleware = async (request, event) => {\r\n return withAuthNextMiddleware(request, event);\r\n };\r\n\r\n if (request && event) {\r\n return nextMiddleware(request, event);\r\n }\r\n\r\n return nextMiddleware;\r\n };\r\n return middleware();\r\n}) as TernSecureMiddleware;\r\n\r\nconst parseRequestAndEvent = (args: unknown[]) => {\r\n return [\r\n args[0] instanceof Request ? args[0] : undefined,\r\n args[0] instanceof Request ? args[1] : undefined,\r\n ] as [NextMiddlewareRequestParam | undefined, NextMiddlewareEvtParam | undefined];\r\n};\r\n\r\nconst parseHandlerAndOptions = (args: unknown[]) => {\r\n return [\r\n typeof args[0] === 'function' ? args[0] : undefined,\r\n (args.length === 2 ? args[1] : typeof args[0] === 'function' ? {} : args[0]) || {},\r\n ] as [MiddlewareHandler | undefined, MiddlewareOptions | MiddlewareOptionsCallback];\r\n};\r\n\r\n/**\r\n * Create middleware redirect functions\r\n */\r\nconst createMiddlewareRedirects = (ternSecureRequest: TernSecureRequest) => {\r\n const redirectToSignIn: MiddlewareAuthObject['redirectToSignIn'] = (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignInError(url, opts.returnBackUrl);\r\n };\r\n\r\n const redirectToSignUp: MiddlewareAuthObject['redirectToSignUp'] = (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignUpError(url, opts.returnBackUrl);\r\n };\r\n\r\n return { redirectToSignIn, redirectToSignUp };\r\n};\r\n\r\nconst createMiddlewareProtect = (\r\n ternSecureRequest: TernSecureRequest,\r\n authObject: AuthObject,\r\n redirectToSignIn: RedirectFun<Response>,\r\n) => {\r\n return (async (params: any, options: any) => {\r\n const notFound = () => nextjsNotFound();\r\n\r\n const redirect = (url: string) =>\r\n nextjsRedirectError(url, {\r\n redirectUrl: url,\r\n });\r\n\r\n return createProtect({\r\n request: ternSecureRequest,\r\n redirect,\r\n notFound,\r\n authObject,\r\n redirectToSignIn,\r\n })(params, options);\r\n }) as unknown as Promise<AuthProtect>;\r\n};\r\n\r\nexport const redirectAdapter = (url: string | URL) => {\r\n return NextResponse.redirect(url, {\r\n headers: { [constants.Headers.TernSecureRedirectTo]: 'true' },\r\n });\r\n};\r\n\r\n/**\r\n * Handle control flow errors in middleware\r\n */\r\nconst handleControlError = (\r\n error: any,\r\n ternSecureRequest: TernSecureRequest,\r\n nextrequest: NextRequest,\r\n requestState: RequestState,\r\n): Response => {\r\n if (isNextjsNotFoundError(error)) {\r\n return setHeader(\r\n NextResponse.rewrite(new URL(`/tern_${Date.now()}`, nextrequest.url)),\r\n constants.Headers.AuthReason,\r\n 'protect-rewrite',\r\n );\r\n }\r\n\r\n const isRedirectToSignIn = isRedirectToSignInError(error);\r\n const isRedirectToSignUp = isRedirectToSignUpError(error);\r\n\r\n if (isRedirectToSignIn || isRedirectToSignUp) {\r\n const redirect = createRedirect({\r\n redirectAdapter,\r\n baseUrl: ternSecureRequest.ternUrl,\r\n signInUrl: requestState.signInUrl,\r\n signUpUrl: requestState.signUpUrl,\r\n });\r\n\r\n const { returnBackUrl } = error;\r\n\r\n return redirect[isRedirectToSignIn ? 'redirectToSignIn' : 'redirectToSignUp']({\r\n returnBackUrl,\r\n });\r\n }\r\n\r\n if (isNextjsRedirectError(error)) {\r\n return redirectAdapter(error.redirectUrl);\r\n }\r\n\r\n throw error;\r\n};\r\n"],"mappings":"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","names":["request","event"]}
1
+ {"version":3,"sources":["../../../src/server/ternSecureProxy.ts"],"sourcesContent":["import type {\r\n AuthenticateRequestOptions,\r\n AuthObject,\r\n RedirectFun,\r\n RequestState,\r\n TernSecureRequest,\r\n} from '@tern-secure/backend';\r\nimport { AuthStatus, constants, createRedirect, createTernSecureRequest } from '@tern-secure/backend';\r\nimport { notFound as nextjsNotFound } from 'next/navigation';\r\nimport type { NextMiddleware, NextRequest } from 'next/server';\r\nimport { NextResponse } from 'next/server';\r\n\r\nimport { isRedirect, setHeader } from '../utils/response';\r\nimport { serverRedirectWithAuth } from '../utils/serverRedirectAuth';\r\nimport { FIREBASE_API_KEY, FIREBASE_APP_ID, FIREBASE_PROJECT_ID,SIGN_IN_URL, SIGN_UP_URL } from './constant';\r\nimport {\r\n isNextjsNotFoundError,\r\n isNextjsRedirectError,\r\n isRedirectToSignInError,\r\n isRedirectToSignUpError,\r\n nextjsRedirectError,\r\n redirectToSignInError,\r\n redirectToSignUpError,\r\n} from './nextErrors';\r\nimport { type AuthProtect, createProtect } from './protect';\r\nimport { ternSecureBackendClient } from './ternsecureClient';\r\nimport type {\r\n NextMiddlewareEvtParam,\r\n NextMiddlewareRequestParam,\r\n NextMiddlewareReturn,\r\n} from './types';\r\nimport { decorateRequest } from './utils';\r\n\r\nexport type MiddlewareAuthObject = AuthObject & {\r\n redirectToSignIn: RedirectFun<Response>;\r\n redirectToSignUp: RedirectFun<Response>;\r\n};\r\n\r\nexport interface MiddlewareAuth {\r\n (): Promise<MiddlewareAuthObject>;\r\n\r\n protect: AuthProtect;\r\n}\r\n\r\ntype MiddlewareHandler = (\r\n auth: MiddlewareAuth,\r\n request: NextMiddlewareRequestParam,\r\n event: NextMiddlewareEvtParam,\r\n) => NextMiddlewareReturn;\r\n\r\nexport interface MiddlewareOptions extends AuthenticateRequestOptions {\r\n debug?: boolean;\r\n}\r\ntype MiddlewareOptionsCallback = (\r\n req: NextRequest,\r\n) => MiddlewareOptions | Promise<MiddlewareOptions>;\r\n\r\ninterface TernSecureMiddleware {\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware((auth, request, event) => { ... }, options);\r\n */\r\n (handler: MiddlewareHandler, options?: MiddlewareOptions): NextMiddleware;\r\n\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware((auth, request, event) => { ... }, (req) => options);\r\n */\r\n (handler: MiddlewareHandler, options?: MiddlewareOptionsCallback): NextMiddleware;\r\n\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware(options);\r\n */\r\n (options?: MiddlewareOptions): NextMiddleware;\r\n /**\r\n * @example\r\n * export default ternSecureMiddleware;\r\n */\r\n (request: NextMiddlewareRequestParam, event: NextMiddlewareEvtParam): NextMiddlewareReturn;\r\n}\r\n\r\nexport const ternSecureProxy = ((\r\n ...args: unknown[]\r\n): NextMiddleware | NextMiddlewareReturn => {\r\n const [request, event] = parseRequestAndEvent(args);\r\n const [handler, params] = parseHandlerAndOptions(args);\r\n\r\n const middleware = () => {\r\n const withAuthNextMiddleware: NextMiddleware = async (request, event) => {\r\n const resolvedParams = typeof params === 'function' ? await params(request) : params;\r\n\r\n const signInUrl = resolvedParams.signInUrl || SIGN_IN_URL;\r\n const signUpUrl = resolvedParams.signUpUrl || SIGN_UP_URL;\r\n const apiKey = resolvedParams.apiKey || FIREBASE_API_KEY;\r\n const appId = FIREBASE_APP_ID;\r\n const projectId = FIREBASE_PROJECT_ID;\r\n const firebaseConfig = resolvedParams.firebaseConfig || {\r\n apiKey,\r\n appId,\r\n projectId,\r\n }\r\n const firebaseAdminConfig = resolvedParams.firebaseAdminConfig;\r\n\r\n const options = {\r\n signInUrl,\r\n signUpUrl,\r\n apiKey,\r\n firebaseConfig,\r\n firebaseAdminConfig,\r\n ...resolvedParams,\r\n };\r\n\r\n const reqBackendClient = await ternSecureBackendClient();\r\n\r\n const ternSecureRequest = createTernSecureRequest(request);\r\n\r\n const requestStateClient = await reqBackendClient.authenticateRequest(\r\n ternSecureRequest,\r\n options,\r\n );\r\n\r\n const locationHeader = requestStateClient.headers.get(constants.Headers.Location);\r\n const appCheckToken = requestStateClient.headers.get(constants.Headers.AppCheckToken);\r\n console.log(\"[ternSecureProxy] App Check Token in Proxy:\", appCheckToken);\r\n if (locationHeader) {\r\n return new Response(null, {\r\n status: 307,\r\n headers: requestStateClient.headers,\r\n });\r\n } else if (requestStateClient.status === AuthStatus.Handshake) {\r\n throw new Error('TernSecure: handshake status without redirect is not supported.');\r\n }\r\n\r\n const authObjectClient = requestStateClient.auth();\r\n\r\n const redirectToSignIn = createProxyRedirectToSignIn(ternSecureRequest);\r\n const redirectToSignUp = createProxyRedirectToSignUp(ternSecureRequest);\r\n const protect = await createMiddlewareProtect(\r\n ternSecureRequest,\r\n authObjectClient,\r\n redirectToSignIn,\r\n );\r\n\r\n const authObj: MiddlewareAuthObject = Object.assign(authObjectClient, {\r\n redirectToSignIn,\r\n redirectToSignUp,\r\n });\r\n\r\n const authHandler = () => Promise.resolve(authObj);\r\n authHandler.protect = protect;\r\n\r\n let handlerResult: Response = NextResponse.next();\r\n\r\n try {\r\n const userHandlerResult = await handler?.(authHandler, request, event);\r\n handlerResult = userHandlerResult || handlerResult;\r\n } catch (error: any) {\r\n handlerResult = handleControlError(error, ternSecureRequest, request, requestStateClient);\r\n }\r\n\r\n if (requestStateClient.headers) {\r\n requestStateClient.headers.forEach((value, key) => {\r\n handlerResult.headers.append(key, value);\r\n });\r\n }\r\n\r\n if (isRedirect(handlerResult)) {\r\n return serverRedirectWithAuth(ternSecureRequest, handlerResult);\r\n }\r\n\r\n decorateRequest(ternSecureRequest, handlerResult, requestStateClient, appCheckToken || undefined);\r\n return handlerResult;\r\n };\r\n\r\n const nextMiddleware: NextMiddleware = async (request, event) => {\r\n return withAuthNextMiddleware(request, event);\r\n };\r\n\r\n if (request && event) {\r\n return nextMiddleware(request, event);\r\n }\r\n\r\n return nextMiddleware;\r\n };\r\n return middleware();\r\n}) as TernSecureMiddleware;\r\n\r\nconst parseRequestAndEvent = (args: unknown[]) => {\r\n return [\r\n args[0] instanceof Request ? args[0] : undefined,\r\n args[0] instanceof Request ? args[1] : undefined,\r\n ] as [NextMiddlewareRequestParam | undefined, NextMiddlewareEvtParam | undefined];\r\n};\r\n\r\nconst parseHandlerAndOptions = (args: unknown[]) => {\r\n return [\r\n typeof args[0] === 'function' ? args[0] : undefined,\r\n (args.length === 2 ? args[1] : typeof args[0] === 'function' ? {} : args[0]) || {},\r\n ] as [MiddlewareHandler | undefined, MiddlewareOptions | MiddlewareOptionsCallback];\r\n};\r\n\r\n\r\nconst createProxyRedirectToSignIn = (\r\n ternSecureRequest: TernSecureRequest,\r\n): MiddlewareAuthObject['redirectToSignIn'] => {\r\n return (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignInError(url, opts.returnBackUrl);\r\n };\r\n};\r\n\r\nconst createProxyRedirectToSignUp = (\r\n ternSecureRequest: TernSecureRequest,\r\n): MiddlewareAuthObject['redirectToSignUp'] => {\r\n return (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignUpError(url, opts.returnBackUrl);\r\n };\r\n};\r\n\r\n/**\r\n * Create middleware redirect functions\r\n * @deprecated\r\n */\r\nconst createMiddlewareRedirects = (ternSecureRequest: TernSecureRequest) => {\r\n const redirectToSignIn: MiddlewareAuthObject['redirectToSignIn'] = (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignInError(url, opts.returnBackUrl);\r\n };\r\n\r\n const redirectToSignUp: MiddlewareAuthObject['redirectToSignUp'] = (opts = {}) => {\r\n const url = ternSecureRequest.ternUrl.toString();\r\n redirectToSignUpError(url, opts.returnBackUrl);\r\n };\r\n\r\n return { redirectToSignIn, redirectToSignUp };\r\n};\r\n\r\nconst createMiddlewareProtect = (\r\n ternSecureRequest: TernSecureRequest,\r\n authObject: AuthObject,\r\n redirectToSignIn: RedirectFun<Response>,\r\n) => {\r\n return (async (params: any, options: any) => {\r\n const notFound = () => nextjsNotFound();\r\n\r\n const redirect = (url: string) =>\r\n nextjsRedirectError(url, {\r\n redirectUrl: url,\r\n });\r\n\r\n return createProtect({\r\n request: ternSecureRequest,\r\n redirect,\r\n notFound,\r\n authObject,\r\n redirectToSignIn,\r\n })(params, options);\r\n }) as unknown as Promise<AuthProtect>;\r\n};\r\n\r\nexport const redirectAdapter = (url: string | URL) => {\r\n return NextResponse.redirect(url, {\r\n headers: { [constants.Headers.TernSecureRedirectTo]: 'true' },\r\n });\r\n};\r\n\r\n/**\r\n * Handle control flow errors in middleware\r\n */\r\nconst handleControlError = (\r\n error: any,\r\n ternSecureRequest: TernSecureRequest,\r\n nextrequest: NextRequest,\r\n requestState: RequestState,\r\n): Response => {\r\n if (isNextjsNotFoundError(error)) {\r\n return setHeader(\r\n NextResponse.rewrite(new URL(`/tern_${Date.now()}`, nextrequest.url)),\r\n constants.Headers.AuthReason,\r\n 'protect-rewrite',\r\n );\r\n }\r\n\r\n const isRedirectToSignIn = isRedirectToSignInError(error);\r\n const isRedirectToSignUp = isRedirectToSignUpError(error);\r\n\r\n if (isRedirectToSignIn || isRedirectToSignUp) {\r\n const redirect = createRedirect({\r\n redirectAdapter,\r\n baseUrl: ternSecureRequest.ternUrl,\r\n signInUrl: requestState.signInUrl,\r\n signUpUrl: requestState.signUpUrl,\r\n });\r\n\r\n const { returnBackUrl } = error;\r\n\r\n return redirect[isRedirectToSignIn ? 'redirectToSignIn' : 'redirectToSignUp']({\r\n returnBackUrl,\r\n });\r\n }\r\n\r\n if (isNextjsRedirectError(error)) {\r\n return redirectAdapter(error.redirectUrl);\r\n }\r\n\r\n throw error;\r\n};\r\n"],"mappings":"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","names":["request","event"]}
@@ -95,7 +95,7 @@ const setRequestHeadersOnNextResponse = (res, req, newHeaders) => {
95
95
  res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);
96
96
  });
97
97
  };
98
- function decorateRequest(req, res, requestState) {
98
+ function decorateRequest(req, res, requestState, appCheckToken) {
99
99
  const { reason, token, status } = requestState;
100
100
  if (!res) {
101
101
  res = NextResponse.next();
@@ -120,6 +120,7 @@ function decorateRequest(req, res, requestState) {
120
120
  setRequestHeadersOnNextResponse(res, req, {
121
121
  [constants.Headers.AuthStatus]: status,
122
122
  [constants.Headers.AuthToken]: token || "",
123
+ [constants.Headers.AppCheckToken]: appCheckToken || req.headers.get(constants.Headers.AppCheckToken) || "",
123
124
  [constants.Headers.AuthReason]: reason || "",
124
125
  [constants.Headers.TernSecureUrl]: req.ternUrl.toString()
125
126
  });
@@ -148,7 +149,7 @@ async function buildRequestLike() {
148
149
  throw e;
149
150
  }
150
151
  throw new Error(
151
- `Clerk: auth(), currentUser() and clerkClient(), are only supported in App Router (/app directory).
152
+ `TernSecure: auth(), currentUser() and ternSecureClient(), are only supported in App Router (/app directory).
152
153
  If you're using /pages, try getAuth() instead.
153
154
  Original error: ${e}`
154
155
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/utils.ts"],"sourcesContent":["import type {\r\n RequestState,\r\n TernSecureRequest,\r\n} from \"@tern-secure/backend\";\r\nimport { constants } from \"@tern-secure/backend\";\r\nimport { NextRequest,NextResponse } from 'next/server';\r\n\r\nimport { constants as nextConstants } from \"../constants\";\r\nimport type { User } from \"./types\"\r\n\r\nconst OVERRIDE_HEADERS = 'x-middleware-override-headers';\r\nconst MIDDLEWARE_HEADER_PREFIX = 'x-middleware-request' as string;\r\n\r\ninterface RequestContext {\r\n user: User\r\n sessionId: string\r\n}\r\n\r\n// Use process.env in Node.js and globalThis in Edge\r\nconst getGlobalObject = () => {\r\n if (typeof process !== 'undefined') {\r\n return process\r\n }\r\n return globalThis\r\n}\r\n\r\nconst STORE_KEY = '__TERN_AUTH_STORE__'\r\n\r\nexport class Store {\r\n private static getStore() {\r\n const global = getGlobalObject() as any\r\n \r\n if (!global[STORE_KEY]) {\r\n global[STORE_KEY] = {\r\n contexts: new Map<string, RequestContext>(),\r\n sessions: new Map<string, User>(),\r\n currentSession: null as RequestContext | null\r\n }\r\n }\r\n \r\n return global[STORE_KEY]\r\n }\r\n\r\n static setContext(context: RequestContext) {\r\n const store = this.getStore()\r\n const { user, sessionId } = context\r\n \r\n console.log(\"Store: Setting context:\", { sessionId, user })\r\n \r\n // Store in both maps\r\n store.contexts.set(sessionId, context)\r\n store.sessions.set(sessionId, user)\r\n \r\n // Set as current session\r\n store.currentSession = context\r\n \r\n console.log(\"Store: Updated state:\", {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession\r\n })\r\n }\r\n\r\n static getContext(): RequestContext | null {\r\n const store = this.getStore()\r\n \r\n // First try current session\r\n if (store.currentSession) {\r\n const session = this.getSession(store.currentSession.sessionId)\r\n if (session && session.uid === store.currentSession.user.uid) {\r\n return store.currentSession\r\n }\r\n }\r\n \r\n // Then try to find any valid context\r\n for (const [sessionId, user] of store.sessions.entries()) {\r\n const context = store.contexts.get(sessionId)\r\n if (context && context.user.uid === user.uid) {\r\n // Update current session\r\n store.currentSession = context\r\n return context\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n static setSession(sessionId: string, user: User) {\r\n const store = this.getStore()\r\n store.sessions.set(sessionId, user)\r\n }\r\n\r\n static getSession(sessionId: string): User | null {\r\n const store = this.getStore()\r\n return store.sessions.get(sessionId) || null\r\n }\r\n\r\n static debug() {\r\n const store = this.getStore()\r\n return {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession,\r\n contexts: Array.from(store.contexts.entries()),\r\n sessions: Array.from(store.sessions.entries())\r\n }\r\n }\r\n\r\n static cleanup() {\r\n const store = this.getStore()\r\n const MAX_ENTRIES = 1000\r\n \r\n if (store.contexts.size > MAX_ENTRIES) {\r\n const keys = Array.from(store.contexts.keys())\r\n const toDelete = keys.slice(0, keys.length - MAX_ENTRIES)\r\n \r\n toDelete.forEach(key => {\r\n store.contexts.delete(key)\r\n store.sessions.delete(key)\r\n })\r\n }\r\n }\r\n}\r\n\r\n\r\nexport const setRequestHeadersOnNextResponse = (\r\n res: NextResponse | Response,\r\n req: Request,\r\n newHeaders: Record<string, string>,\r\n) => {\r\n if (!res.headers.get(OVERRIDE_HEADERS)) {\r\n // Emulate a user setting overrides by explicitly adding the required nextjs headers\r\n // https://github.com/vercel/next.js/pull/41380\r\n // @ts-expect-error -- property keys does not exist on type Headers\r\n res.headers.set(OVERRIDE_HEADERS, [...req.headers.keys()]);\r\n req.headers.forEach((val, key) => {\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n }\r\n\r\n // Now that we have normalised res to include overrides, just append the new header\r\n Object.entries(newHeaders).forEach(([key, val]) => {\r\n res.headers.set(OVERRIDE_HEADERS, `${res.headers.get(OVERRIDE_HEADERS)},${key}`);\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n};\r\n\r\nexport function decorateRequest(\r\n req: TernSecureRequest,\r\n res: Response,\r\n requestState: RequestState,\r\n): Response {\r\n const { reason, token, status } = requestState;\r\n // pass-through case, convert to next()\r\n if (!res) {\r\n res = NextResponse.next();\r\n }\r\n\r\n // redirect() case, return early\r\n if (res.headers.get(nextConstants.Headers.NextRedirect)) {\r\n return res;\r\n }\r\n\r\n let rewriteURL;\r\n\r\n // next() case, convert to a rewrite\r\n if (res.headers.get(nextConstants.Headers.NextResume) === '1') {\r\n res.headers.delete(nextConstants.Headers.NextResume);\r\n rewriteURL = new URL(req.url);\r\n }\r\n\r\n // rewrite() case, set auth result only if origin remains the same\r\n const rewriteURLHeader = res.headers.get(nextConstants.Headers.NextRewrite);\r\n\r\n if (rewriteURLHeader) {\r\n const reqURL = new URL(req.url);\r\n rewriteURL = new URL(rewriteURLHeader);\r\n\r\n // if the origin has changed, return early\r\n if (rewriteURL.origin !== reqURL.origin) {\r\n return res;\r\n }\r\n }\r\n\r\n if (rewriteURL) {\r\n setRequestHeadersOnNextResponse(res, req, {\r\n [constants.Headers.AuthStatus]: status,\r\n [constants.Headers.AuthToken]: token || '',\r\n [constants.Headers.AuthReason]: reason || '',\r\n [constants.Headers.TernSecureUrl]: req.ternUrl.toString(),\r\n });\r\n res.headers.set(nextConstants.Headers.NextRewrite, rewriteURL.href);\r\n }\r\n\r\n return res;\r\n}\r\n\r\n\r\nexport const isPrerenderingBailout = (e: unknown) => {\r\n if (!(e instanceof Error) || !('message' in e)) {\r\n return false;\r\n }\r\n\r\n const { message } = e;\r\n\r\n const lowerCaseInput = message.toLowerCase();\r\n const dynamicServerUsage = lowerCaseInput.includes('dynamic server usage');\r\n const bailOutPrerendering = lowerCaseInput.includes('this page needs to bail out of prerendering');\r\n\r\n // note: new error message syntax introduced in next@14.1.1-canary.21\r\n // but we still want to support older versions.\r\n // https://github.com/vercel/next.js/pull/61332 (dynamic-rendering.ts:153)\r\n const routeRegex = /Route .*? needs to bail out of prerendering at this point because it used .*?./;\r\n\r\n return routeRegex.test(message) || dynamicServerUsage || bailOutPrerendering;\r\n};\r\n\r\nexport async function buildRequestLike(): Promise<NextRequest> {\r\n try {\r\n // Dynamically import next/headers, otherwise Next12 apps will break\r\n // @ts-expect-error: Cannot find module 'next/headers' or its corresponding type declarations.ts(2307)\r\n const { headers } = await import('next/headers');\r\n const resolvedHeaders = await headers();\r\n return new NextRequest('https://placeholder.com', { headers: resolvedHeaders });\r\n } catch (e: any) {\r\n // rethrow the error when react throws a prerendering bailout\r\n // https://nextjs.org/docs/messages/ppr-caught-error\r\n if (e && isPrerenderingBailout(e)) {\r\n throw e;\r\n }\r\n\r\n throw new Error(\r\n `Clerk: auth(), currentUser() and clerkClient(), are only supported in App Router (/app directory).\\nIf you're using /pages, try getAuth() instead.\\nOriginal error: ${e}`,\r\n );\r\n }\r\n}\r\n\r\n// Original source: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/get-script-nonce-from-header.tsx\r\nexport function getScriptNonceFromHeader(cspHeaderValue: string): string | undefined {\r\n const directives = cspHeaderValue\r\n // Directives are split by ';'.\r\n .split(';')\r\n .map(directive => directive.trim());\r\n\r\n // First try to find the directive for the 'script-src', otherwise try to\r\n // fallback to the 'default-src'.\r\n const directive =\r\n directives.find(dir => dir.startsWith('script-src')) || directives.find(dir => dir.startsWith('default-src'));\r\n\r\n // If no directive could be found, then we're done.\r\n if (!directive) {\r\n return;\r\n }\r\n\r\n // Extract the nonce from the directive\r\n const nonce = directive\r\n .split(' ')\r\n // Remove the 'strict-src'/'default-src' string, this can't be the nonce.\r\n .slice(1)\r\n .map(source => source.trim())\r\n // Find the first source with the 'nonce-' prefix.\r\n .find(source => source.startsWith(\"'nonce-\") && source.length > 8 && source.endsWith(\"'\"))\r\n // Grab the nonce by trimming the 'nonce-' prefix.\r\n ?.slice(7, -1);\r\n\r\n // If we couldn't find the nonce, then we're done.\r\n if (!nonce) {\r\n return;\r\n }\r\n\r\n // Don't accept the nonce value if it contains HTML escape characters.\r\n // Technically, the spec requires a base64'd value, but this is just an\r\n // extra layer.\r\n if (/[&><\\u2028\\u2029]/g.test(nonce)) {\r\n throw new Error(\r\n 'Nonce value from Content-Security-Policy contained invalid HTML escape characters, which is disallowed for security reasons. Make sure that your nonce value does not contain the following characters: `<`, `>`, `&`',\r\n );\r\n }\r\n\r\n return nonce;\r\n}\r\n"],"mappings":"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","names":["directive"]}
1
+ {"version":3,"sources":["../../../src/server/utils.ts"],"sourcesContent":["import type {\r\n RequestState,\r\n TernSecureRequest,\r\n} from \"@tern-secure/backend\";\r\nimport { constants } from \"@tern-secure/backend\";\r\nimport { NextRequest,NextResponse } from 'next/server';\r\n\r\nimport { constants as nextConstants } from \"../constants\";\r\nimport type { User } from \"./types\"\r\n\r\nconst OVERRIDE_HEADERS = 'x-middleware-override-headers';\r\nconst MIDDLEWARE_HEADER_PREFIX = 'x-middleware-request' as string;\r\n\r\ninterface RequestContext {\r\n user: User\r\n sessionId: string\r\n}\r\n\r\n// Use process.env in Node.js and globalThis in Edge\r\nconst getGlobalObject = () => {\r\n if (typeof process !== 'undefined') {\r\n return process\r\n }\r\n return globalThis\r\n}\r\n\r\nconst STORE_KEY = '__TERN_AUTH_STORE__'\r\n\r\nexport class Store {\r\n private static getStore() {\r\n const global = getGlobalObject() as any\r\n \r\n if (!global[STORE_KEY]) {\r\n global[STORE_KEY] = {\r\n contexts: new Map<string, RequestContext>(),\r\n sessions: new Map<string, User>(),\r\n currentSession: null as RequestContext | null\r\n }\r\n }\r\n \r\n return global[STORE_KEY]\r\n }\r\n\r\n static setContext(context: RequestContext) {\r\n const store = this.getStore()\r\n const { user, sessionId } = context\r\n \r\n console.log(\"Store: Setting context:\", { sessionId, user })\r\n \r\n // Store in both maps\r\n store.contexts.set(sessionId, context)\r\n store.sessions.set(sessionId, user)\r\n \r\n // Set as current session\r\n store.currentSession = context\r\n \r\n console.log(\"Store: Updated state:\", {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession\r\n })\r\n }\r\n\r\n static getContext(): RequestContext | null {\r\n const store = this.getStore()\r\n \r\n // First try current session\r\n if (store.currentSession) {\r\n const session = this.getSession(store.currentSession.sessionId)\r\n if (session && session.uid === store.currentSession.user.uid) {\r\n return store.currentSession\r\n }\r\n }\r\n \r\n // Then try to find any valid context\r\n for (const [sessionId, user] of store.sessions.entries()) {\r\n const context = store.contexts.get(sessionId)\r\n if (context && context.user.uid === user.uid) {\r\n // Update current session\r\n store.currentSession = context\r\n return context\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n static setSession(sessionId: string, user: User) {\r\n const store = this.getStore()\r\n store.sessions.set(sessionId, user)\r\n }\r\n\r\n static getSession(sessionId: string): User | null {\r\n const store = this.getStore()\r\n return store.sessions.get(sessionId) || null\r\n }\r\n\r\n static debug() {\r\n const store = this.getStore()\r\n return {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession,\r\n contexts: Array.from(store.contexts.entries()),\r\n sessions: Array.from(store.sessions.entries())\r\n }\r\n }\r\n\r\n static cleanup() {\r\n const store = this.getStore()\r\n const MAX_ENTRIES = 1000\r\n \r\n if (store.contexts.size > MAX_ENTRIES) {\r\n const keys = Array.from(store.contexts.keys())\r\n const toDelete = keys.slice(0, keys.length - MAX_ENTRIES)\r\n \r\n toDelete.forEach(key => {\r\n store.contexts.delete(key)\r\n store.sessions.delete(key)\r\n })\r\n }\r\n }\r\n}\r\n\r\n\r\nexport const setRequestHeadersOnNextResponse = (\r\n res: NextResponse | Response,\r\n req: Request,\r\n newHeaders: Record<string, string>,\r\n) => {\r\n if (!res.headers.get(OVERRIDE_HEADERS)) {\r\n // Emulate a user setting overrides by explicitly adding the required nextjs headers\r\n // https://github.com/vercel/next.js/pull/41380\r\n // @ts-expect-error -- property keys does not exist on type Headers\r\n res.headers.set(OVERRIDE_HEADERS, [...req.headers.keys()]);\r\n req.headers.forEach((val, key) => {\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n }\r\n\r\n // Now that we have normalised res to include overrides, just append the new header\r\n Object.entries(newHeaders).forEach(([key, val]) => {\r\n res.headers.set(OVERRIDE_HEADERS, `${res.headers.get(OVERRIDE_HEADERS)},${key}`);\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n};\r\n\r\nexport function decorateRequest(\r\n req: TernSecureRequest,\r\n res: Response,\r\n requestState: RequestState,\r\n appCheckToken?: string,\r\n): Response {\r\n const { reason, token, status } = requestState;\r\n // pass-through case, convert to next()\r\n if (!res) {\r\n res = NextResponse.next();\r\n }\r\n\r\n // redirect() case, return early\r\n if (res.headers.get(nextConstants.Headers.NextRedirect)) {\r\n return res;\r\n }\r\n\r\n let rewriteURL;\r\n\r\n // next() case, convert to a rewrite\r\n if (res.headers.get(nextConstants.Headers.NextResume) === '1') {\r\n res.headers.delete(nextConstants.Headers.NextResume);\r\n rewriteURL = new URL(req.url);\r\n }\r\n\r\n // rewrite() case, set auth result only if origin remains the same\r\n const rewriteURLHeader = res.headers.get(nextConstants.Headers.NextRewrite);\r\n\r\n if (rewriteURLHeader) {\r\n const reqURL = new URL(req.url);\r\n rewriteURL = new URL(rewriteURLHeader);\r\n\r\n // if the origin has changed, return early\r\n if (rewriteURL.origin !== reqURL.origin) {\r\n return res;\r\n }\r\n }\r\n\r\n if (rewriteURL) {\r\n setRequestHeadersOnNextResponse(res, req, {\r\n [constants.Headers.AuthStatus]: status,\r\n [constants.Headers.AuthToken]: token || '',\r\n [constants.Headers.AppCheckToken]: appCheckToken || req.headers.get(constants.Headers.AppCheckToken) || '',\r\n [constants.Headers.AuthReason]: reason || '',\r\n [constants.Headers.TernSecureUrl]: req.ternUrl.toString(),\r\n });\r\n res.headers.set(nextConstants.Headers.NextRewrite, rewriteURL.href);\r\n }\r\n\r\n return res;\r\n}\r\n\r\n\r\nexport const isPrerenderingBailout = (e: unknown) => {\r\n if (!(e instanceof Error) || !('message' in e)) {\r\n return false;\r\n }\r\n\r\n const { message } = e;\r\n\r\n const lowerCaseInput = message.toLowerCase();\r\n const dynamicServerUsage = lowerCaseInput.includes('dynamic server usage');\r\n const bailOutPrerendering = lowerCaseInput.includes('this page needs to bail out of prerendering');\r\n\r\n // note: new error message syntax introduced in next@14.1.1-canary.21\r\n // but we still want to support older versions.\r\n // https://github.com/vercel/next.js/pull/61332 (dynamic-rendering.ts:153)\r\n const routeRegex = /Route .*? needs to bail out of prerendering at this point because it used .*?./;\r\n\r\n return routeRegex.test(message) || dynamicServerUsage || bailOutPrerendering;\r\n};\r\n\r\nexport async function buildRequestLike(): Promise<NextRequest> {\r\n try {\r\n // Dynamically import next/headers, otherwise Next12 apps will break\r\n // @ts-expect-error: Cannot find module 'next/headers' or its corresponding type declarations.ts(2307)\r\n const { headers } = await import('next/headers');\r\n const resolvedHeaders = await headers();\r\n return new NextRequest('https://placeholder.com', { headers: resolvedHeaders });\r\n } catch (e: any) {\r\n // rethrow the error when react throws a prerendering bailout\r\n // https://nextjs.org/docs/messages/ppr-caught-error\r\n if (e && isPrerenderingBailout(e)) {\r\n throw e;\r\n }\r\n\r\n throw new Error(\r\n `TernSecure: auth(), currentUser() and ternSecureClient(), are only supported in App Router (/app directory).\\nIf you're using /pages, try getAuth() instead.\\nOriginal error: ${e}`,\r\n );\r\n }\r\n}\r\n\r\n// Original source: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/get-script-nonce-from-header.tsx\r\nexport function getScriptNonceFromHeader(cspHeaderValue: string): string | undefined {\r\n const directives = cspHeaderValue\r\n // Directives are split by ';'.\r\n .split(';')\r\n .map(directive => directive.trim());\r\n\r\n // First try to find the directive for the 'script-src', otherwise try to\r\n // fallback to the 'default-src'.\r\n const directive =\r\n directives.find(dir => dir.startsWith('script-src')) || directives.find(dir => dir.startsWith('default-src'));\r\n\r\n // If no directive could be found, then we're done.\r\n if (!directive) {\r\n return;\r\n }\r\n\r\n // Extract the nonce from the directive\r\n const nonce = directive\r\n .split(' ')\r\n // Remove the 'strict-src'/'default-src' string, this can't be the nonce.\r\n .slice(1)\r\n .map(source => source.trim())\r\n // Find the first source with the 'nonce-' prefix.\r\n .find(source => source.startsWith(\"'nonce-\") && source.length > 8 && source.endsWith(\"'\"))\r\n // Grab the nonce by trimming the 'nonce-' prefix.\r\n ?.slice(7, -1);\r\n\r\n // If we couldn't find the nonce, then we're done.\r\n if (!nonce) {\r\n return;\r\n }\r\n\r\n // Don't accept the nonce value if it contains HTML escape characters.\r\n // Technically, the spec requires a base64'd value, but this is just an\r\n // extra layer.\r\n if (/[&><\\u2028\\u2029]/g.test(nonce)) {\r\n throw new Error(\r\n 'Nonce value from Content-Security-Policy contained invalid HTML escape characters, which is disallowed for security reasons. Make sure that your nonce value does not contain the following characters: `<`, `>`, `&`',\r\n );\r\n }\r\n\r\n return nonce;\r\n}\r\n"],"mappings":"AAIA,SAAS,iBAAiB;AAC1B,SAAS,aAAY,oBAAoB;AAEzC,SAAS,aAAa,qBAAqB;AAG3C,MAAM,mBAAmB;AACzB,MAAM,2BAA2B;AAQjC,MAAM,kBAAkB,MAAM;AAC5B,MAAI,OAAO,YAAY,aAAa;AAClC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,MAAM,YAAY;AAEX,MAAM,MAAM;AAAA,EACjB,OAAe,WAAW;AACxB,UAAM,SAAS,gBAAgB;AAE/B,QAAI,CAAC,OAAO,SAAS,GAAG;AACtB,aAAO,SAAS,IAAI;AAAA,QAClB,UAAU,oBAAI,IAA4B;AAAA,QAC1C,UAAU,oBAAI,IAAkB;AAAA,QAChC,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA,EAEA,OAAO,WAAW,SAAyB;AACzC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,EAAE,MAAM,UAAU,IAAI;AAE5B,YAAQ,IAAI,2BAA2B,EAAE,WAAW,KAAK,CAAC;AAG1D,UAAM,SAAS,IAAI,WAAW,OAAO;AACrC,UAAM,SAAS,IAAI,WAAW,IAAI;AAGlC,UAAM,iBAAiB;AAEvB,YAAQ,IAAI,yBAAyB;AAAA,MACnC,cAAc,MAAM,SAAS;AAAA,MAC7B,cAAc,MAAM,SAAS;AAAA,MAC7B,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,aAAoC;AACzC,UAAM,QAAQ,KAAK,SAAS;AAG5B,QAAI,MAAM,gBAAgB;AACxB,YAAM,UAAU,KAAK,WAAW,MAAM,eAAe,SAAS;AAC9D,UAAI,WAAW,QAAQ,QAAQ,MAAM,eAAe,KAAK,KAAK;AAC5D,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAGA,eAAW,CAAC,WAAW,IAAI,KAAK,MAAM,SAAS,QAAQ,GAAG;AACxD,YAAM,UAAU,MAAM,SAAS,IAAI,SAAS;AAC5C,UAAI,WAAW,QAAQ,KAAK,QAAQ,KAAK,KAAK;AAE5C,cAAM,iBAAiB;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,WAAmB,MAAY;AAC/C,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,SAAS,IAAI,WAAW,IAAI;AAAA,EACpC;AAAA,EAEA,OAAO,WAAW,WAAgC;AAChD,UAAM,QAAQ,KAAK,SAAS;AAC5B,WAAO,MAAM,SAAS,IAAI,SAAS,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAO,QAAQ;AACb,UAAM,QAAQ,KAAK,SAAS;AAC5B,WAAO;AAAA,MACL,cAAc,MAAM,SAAS;AAAA,MAC7B,cAAc,MAAM,SAAS;AAAA,MAC7B,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM,KAAK,MAAM,SAAS,QAAQ,CAAC;AAAA,MAC7C,UAAU,MAAM,KAAK,MAAM,SAAS,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,UAAU;AACf,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,cAAc;AAEpB,QAAI,MAAM,SAAS,OAAO,aAAa;AACrC,YAAM,OAAO,MAAM,KAAK,MAAM,SAAS,KAAK,CAAC;AAC7C,YAAM,WAAW,KAAK,MAAM,GAAG,KAAK,SAAS,WAAW;AAExD,eAAS,QAAQ,SAAO;AACtB,cAAM,SAAS,OAAO,GAAG;AACzB,cAAM,SAAS,OAAO,GAAG;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAGO,MAAM,kCAAkC,CAC7C,KACA,KACA,eACG;AACH,MAAI,CAAC,IAAI,QAAQ,IAAI,gBAAgB,GAAG;AAItC,QAAI,QAAQ,IAAI,kBAAkB,CAAC,GAAG,IAAI,QAAQ,KAAK,CAAC,CAAC;AACzD,QAAI,QAAQ,QAAQ,CAAC,KAAK,QAAQ;AAChC,UAAI,QAAQ,IAAI,GAAG,wBAAwB,IAAI,GAAG,IAAI,GAAG;AAAA,IAC3D,CAAC;AAAA,EACH;AAGA,SAAO,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,GAAG,MAAM;AACjD,QAAI,QAAQ,IAAI,kBAAkB,GAAG,IAAI,QAAQ,IAAI,gBAAgB,CAAC,IAAI,GAAG,EAAE;AAC/E,QAAI,QAAQ,IAAI,GAAG,wBAAwB,IAAI,GAAG,IAAI,GAAG;AAAA,EAC3D,CAAC;AACH;AAEO,SAAS,gBACd,KACA,KACA,cACA,eACU;AACV,QAAM,EAAE,QAAQ,OAAO,OAAO,IAAI;AAElC,MAAI,CAAC,KAAK;AACR,UAAM,aAAa,KAAK;AAAA,EAC1B;AAGA,MAAI,IAAI,QAAQ,IAAI,cAAc,QAAQ,YAAY,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,MAAI;AAGJ,MAAI,IAAI,QAAQ,IAAI,cAAc,QAAQ,UAAU,MAAM,KAAK;AAC7D,QAAI,QAAQ,OAAO,cAAc,QAAQ,UAAU;AACnD,iBAAa,IAAI,IAAI,IAAI,GAAG;AAAA,EAC9B;AAGA,QAAM,mBAAmB,IAAI,QAAQ,IAAI,cAAc,QAAQ,WAAW;AAE1E,MAAI,kBAAkB;AACpB,UAAM,SAAS,IAAI,IAAI,IAAI,GAAG;AAC9B,iBAAa,IAAI,IAAI,gBAAgB;AAGrC,QAAI,WAAW,WAAW,OAAO,QAAQ;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,YAAY;AACd,oCAAgC,KAAK,KAAK;AAAA,MACxC,CAAC,UAAU,QAAQ,UAAU,GAAG;AAAA,MAChC,CAAC,UAAU,QAAQ,SAAS,GAAG,SAAS;AAAA,MACxC,CAAC,UAAU,QAAQ,aAAa,GAAG,iBAAiB,IAAI,QAAQ,IAAI,UAAU,QAAQ,aAAa,KAAK;AAAA,MACxG,CAAC,UAAU,QAAQ,UAAU,GAAG,UAAU;AAAA,MAC1C,CAAC,UAAU,QAAQ,aAAa,GAAG,IAAI,QAAQ,SAAS;AAAA,IAC1D,CAAC;AACD,QAAI,QAAQ,IAAI,cAAc,QAAQ,aAAa,WAAW,IAAI;AAAA,EACpE;AAEA,SAAO;AACT;AAGO,MAAM,wBAAwB,CAAC,MAAe;AACnD,MAAI,EAAE,aAAa,UAAU,EAAE,aAAa,IAAI;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,QAAQ,IAAI;AAEpB,QAAM,iBAAiB,QAAQ,YAAY;AAC3C,QAAM,qBAAqB,eAAe,SAAS,sBAAsB;AACzE,QAAM,sBAAsB,eAAe,SAAS,6CAA6C;AAKjG,QAAM,aAAa;AAEnB,SAAO,WAAW,KAAK,OAAO,KAAK,sBAAsB;AAC3D;AAEA,eAAsB,mBAAyC;AAC7D,MAAI;AAGF,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,cAAc;AAC/C,UAAM,kBAAkB,MAAM,QAAQ;AACtC,WAAO,IAAI,YAAY,2BAA2B,EAAE,SAAS,gBAAgB,CAAC;AAAA,EAChF,SAAS,GAAQ;AAGf,QAAI,KAAK,sBAAsB,CAAC,GAAG;AACjC,YAAM;AAAA,IACR;AAEA,UAAM,IAAI;AAAA,MACR;AAAA;AAAA,kBAAiL,CAAC;AAAA,IACpL;AAAA,EACF;AACF;AAGO,SAAS,yBAAyB,gBAA4C;AACnF,QAAM,aAAa,eAEhB,MAAM,GAAG,EACT,IAAI,CAAAA,eAAaA,WAAU,KAAK,CAAC;AAIpC,QAAM,YACJ,WAAW,KAAK,SAAO,IAAI,WAAW,YAAY,CAAC,KAAK,WAAW,KAAK,SAAO,IAAI,WAAW,aAAa,CAAC;AAG9G,MAAI,CAAC,WAAW;AACd;AAAA,EACF;AAGA,QAAM,QAAQ,UACX,MAAM,GAAG,EAET,MAAM,CAAC,EACP,IAAI,YAAU,OAAO,KAAK,CAAC,EAE3B,KAAK,YAAU,OAAO,WAAW,SAAS,KAAK,OAAO,SAAS,KAAK,OAAO,SAAS,GAAG,CAAC,GAEvF,MAAM,GAAG,EAAE;AAGf,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAKA,MAAI,qBAAqB,KAAK,KAAK,GAAG;AACpC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":["directive"]}
@@ -1,5 +1,6 @@
1
1
  const allNextProviderPropsWithEnv = (nextProps) => {
2
2
  const {
3
+ tenantId,
3
4
  signInUrl,
4
5
  signUpUrl,
5
6
  signInForceRedirectUrl,
@@ -13,11 +14,17 @@ const allNextProviderPropsWithEnv = (nextProps) => {
13
14
  enableServiceWorker: propsEnableServiceWorker,
14
15
  loadingComponent: propsLoadingComponent,
15
16
  persistence: propsPersistence,
17
+ ternUIUrl: propsTernUIUrl,
18
+ ternUIVersion: propsTernUIVersion,
19
+ appCheck,
16
20
  ...baseProps
17
21
  } = nextProps;
18
22
  const envConfig = {
23
+ tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || "",
19
24
  apiKey: process.env.NEXT_PUBLIC_TERN_API_KEY,
20
25
  apiUrl: process.env.TERNSECURE_API_URL || "",
26
+ ternUIUrl: process.env.NEXT_PUBLIC_TERN_UI_URL || "",
27
+ ternUIVersion: process.env.NEXT_PUBLIC_TERN_UI_VERSION || "",
21
28
  projectId: process.env.NEXT_PUBLIC_TERN_PROJECT_ID,
22
29
  customDomain: process.env.NEXT_PUBLIC_TERN_CUSTOM_DOMAIN,
23
30
  proxyUrl: process.env.NEXT_PUBLIC_TERN_PROXY_URL,
@@ -43,9 +50,9 @@ const allNextProviderPropsWithEnv = (nextProps) => {
43
50
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
44
51
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
45
52
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
46
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID,
47
- tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || ""
53
+ measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID || ""
48
54
  };
55
+ const finalTenantId = tenantId ?? envConfig.tenantId;
49
56
  const finalApiUrl = propsApiUrl ?? envConfig.apiUrl;
50
57
  const finalSignInUrl = signInUrl ?? envConfig.signInUrl;
51
58
  const finalSignUpUrl = signUpUrl ?? envConfig.signUpUrl;
@@ -54,16 +61,20 @@ const allNextProviderPropsWithEnv = (nextProps) => {
54
61
  const finalSignInFallbackRedirectUrl = signInFallbackRedirectUrl ?? envConfig.signInFallbackRedirectUrl;
55
62
  const finalSignUpFallbackRedirectUrl = signUpFallbackRedirectUrl ?? envConfig.signUpFallbackRedirectUrl;
56
63
  const finalPersistence = propsPersistence ?? envConfig.persistence;
64
+ const finalTernUIUrl = propsTernUIUrl ?? envConfig.ternUIUrl;
65
+ const finalTernUIVersion = propsTernUIVersion ?? envConfig.ternUIVersion;
57
66
  const result = {
58
67
  ...baseProps,
59
68
  // Set the Firebase configuration properties
60
69
  ternSecureConfig,
61
70
  // Set properties explicitly taken from TernSecureNextProps (props version)
62
71
  // These are part of the TernSecureProviderProps interface.
72
+ tenantId: finalTenantId,
63
73
  requiresVerification: propsRequiresVerification,
64
74
  isTernSecureDev: propsIsTernSecureDev,
65
75
  enableServiceWorker: propsEnableServiceWorker,
66
76
  loadingComponent: propsLoadingComponent,
77
+ appCheck,
67
78
  //TernSecure: baseProps.Instance,
68
79
  initialState: baseProps.initialState,
69
80
  bypassApiKey: baseProps.bypassApiKey,
@@ -75,7 +86,9 @@ const allNextProviderPropsWithEnv = (nextProps) => {
75
86
  signUpFallbackRedirectUrl: finalSignUpFallbackRedirectUrl,
76
87
  mode: baseProps.mode,
77
88
  apiUrl: finalApiUrl,
78
- persistence: finalPersistence
89
+ persistence: finalPersistence,
90
+ ternUIUrl: finalTernUIUrl,
91
+ ternUIVersion: finalTernUIVersion
79
92
  };
80
93
  Object.keys(result).forEach((key) => {
81
94
  if (result[key] === void 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/allNextProviderProps.ts"],"sourcesContent":["import type { \n IsoTernSecureAuthOptions,\n TernSecureProviderProps} from \"@tern-secure/react\";\n\nimport type { NextProviderProcessedProps, TernSecureNextProps } from \"../types\";\n\n\nexport const allNextProviderPropsWithEnv = (\n nextProps: Omit<TernSecureNextProps, 'children'>\n): any => {\n const {\n signInUrl,\n signUpUrl,\n signInForceRedirectUrl,\n signUpForceRedirectUrl,\n signInFallbackRedirectUrl,\n signUpFallbackRedirectUrl,\n //apiKey: propsApiKey,\n apiUrl: propsApiUrl,\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n persistence: propsPersistence,\n ...baseProps \n } = nextProps;\n\n const envConfig = {\n apiKey: process.env.NEXT_PUBLIC_TERN_API_KEY,\n apiUrl: process.env.TERNSECURE_API_URL || '',\n projectId: process.env.NEXT_PUBLIC_TERN_PROJECT_ID,\n customDomain: process.env.NEXT_PUBLIC_TERN_CUSTOM_DOMAIN,\n proxyUrl: process.env.NEXT_PUBLIC_TERN_PROXY_URL,\n environment: process.env.NEXT_PUBLIC_TERN_ENVIRONMENT,\n signInUrl: process.env.NEXT_PUBLIC_SIGN_IN_URL || '',\n signUpUrl: process.env.NEXT_PUBLIC_SIGN_UP_URL || '',\n signInForceRedirectUrl: process.env.NEXT_PUBLIC_SIGN_IN_FORCE_REDIRECT_URL || '',\n signUpForceRedirectUrl: process.env.NEXT_PUBLIC_SIGN_UP_FORCE_REDIRECT_URL || '',\n signInFallbackRedirectUrl: process.env.NEXT_PUBLIC_SIGN_IN_FALLBACK_REDIRECT_URL || '',\n signUpFallbackRedirectUrl: process.env.NEXT_PUBLIC_SIGN_UP_FALLBACK_REDIRECT_URL || '',\n persistence: process.env.NEXT_PUBLIC_TERN_PERSISTENCE as 'local' | 'session' | 'browserCookie' | 'none',\n useEmulator: process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR,\n projectIdAdmin: process.env.FIREBASE_PROJECT_ID,\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL,\n privateKey: process.env.FIREBASE_PRIVATE_KEY,\n };\n\n const ternSecureConfig = {\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\n databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL || '',\n appName: process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || '',\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID,\n tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || '',\n };\n\n // Merge config values: props take precedence over environment variables\n //const finalApiKey = propsApiKey ?? envConfig.apiKey;\n const finalApiUrl = propsApiUrl ?? envConfig.apiUrl;\n const finalSignInUrl = signInUrl ?? envConfig.signInUrl;\n const finalSignUpUrl = signUpUrl ?? envConfig.signUpUrl;\n const finalSignInForceRedirectUrl = signInForceRedirectUrl ?? envConfig.signInForceRedirectUrl;\n const finalSignUpForceRedirectUrl = signUpForceRedirectUrl ?? envConfig.signUpForceRedirectUrl;\n const finalSignInFallbackRedirectUrl = signInFallbackRedirectUrl ?? envConfig.signInFallbackRedirectUrl;\n const finalSignUpFallbackRedirectUrl = signUpFallbackRedirectUrl ?? envConfig.signUpFallbackRedirectUrl;\n const finalPersistence = propsPersistence ?? envConfig.persistence;\n\n // Construct the result, ensuring it conforms to NextProviderProcessedProps\n // (Omit<TernSecureProviderProps, 'children'>)\n const result: NextProviderProcessedProps = {\n ...(baseProps as Omit<TernSecureProviderProps, 'children' | keyof IsoTernSecureAuthOptions | 'requiresVerification' | 'loadingComponent'>),\n\n // Set the Firebase configuration properties\n ternSecureConfig,\n \n // Set properties explicitly taken from TernSecureNextProps (props version)\n // These are part of the TernSecureProviderProps interface.\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n\n //TernSecure: baseProps.Instance,\n initialState: baseProps.initialState,\n bypassApiKey: baseProps.bypassApiKey,\n signInUrl: finalSignInUrl,\n signUpUrl: finalSignUpUrl,\n signInForceRedirectUrl: finalSignInForceRedirectUrl,\n signUpForceRedirectUrl: finalSignUpForceRedirectUrl,\n signInFallbackRedirectUrl: finalSignInFallbackRedirectUrl,\n signUpFallbackRedirectUrl: finalSignUpFallbackRedirectUrl,\n mode: baseProps.mode,\n apiUrl: finalApiUrl,\n persistence: finalPersistence\n };\n\n // Clean up undefined keys that might have resulted from spreading if not present in baseProps\n // and also not set by merged values (e.g. if env var is also undefined)\n Object.keys(result).forEach(key => {\n if (result[key as keyof NextProviderProcessedProps] === undefined) {\n delete result[key as keyof NextProviderProcessedProps];\n }\n });\n\n return result;\n};"],"mappings":"AAOO,MAAM,8BAA8B,CACzC,cACQ;AACR,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,YAAY;AAAA,IAChB,QAAQ,QAAQ,IAAI;AAAA,IACpB,QAAQ,QAAQ,IAAI,sBAAsB;AAAA,IAC1C,WAAW,QAAQ,IAAI;AAAA,IACvB,cAAc,QAAQ,IAAI;AAAA,IAC1B,UAAU,QAAQ,IAAI;AAAA,IACtB,aAAa,QAAQ,IAAI;AAAA,IACzB,WAAW,QAAQ,IAAI,2BAA2B;AAAA,IAClD,WAAW,QAAQ,IAAI,2BAA2B;AAAA,IAClD,wBAAwB,QAAQ,IAAI,0CAA0C;AAAA,IAC9E,wBAAwB,QAAQ,IAAI,0CAA0C;AAAA,IAC9E,2BAA2B,QAAQ,IAAI,6CAA6C;AAAA,IACpF,2BAA2B,QAAQ,IAAI,6CAA6C;AAAA,IACpF,aAAa,QAAQ,IAAI;AAAA,IACzB,aAAa,QAAQ,IAAI;AAAA,IACzB,gBAAgB,QAAQ,IAAI;AAAA,IAC5B,aAAa,QAAQ,IAAI;AAAA,IACzB,YAAY,QAAQ,IAAI;AAAA,EAC1B;AAEA,QAAM,mBAAmB;AAAA,IACvB,QAAQ,QAAQ,IAAI,gCAAgC;AAAA,IACpD,YAAY,QAAQ,IAAI,oCAAoC;AAAA,IAC5D,aAAa,QAAQ,IAAI,qCAAqC;AAAA,IAC9D,SAAS,QAAQ,IAAI,iCAAiC;AAAA,IACtD,WAAW,QAAQ,IAAI,mCAAmC;AAAA,IAC1D,eAAe,QAAQ,IAAI,uCAAuC;AAAA,IAClE,mBAAmB,QAAQ,IAAI,4CAA4C;AAAA,IAC3E,OAAO,QAAQ,IAAI,+BAA+B;AAAA,IAClD,eAAe,QAAQ,IAAI;AAAA,IAC3B,UAAU,QAAQ,IAAI,kCAAkC;AAAA,EAC1D;AAIA,QAAM,cAAc,eAAe,UAAU;AAC7C,QAAM,iBAAiB,aAAa,UAAU;AAC9C,QAAM,iBAAiB,aAAa,UAAU;AAC9C,QAAM,8BAA8B,0BAA0B,UAAU;AACxE,QAAM,8BAA8B,0BAA0B,UAAU;AACxE,QAAM,iCAAiC,6BAA6B,UAAU;AAC9E,QAAM,iCAAiC,6BAA6B,UAAU;AAC9E,QAAM,mBAAmB,oBAAoB,UAAU;AAIvD,QAAM,SAAqC;AAAA,IACzC,GAAI;AAAA;AAAA,IAGJ;AAAA;AAAA;AAAA,IAIA,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA;AAAA,IAGlB,cAAc,UAAU;AAAA,IACxB,cAAc,UAAU;AAAA,IACxB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,2BAA2B;AAAA,IAC3B,2BAA2B;AAAA,IAC3B,MAAM,UAAU;AAAA,IAChB,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAIA,SAAO,KAAK,MAAM,EAAE,QAAQ,SAAO;AACjC,QAAI,OAAO,GAAuC,MAAM,QAAW;AACjE,aAAO,OAAO,GAAuC;AAAA,IACvD;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/allNextProviderProps.ts"],"sourcesContent":["import type { \n IsoTernSecureAuthOptions,\n TernSecureProviderProps} from \"@tern-secure/react\";\n\nimport type { NextProviderProcessedProps, TernSecureNextProps } from \"../types\";\n\n\nexport const allNextProviderPropsWithEnv = (\n nextProps: Omit<TernSecureNextProps, 'children'>\n): any => {\n const {\n tenantId,\n signInUrl,\n signUpUrl,\n signInForceRedirectUrl,\n signUpForceRedirectUrl,\n signInFallbackRedirectUrl,\n signUpFallbackRedirectUrl,\n //apiKey: propsApiKey,\n apiUrl: propsApiUrl,\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n persistence: propsPersistence,\n ternUIUrl: propsTernUIUrl,\n ternUIVersion: propsTernUIVersion,\n appCheck,\n ...baseProps \n } = nextProps;\n\n const envConfig = {\n tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || '',\n apiKey: process.env.NEXT_PUBLIC_TERN_API_KEY,\n apiUrl: process.env.TERNSECURE_API_URL || '',\n ternUIUrl: process.env.NEXT_PUBLIC_TERN_UI_URL || '',\n ternUIVersion: process.env.NEXT_PUBLIC_TERN_UI_VERSION || '',\n projectId: process.env.NEXT_PUBLIC_TERN_PROJECT_ID,\n customDomain: process.env.NEXT_PUBLIC_TERN_CUSTOM_DOMAIN,\n proxyUrl: process.env.NEXT_PUBLIC_TERN_PROXY_URL,\n environment: process.env.NEXT_PUBLIC_TERN_ENVIRONMENT,\n signInUrl: process.env.NEXT_PUBLIC_SIGN_IN_URL || '',\n signUpUrl: process.env.NEXT_PUBLIC_SIGN_UP_URL || '',\n signInForceRedirectUrl: process.env.NEXT_PUBLIC_SIGN_IN_FORCE_REDIRECT_URL || '',\n signUpForceRedirectUrl: process.env.NEXT_PUBLIC_SIGN_UP_FORCE_REDIRECT_URL || '',\n signInFallbackRedirectUrl: process.env.NEXT_PUBLIC_SIGN_IN_FALLBACK_REDIRECT_URL || '',\n signUpFallbackRedirectUrl: process.env.NEXT_PUBLIC_SIGN_UP_FALLBACK_REDIRECT_URL || '',\n persistence: process.env.NEXT_PUBLIC_TERN_PERSISTENCE as 'local' | 'session' | 'browserCookie' | 'none',\n useEmulator: process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR,\n projectIdAdmin: process.env.FIREBASE_PROJECT_ID,\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL,\n privateKey: process.env.FIREBASE_PRIVATE_KEY,\n };\n\n const ternSecureConfig = {\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\n databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL || '',\n appName: process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || '',\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID || '',\n };\n\n // Merge config values: props take precedence over environment variables\n //const finalApiKey = propsApiKey ?? envConfig.apiKey;\n const finalTenantId = tenantId ?? envConfig.tenantId;\n const finalApiUrl = propsApiUrl ?? envConfig.apiUrl;\n const finalSignInUrl = signInUrl ?? envConfig.signInUrl;\n const finalSignUpUrl = signUpUrl ?? envConfig.signUpUrl;\n const finalSignInForceRedirectUrl = signInForceRedirectUrl ?? envConfig.signInForceRedirectUrl;\n const finalSignUpForceRedirectUrl = signUpForceRedirectUrl ?? envConfig.signUpForceRedirectUrl;\n const finalSignInFallbackRedirectUrl = signInFallbackRedirectUrl ?? envConfig.signInFallbackRedirectUrl;\n const finalSignUpFallbackRedirectUrl = signUpFallbackRedirectUrl ?? envConfig.signUpFallbackRedirectUrl;\n const finalPersistence = propsPersistence ?? envConfig.persistence;\n const finalTernUIUrl = propsTernUIUrl ?? envConfig.ternUIUrl;\n const finalTernUIVersion = propsTernUIVersion ?? envConfig.ternUIVersion;\n\n // Construct the result, ensuring it conforms to NextProviderProcessedProps\n // (Omit<TernSecureProviderProps, 'children'>)\n const result: NextProviderProcessedProps = {\n ...(baseProps as Omit<TernSecureProviderProps, 'children' | keyof IsoTernSecureAuthOptions | 'requiresVerification' | 'loadingComponent'>),\n\n // Set the Firebase configuration properties\n ternSecureConfig,\n \n // Set properties explicitly taken from TernSecureNextProps (props version)\n // These are part of the TernSecureProviderProps interface.\n tenantId: finalTenantId,\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n appCheck,\n\n //TernSecure: baseProps.Instance,\n initialState: baseProps.initialState,\n bypassApiKey: baseProps.bypassApiKey,\n signInUrl: finalSignInUrl,\n signUpUrl: finalSignUpUrl,\n signInForceRedirectUrl: finalSignInForceRedirectUrl,\n signUpForceRedirectUrl: finalSignUpForceRedirectUrl,\n signInFallbackRedirectUrl: finalSignInFallbackRedirectUrl,\n signUpFallbackRedirectUrl: finalSignUpFallbackRedirectUrl,\n mode: baseProps.mode,\n apiUrl: finalApiUrl,\n persistence: finalPersistence,\n ternUIUrl: finalTernUIUrl,\n ternUIVersion: finalTernUIVersion\n };\n\n // Clean up undefined keys that might have resulted from spreading if not present in baseProps\n // and also not set by merged values (e.g. if env var is also undefined)\n Object.keys(result).forEach(key => {\n if (result[key as keyof NextProviderProcessedProps] === undefined) {\n delete result[key as keyof NextProviderProcessedProps];\n }\n });\n\n return result;\n};"],"mappings":"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","names":[]}