@tern-secure/nextjs 3.4.3 → 4.1.0

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 (96) hide show
  1. package/dist/cjs/app-router/client/TernSecureProvider.js +17 -2
  2. package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
  3. package/dist/cjs/app-router/client/actions.js +55 -55
  4. package/dist/cjs/app-router/client/actions.js.map +1 -1
  5. package/dist/cjs/app-router/route-handler/internal-route.js +22 -3
  6. package/dist/cjs/app-router/route-handler/internal-route.js.map +1 -1
  7. package/dist/cjs/boundary/TernSecureClientProvider.js +167 -34
  8. package/dist/cjs/boundary/TernSecureClientProvider.js.map +1 -1
  9. package/dist/cjs/boundary/TernSecureCtx.js.map +1 -1
  10. package/dist/cjs/boundary/hooks/useAuth.js +15 -2
  11. package/dist/cjs/boundary/hooks/useAuth.js.map +1 -1
  12. package/dist/cjs/components/sign-in.js +158 -35
  13. package/dist/cjs/components/sign-in.js.map +1 -1
  14. package/dist/cjs/components/sign-out-button.js +84 -0
  15. package/dist/cjs/components/sign-out-button.js.map +1 -0
  16. package/dist/cjs/components/sign-out.js +39 -9
  17. package/dist/cjs/components/sign-out.js.map +1 -1
  18. package/dist/cjs/components/sign-up.js +10 -5
  19. package/dist/cjs/components/sign-up.js.map +1 -1
  20. package/dist/cjs/errors.js +233 -5
  21. package/dist/cjs/errors.js.map +1 -1
  22. package/dist/cjs/index.js +3 -3
  23. package/dist/cjs/index.js.map +1 -1
  24. package/dist/cjs/types.js +14 -0
  25. package/dist/cjs/types.js.map +1 -1
  26. package/dist/cjs/utils/construct.js +50 -18
  27. package/dist/cjs/utils/construct.js.map +1 -1
  28. package/dist/cjs/utils/redirect.js +57 -0
  29. package/dist/cjs/utils/redirect.js.map +1 -0
  30. package/dist/esm/app-router/client/TernSecureProvider.js +17 -2
  31. package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
  32. package/dist/esm/app-router/client/actions.js +64 -56
  33. package/dist/esm/app-router/client/actions.js.map +1 -1
  34. package/dist/esm/app-router/route-handler/internal-route.js +18 -2
  35. package/dist/esm/app-router/route-handler/internal-route.js.map +1 -1
  36. package/dist/esm/boundary/TernSecureClientProvider.js +168 -35
  37. package/dist/esm/boundary/TernSecureClientProvider.js.map +1 -1
  38. package/dist/esm/boundary/TernSecureCtx.js.map +1 -1
  39. package/dist/esm/boundary/hooks/useAuth.js +15 -2
  40. package/dist/esm/boundary/hooks/useAuth.js.map +1 -1
  41. package/dist/esm/components/sign-in.js +160 -37
  42. package/dist/esm/components/sign-in.js.map +1 -1
  43. package/dist/esm/components/sign-out-button.js +60 -0
  44. package/dist/esm/components/sign-out-button.js.map +1 -0
  45. package/dist/esm/components/sign-out.js +30 -10
  46. package/dist/esm/components/sign-out.js.map +1 -1
  47. package/dist/esm/components/sign-up.js +10 -5
  48. package/dist/esm/components/sign-up.js.map +1 -1
  49. package/dist/esm/errors.js +229 -4
  50. package/dist/esm/errors.js.map +1 -1
  51. package/dist/esm/index.js +2 -2
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/esm/types.js +6 -0
  54. package/dist/esm/types.js.map +1 -1
  55. package/dist/esm/utils/construct.js +46 -17
  56. package/dist/esm/utils/construct.js.map +1 -1
  57. package/dist/esm/utils/redirect.js +32 -0
  58. package/dist/esm/utils/redirect.js.map +1 -0
  59. package/dist/types/app-router/client/TernSecureProvider.d.ts +14 -3
  60. package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
  61. package/dist/types/app-router/client/actions.d.ts +24 -18
  62. package/dist/types/app-router/client/actions.d.ts.map +1 -1
  63. package/dist/types/app-router/route-handler/internal-route.d.ts +8 -1
  64. package/dist/types/app-router/route-handler/internal-route.d.ts.map +1 -1
  65. package/dist/types/boundary/TernSecureClientProvider.d.ts +17 -1
  66. package/dist/types/boundary/TernSecureClientProvider.d.ts.map +1 -1
  67. package/dist/types/boundary/TernSecureCtx.d.ts +3 -8
  68. package/dist/types/boundary/TernSecureCtx.d.ts.map +1 -1
  69. package/dist/types/boundary/hooks/useAuth.d.ts +6 -1
  70. package/dist/types/boundary/hooks/useAuth.d.ts.map +1 -1
  71. package/dist/types/components/sign-in.d.ts.map +1 -1
  72. package/dist/types/components/sign-out-button.d.ts +14 -0
  73. package/dist/types/components/sign-out-button.d.ts.map +1 -0
  74. package/dist/types/components/sign-out.d.ts +7 -5
  75. package/dist/types/components/sign-out.d.ts.map +1 -1
  76. package/dist/types/components/sign-up.d.ts +4 -0
  77. package/dist/types/components/sign-up.d.ts.map +1 -1
  78. package/dist/types/components/ui/alert.d.ts +1 -1
  79. package/dist/types/components/ui/button.d.ts +1 -1
  80. package/dist/types/errors.d.ts +37 -2
  81. package/dist/types/errors.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +1 -1
  83. package/dist/types/index.d.ts.map +1 -1
  84. package/dist/types/types.d.ts +45 -0
  85. package/dist/types/types.d.ts.map +1 -1
  86. package/dist/types/utils/construct.d.ts +20 -4
  87. package/dist/types/utils/construct.d.ts.map +1 -1
  88. package/dist/types/utils/redirect.d.ts +9 -0
  89. package/dist/types/utils/redirect.d.ts.map +1 -0
  90. package/package.json +6 -6
  91. package/dist/cjs/boundary/hooks/useUser.js +0 -44
  92. package/dist/cjs/boundary/hooks/useUser.js.map +0 -1
  93. package/dist/esm/boundary/hooks/useUser.js +0 -20
  94. package/dist/esm/boundary/hooks/useUser.js.map +0 -1
  95. package/dist/types/boundary/hooks/useUser.d.ts +0 -7
  96. package/dist/types/boundary/hooks/useUser.d.ts.map +0 -1
@@ -20,44 +20,76 @@ var construct_exports = {};
20
20
  __export(construct_exports, {
21
21
  constructFullUrl: () => constructFullUrl,
22
22
  constructUrlWithRedirect: () => constructUrlWithRedirect,
23
- getValidRedirectUrl: () => getValidRedirectUrl
23
+ getPreviousPath: () => getPreviousPath,
24
+ getValidRedirectUrl: () => getValidRedirectUrl,
25
+ hasRedirectLoop: () => hasRedirectLoop,
26
+ storePreviousPath: () => storePreviousPath
24
27
  });
25
28
  module.exports = __toCommonJS(construct_exports);
29
+ var import_internal_route = require("../app-router/route-handler/internal-route");
26
30
  const constructFullUrl = (path) => {
31
+ if (typeof window === "undefined") return path;
27
32
  const baseUrl = window.location.origin;
28
33
  if (path.startsWith("http")) {
29
34
  return path;
30
35
  }
31
36
  return `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
32
37
  };
33
- const constructUrlWithRedirect = (path, redirectUrl, loginPath) => {
34
- const url = new URL(path, window.location.origin);
35
- if (redirectUrl && !redirectUrl.startsWith(loginPath)) {
36
- const fullRedirectUrl = redirectUrl.startsWith("http") ? redirectUrl : constructFullUrl(redirectUrl);
37
- url.searchParams.set("redirect_url", fullRedirectUrl);
38
+ const hasRedirectLoop = (currentPath, redirectPath) => {
39
+ if (!currentPath || !redirectPath) return false;
40
+ const cleanCurrentPath = currentPath.split("?")[0];
41
+ const cleanRedirectPath = redirectPath.split("?")[0];
42
+ return cleanCurrentPath === cleanRedirectPath;
43
+ };
44
+ const constructUrlWithRedirect = (path, redirectUrl) => {
45
+ const url = new URL(path, typeof window !== "undefined" ? window.location.origin : void 0);
46
+ if (redirectUrl && !(0, import_internal_route.isAuthRoute)(redirectUrl) && !(0, import_internal_route.isInternalRoute)(redirectUrl)) {
47
+ url.searchParams.set("redirect", redirectUrl);
38
48
  }
39
49
  return url.toString();
40
50
  };
41
- const getValidRedirectUrl = (redirectUrl, searchParams) => {
42
- const redirect = redirectUrl || searchParams.get("redirect_url") || "/";
51
+ const storePreviousPath = (path) => {
52
+ if (typeof window !== "undefined" && !(0, import_internal_route.isAuthRoute)(path)) {
53
+ sessionStorage.setItem("previousPath", path);
54
+ }
55
+ };
56
+ const getPreviousPath = () => {
57
+ if (typeof window !== "undefined") {
58
+ return sessionStorage.getItem("previousPath");
59
+ }
60
+ return null;
61
+ };
62
+ const getValidRedirectUrl = (searchParams, configuredRedirect) => {
63
+ const urlRedirect = searchParams.get("redirect");
64
+ if (urlRedirect) {
65
+ return validateUrl(urlRedirect);
66
+ }
67
+ if (configuredRedirect) {
68
+ return validateUrl(configuredRedirect);
69
+ }
70
+ return "/";
71
+ };
72
+ const validateUrl = (url) => {
43
73
  try {
44
- if (redirect.startsWith("http")) {
45
- const url = new URL(redirect);
46
- if (url.origin === window.location.origin) {
47
- return redirect;
74
+ if (url.startsWith("http")) {
75
+ const urlObj = new URL(url);
76
+ if (typeof window !== "undefined" && urlObj.origin !== window.location.origin) {
77
+ return "/";
48
78
  }
49
- return "/";
79
+ return !(0, import_internal_route.isAuthRoute)(urlObj.pathname) && !(0, import_internal_route.isInternalRoute)(urlObj.pathname) ? urlObj.pathname : "/";
50
80
  }
51
- return constructFullUrl(redirect);
52
- } catch (e) {
53
- console.error("Invalid redirect URL:", e);
54
- return constructFullUrl("/");
81
+ return !(0, import_internal_route.isAuthRoute)(url) && !(0, import_internal_route.isInternalRoute)(url) ? url : "/";
82
+ } catch {
83
+ return "/";
55
84
  }
56
85
  };
57
86
  // Annotate the CommonJS export names for ESM import in node:
58
87
  0 && (module.exports = {
59
88
  constructFullUrl,
60
89
  constructUrlWithRedirect,
61
- getValidRedirectUrl
90
+ getPreviousPath,
91
+ getValidRedirectUrl,
92
+ hasRedirectLoop,
93
+ storePreviousPath
62
94
  });
63
95
  //# sourceMappingURL=construct.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["/**\n * Constructs a full URL with the current origin\n * @param path - The path to construct the URL for\n * @returns The full URL with origin\n */\nexport const constructFullUrl = (path: string) => {\n const baseUrl = window.location.origin\n if (path.startsWith('http')) {\n return path\n }\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n }\n \n /**\n * Constructs a URL with redirect parameters\n * @param path - The base path (usually login path)\n * @param redirectUrl - The URL to redirect to after action completes\n * @param loginPath - The login path to check against\n * @returns The full URL with redirect parameters\n */\n export const constructUrlWithRedirect = (path: string, redirectUrl: string, loginPath: string) => {\n // Create the URL with the full origin\n const url = new URL(path, window.location.origin)\n \n // Add redirect parameter if provided and not redirecting to login\n if (redirectUrl && !redirectUrl.startsWith(loginPath)) {\n // Ensure redirect URL is also absolute if it's not already\n const fullRedirectUrl = redirectUrl.startsWith('http') \n ? redirectUrl \n : constructFullUrl(redirectUrl)\n \n url.searchParams.set('redirect_url', fullRedirectUrl)\n }\n \n return url.toString()\n }\n \n /**\n * Gets a validated redirect URL ensuring it's from the same origin\n * @param redirectUrl - The URL to validate\n * @param searchParams - The search parameters to check for redirect_url\n * @returns A validated redirect URL\n */\n export const getValidRedirectUrl = (\n redirectUrl: string | undefined,\n searchParams: URLSearchParams\n ): string => {\n const redirect = redirectUrl || searchParams.get('redirect_url') || '/'\n \n try {\n if (redirect.startsWith('http')) {\n const url = new URL(redirect)\n if (url.origin === window.location.origin) {\n return redirect\n }\n return '/'\n }\n return constructFullUrl(redirect)\n } catch (e) {\n console.error('Invalid redirect URL:', e)\n return constructFullUrl('/')\n }\n }\n \n "],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,MAAM,mBAAmB,CAAC,SAAiB;AAC9C,QAAM,UAAU,OAAO,SAAS;AAChC,MAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC9D;AASO,MAAM,2BAA2B,CAAC,MAAc,aAAqB,cAAsB;AAEhG,QAAM,MAAM,IAAI,IAAI,MAAM,OAAO,SAAS,MAAM;AAGhD,MAAI,eAAe,CAAC,YAAY,WAAW,SAAS,GAAG;AAErD,UAAM,kBAAkB,YAAY,WAAW,MAAM,IACjD,cACA,iBAAiB,WAAW;AAEhC,QAAI,aAAa,IAAI,gBAAgB,eAAe;AAAA,EACtD;AAEA,SAAO,IAAI,SAAS;AACtB;AAQO,MAAM,sBAAsB,CACjC,aACA,iBACW;AACX,QAAM,WAAW,eAAe,aAAa,IAAI,cAAc,KAAK;AAEpE,MAAI;AACF,QAAI,SAAS,WAAW,MAAM,GAAG;AAC/B,YAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,UAAI,IAAI,WAAW,OAAO,SAAS,QAAQ;AACzC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AACA,WAAO,iBAAiB,QAAQ;AAAA,EAClC,SAAS,GAAG;AACV,YAAQ,MAAM,yBAAyB,CAAC;AACxC,WAAO,iBAAiB,GAAG;AAAA,EAC7B;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["//v2: redict with taking priority from the sign-in page\n\nimport { isInternalRoute, isAuthRoute } from \"../app-router/route-handler/internal-route\"\n\n/**\n * Constructs a full URL with the current origin\n * @param path - The path to construct the URL for\n * @returns The full URL with origin\n */\nexport const constructFullUrl = (path: string) => {\n if (typeof window === \"undefined\") return path\n const baseUrl = window.location.origin\n if (path.startsWith('http')) {\n return path\n }\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`\n }\n\n\n/**\n * Checks if the current URL has a redirect loop\n * @param currentPath - The current pathname\n * @param redirectPath - The path we're trying to redirect to\n * @returns boolean indicating if there's a redirect loop\n */\nexport const hasRedirectLoop = (currentPath: string, redirectPath: string): boolean => {\n if (!currentPath || !redirectPath) return false\n\n // Remove any query parameters for comparison\n const cleanCurrentPath = currentPath.split(\"?\")[0]\n const cleanRedirectPath = redirectPath.split(\"?\")[0]\n\n return cleanCurrentPath === cleanRedirectPath\n}\n \n/**\n * Constructs a URL with redirect parameters while preventing loops\n * @param path - The base path (usually login path)\n * @param redirectUrl - The URL to redirect to after action completes\n * @param loginPath - The login path to check against\n * @param signUpPath - The sign up path to check against\n * @returns The full URL with redirect parameters\n */\nexport const constructUrlWithRedirect = (\n path: string,\n redirectUrl: string | undefined,\n): string => {\n const url = new URL(path, typeof window !== \"undefined\" ? window.location.origin : undefined)\n \n if (redirectUrl && !isAuthRoute(redirectUrl) && !isInternalRoute(redirectUrl)) {\n url.searchParams.set(\"redirect\", redirectUrl)\n }\n \n return url.toString()\n}\n\n/**\n * Stores the current path before signing out\n */\nexport const storePreviousPath = (path: string): void => {\n if (typeof window !== \"undefined\" && !isAuthRoute(path)) {\n sessionStorage.setItem(\"previousPath\", path)\n }\n}\n\n/**\n * Gets the stored previous path\n */\nexport const getPreviousPath = (): string | null => {\n if (typeof window !== \"undefined\") {\n return sessionStorage.getItem(\"previousPath\")\n }\n return null\n}\n\n\n \n/**\n * Gets a validated redirect URL ensuring it's from the same origin\n * @param redirectUrl - The URL to validate\n * @param searchParams - The search parameters to check for redirect\n * @returns A validated redirect URL\n */\nexport const getValidRedirectUrl = (\n searchParams: URLSearchParams,\n configuredRedirect?: string,\n): string => {\n // Check URL search param first (highest priority)\n const urlRedirect = searchParams.get(\"redirect\")\n if (urlRedirect) {\n return validateUrl(urlRedirect)\n }\n\n // Then check configured redirect (for first visits)\n if (configuredRedirect) {\n return validateUrl(configuredRedirect)\n }\n\n // Default fallback\n return \"/\"\n}\n\n/**\n * Validates and sanitizes URLs\n */\nconst validateUrl = (url: string): string => {\n try {\n // For absolute URLs\n if (url.startsWith(\"http\")) {\n const urlObj = new URL(url)\n if (typeof window !== \"undefined\" && urlObj.origin !== window.location.origin) {\n return \"/\"\n }\n return !isAuthRoute(urlObj.pathname) && !isInternalRoute(urlObj.pathname) \n ? urlObj.pathname \n : \"/\"\n }\n \n // For relative URLs\n return !isAuthRoute(url) && !isInternalRoute(url) ? url : \"/\"\n } catch {\n return \"/\"\n }\n}\n\n\n\n\n\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,4BAA6C;AAOtC,MAAM,mBAAmB,CAAC,SAAiB;AAChD,MAAI,OAAO,WAAW,YAAa,QAAO;AACxC,QAAM,UAAU,OAAO,SAAS;AAChC,MAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC9D;AASK,MAAM,kBAAkB,CAAC,aAAqB,iBAAkC;AACrF,MAAI,CAAC,eAAe,CAAC,aAAc,QAAO;AAG1C,QAAM,mBAAmB,YAAY,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,oBAAoB,aAAa,MAAM,GAAG,EAAE,CAAC;AAEnD,SAAO,qBAAqB;AAC9B;AAUO,MAAM,2BAA2B,CACtC,MACA,gBACW;AACX,QAAM,MAAM,IAAI,IAAI,MAAM,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS,MAAS;AAE5F,MAAI,eAAe,KAAC,mCAAY,WAAW,KAAK,KAAC,uCAAgB,WAAW,GAAG;AAC7E,QAAI,aAAa,IAAI,YAAY,WAAW;AAAA,EAC9C;AAEA,SAAO,IAAI,SAAS;AACtB;AAKO,MAAM,oBAAoB,CAAC,SAAuB;AACvD,MAAI,OAAO,WAAW,eAAe,KAAC,mCAAY,IAAI,GAAG;AACvD,mBAAe,QAAQ,gBAAgB,IAAI;AAAA,EAC7C;AACF;AAKO,MAAM,kBAAkB,MAAqB;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,eAAe,QAAQ,cAAc;AAAA,EAC9C;AACA,SAAO;AACT;AAUO,MAAM,sBAAsB,CACjC,cACA,uBACW;AAEX,QAAM,cAAc,aAAa,IAAI,UAAU;AAC/C,MAAI,aAAa;AACf,WAAO,YAAY,WAAW;AAAA,EAChC;AAGA,MAAI,oBAAoB;AACtB,WAAO,YAAY,kBAAkB;AAAA,EACvC;AAGA,SAAO;AACT;AAKA,MAAM,cAAc,CAAC,QAAwB;AAC3C,MAAI;AAEF,QAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,YAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAI,OAAO,WAAW,eAAe,OAAO,WAAW,OAAO,SAAS,QAAQ;AAC7E,eAAO;AAAA,MACT;AACA,aAAO,KAAC,mCAAY,OAAO,QAAQ,KAAK,KAAC,uCAAgB,OAAO,QAAQ,IACpE,OAAO,WACP;AAAA,IACN;AAGA,WAAO,KAAC,mCAAY,GAAG,KAAK,KAAC,uCAAgB,GAAG,IAAI,MAAM;AAAA,EAC5D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var redirect_exports = {};
20
+ __export(redirect_exports, {
21
+ getCurrentPath: () => getCurrentPath,
22
+ validateRedirectUrl: () => validateRedirectUrl
23
+ });
24
+ module.exports = __toCommonJS(redirect_exports);
25
+ var import_headers = require("next/headers");
26
+ async function validateRedirectUrl(url) {
27
+ if (!url) return "/";
28
+ try {
29
+ if (url.startsWith("/")) {
30
+ const validPaths = ["/"];
31
+ return validPaths.includes(url) ? url : "/";
32
+ }
33
+ const headersList = await (0, import_headers.headers)();
34
+ const currentHost = headersList.get("host");
35
+ const urlObj = new URL(url);
36
+ if (urlObj.host === currentHost) {
37
+ return urlObj.pathname;
38
+ }
39
+ } catch {
40
+ }
41
+ return "/";
42
+ }
43
+ async function getCurrentPath() {
44
+ try {
45
+ const headersList = await (0, import_headers.headers)();
46
+ const pathname = headersList.get("x-pathname") || "/";
47
+ return pathname;
48
+ } catch {
49
+ return "/";
50
+ }
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ getCurrentPath,
55
+ validateRedirectUrl
56
+ });
57
+ //# sourceMappingURL=redirect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/redirect.ts"],"sourcesContent":["import { headers } from \"next/headers\"\n\n/**\n * Validates and sanitizes redirect URLs\n */\nexport async function validateRedirectUrl(url: string | null): Promise<string> {\n if (!url) return \"/\"\n\n try {\n // Check if it's a relative path\n if (url.startsWith(\"/\")) {\n // Basic validation to ensure the path exists in your app\n // Add more paths as needed\n const validPaths = [\"/\"]\n return validPaths.includes(url) ? url : \"/\"\n }\n\n // If it's an absolute URL, ensure it's from your domain\n const headersList = await headers()\n const currentHost = headersList.get(\"host\")\n const urlObj = new URL(url)\n if (urlObj.host === currentHost) {\n return urlObj.pathname\n }\n } catch {\n // Invalid URL format\n }\n\n return \"/\"\n}\n\n/**\n * Gets the current path for redirect purposes\n */\nexport async function getCurrentPath(): Promise<string> {\n try {\n const headersList = await headers()\n const pathname = headersList.get(\"x-pathname\") || \"/\"\n return pathname\n } catch {\n return \"/\"\n }\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwB;AAKxB,eAAsB,oBAAoB,KAAqC;AAC7E,MAAI,CAAC,IAAK,QAAO;AAEjB,MAAI;AAEF,QAAI,IAAI,WAAW,GAAG,GAAG;AAGvB,YAAM,aAAa,CAAC,GAAG;AACvB,aAAO,WAAW,SAAS,GAAG,IAAI,MAAM;AAAA,IAC1C;AAGC,UAAM,cAAc,UAAM,wBAAQ;AACnC,UAAM,cAAc,YAAY,IAAI,MAAM;AAC1C,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,QAAI,OAAO,SAAS,aAAa;AAC/B,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAKA,eAAsB,iBAAkC;AACtD,MAAI;AACF,UAAM,cAAc,UAAM,wBAAQ;AAClC,UAAM,WAAW,YAAY,IAAI,YAAY,KAAK;AAClD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -1,7 +1,22 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { TernSecureClientProvider } from "../../boundary/TernSecureClientProvider";
3
- async function TernSecureProvider({ children }) {
4
- return /* @__PURE__ */ jsx(TernSecureClientProvider, { children });
3
+ async function TernSecureProvider({
4
+ children,
5
+ requiresVerification = true,
6
+ loginPath,
7
+ signUpPath,
8
+ loadingComponent
9
+ }) {
10
+ return /* @__PURE__ */ jsx(
11
+ TernSecureClientProvider,
12
+ {
13
+ requiresVerification,
14
+ loginPath,
15
+ signUpPath,
16
+ loadingComponent,
17
+ children
18
+ }
19
+ );
5
20
  }
6
21
  export {
7
22
  TernSecureProvider
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["import React from \"react\"\nimport { TernSecureClientProvider } from \"../../boundary/TernSecureClientProvider\"\n\n\n// Loading fallback component\n/*function TernSecureLoadingFallback() {\n return (\n <div>\n <span className=\"sr-only\">Loading...</span>\n </div>\n )\n}*/\n/**\n * Root Provider for TernSecure\n * Use this in your Next.js App Router root layout\n * Automatically handles client/server boundary and authentication state\n * \n * @example\n * /// app/layout.tsx\n * import { TernSecureProvider } from '@tern/secure'\n * \n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <TernSecureProvider>\n * {children}\n * </TernSecureProvider>\n * </body>\n * </html>\n * )\n * }\n */\nexport async function TernSecureProvider({ children }: { children: React.ReactNode }) {\n return (\n <TernSecureClientProvider>\n {children}\n </TernSecureClientProvider>\n )\n}"],"mappings":"AAmCI;AAlCJ,SAAS,gCAAgC;AAgCzC,eAAsB,mBAAmB,EAAE,SAAS,GAAkC;AACpF,SACE,oBAAC,4BACI,UACL;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["import React from \"react\"\nimport { TernSecureClientProvider } from \"../../boundary/TernSecureClientProvider\"\n\n\n/**\n * Configuration options for TernSecure authentication\n */\nexport interface TernSecureConfig {\n /** Whether email verification is required (defaults to true) */\n requiresVerification?: boolean\n /** Custom path for login page (defaults to /sign-in) */\n loginPath?: string\n /** Custom path for signup page (defaults to /sign-up) */\n signUpPath?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n}\n\n// Loading fallback component\n/*function TernSecureLoadingFallback() {\n return (\n <div>\n <span className=\"sr-only\">Loading...</span>\n </div>\n )\n}*/\n/**\n * Root Provider for TernSecure\n * Use this in your Next.js App Router root layout\n * Automatically handles client/server boundary and authentication state\n * \n * @example\n * /// app/layout.tsx\n * import { TernSecureProvider } from '@tern/secure'\n * \n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <TernSecureProvider>\n * {children}\n * </TernSecureProvider>\n * </body>\n * </html>\n * )\n * }\n */\nexport async function TernSecureProvider({ \n children,\n requiresVerification = true,\n loginPath,\n signUpPath,\n loadingComponent,\n }: React.PropsWithChildren<TernSecureConfig>) {\n return (\n <TernSecureClientProvider\n requiresVerification={requiresVerification}\n loginPath={loginPath}\n signUpPath={signUpPath}\n loadingComponent={loadingComponent}\n >\n {children}\n </TernSecureClientProvider>\n )\n}"],"mappings":"AAuDI;AAtDJ,SAAS,gCAAgC;AA8CzC,eAAsB,mBAAmB;AAAA,EACvC;AAAA,EACA,uBAAuB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACD,GAA8C;AAC7C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEG;AAAA;AAAA,EACL;AAEJ;","names":[]}
@@ -1,6 +1,14 @@
1
1
  import { TernSecureAuth } from "../../utils/client-init";
2
- import { signInWithEmailAndPassword, signInWithRedirect, getRedirectResult, GoogleAuthProvider, OAuthProvider, createUserWithEmailAndPassword, sendEmailVerification } from "firebase/auth";
3
- import { createSessionCookie } from "../server/sessionTernSecure";
2
+ import {
3
+ signInWithEmailAndPassword,
4
+ signInWithRedirect,
5
+ getRedirectResult,
6
+ GoogleAuthProvider,
7
+ OAuthProvider,
8
+ createUserWithEmailAndPassword,
9
+ sendEmailVerification
10
+ } from "firebase/auth";
11
+ import { handleFirebaseAuthError } from "../../errors";
4
12
  async function createUser(email, password) {
5
13
  const auth = TernSecureAuth();
6
14
  try {
@@ -10,43 +18,40 @@ async function createUser(email, password) {
10
18
  };
11
19
  const userCredential = await createUserWithEmailAndPassword(auth, email, password);
12
20
  await sendEmailVerification(userCredential.user, actionCodeSettings);
13
- return { success: true, message: "Account created successfully.", user: userCredential.user };
21
+ return {
22
+ success: true,
23
+ message: "Account created successfully. Please check your email for verification",
24
+ user: userCredential.user
25
+ };
14
26
  } catch (error) {
15
- if (error instanceof Error) {
16
- switch (error.message) {
17
- case "auth/too-many-requests":
18
- throw new Error("Too many attempts. Please try again later.");
19
- case "auth/network-request-failed":
20
- throw new Error("Network disconnected. Please try again later.");
21
- case "auth/email-already-in-use":
22
- throw new Error("Email is already registered.");
23
- case "auth/invalid-email":
24
- throw new Error("Invalid email address.");
25
- case "auth/operation-not-allowed":
26
- throw new Error("Email/password accounts are not enabled.");
27
- case "auth/weak-password":
28
- throw new Error("Password is too weak.");
29
- default:
30
- throw new Error(error.message);
31
- }
32
- }
33
- throw new Error("Failed to create account");
27
+ const authError = handleFirebaseAuthError(error);
28
+ return {
29
+ success: false,
30
+ message: authError.message,
31
+ error: authError.code,
32
+ user: null
33
+ };
34
34
  }
35
35
  }
36
36
  async function signInWithEmail(email, password) {
37
37
  const auth = TernSecureAuth();
38
38
  try {
39
39
  const UserCredential = await signInWithEmailAndPassword(auth, email, password);
40
- const idToken = await UserCredential.user.getIdToken();
41
- const res = await createSessionCookie(idToken);
42
- if (res.success) {
43
- return { success: true, message: "Connected." };
44
- } else {
45
- throw new Error(res.message);
46
- }
40
+ const user = UserCredential.user;
41
+ return {
42
+ success: true,
43
+ message: "Authentication successful",
44
+ user,
45
+ error: !user.emailVerified ? "REQUIRES_VERIFICATION" : "AUTHENTICATED"
46
+ };
47
47
  } catch (error) {
48
- const errorMessage = error instanceof Error ? error.message : "Failed to sign in";
49
- throw new Error(errorMessage);
48
+ const authError = handleFirebaseAuthError(error);
49
+ return {
50
+ success: false,
51
+ message: authError.message,
52
+ error: authError.code,
53
+ user: null
54
+ };
50
55
  }
51
56
  }
52
57
  async function signInWithRedirectGoogle() {
@@ -60,8 +65,13 @@ async function signInWithRedirectGoogle() {
60
65
  await signInWithRedirect(auth, provider);
61
66
  return { success: true, message: "Redirect initiated" };
62
67
  } catch (error) {
63
- console.error("Error during Google sign-in:", error);
64
- return { success: false, error: "Failed to sign in with Google" };
68
+ const authError = handleFirebaseAuthError(error);
69
+ return {
70
+ success: false,
71
+ message: authError.message,
72
+ error: authError.code,
73
+ user: null
74
+ };
65
75
  }
66
76
  }
67
77
  async function signInWithMicrosoft() {
@@ -74,8 +84,13 @@ async function signInWithMicrosoft() {
74
84
  await signInWithRedirect(auth, provider);
75
85
  return { success: true, message: "Redirect initiated" };
76
86
  } catch (error) {
77
- console.error("Error during Google sign-in:", error);
78
- return { success: false, error: "Failed to sign in with Google" };
87
+ const authError = handleFirebaseAuthError(error);
88
+ return {
89
+ success: false,
90
+ message: authError.message,
91
+ error: authError.code,
92
+ user: null
93
+ };
79
94
  }
80
95
  }
81
96
  async function handleAuthRedirectResult() {
@@ -89,8 +104,13 @@ async function handleAuthRedirectResult() {
89
104
  return { success: false, error: "No redirect result" };
90
105
  }
91
106
  } catch (error) {
92
- console.error("Error handling auth redirect result:", error);
93
- return { success: false, error: error.message || "Failed to handle auth redirect", code: error.code };
107
+ const authError = handleFirebaseAuthError(error);
108
+ return {
109
+ success: false,
110
+ message: authError.message,
111
+ error: authError.code,
112
+ user: null
113
+ };
94
114
  }
95
115
  }
96
116
  async function resendEmailVerification() {
@@ -119,25 +139,13 @@ async function resendEmailVerification() {
119
139
  isVerified: false
120
140
  };
121
141
  } catch (error) {
122
- if (error instanceof Error) {
123
- switch (error.message) {
124
- case "auth/too-many-requests":
125
- throw new Error("Too many attempts. Please try again later.");
126
- case "auth/network-request-failed":
127
- throw new Error("Network disconnected. Please try again later.");
128
- case "auth/email-already-in-use":
129
- throw new Error("Email is already registered.");
130
- case "auth/invalid-email":
131
- throw new Error("Invalid email address.");
132
- case "auth/operation-not-allowed":
133
- throw new Error("Email/password accounts are not enabled.");
134
- case "auth/weak-password":
135
- throw new Error("Password is too weak.");
136
- default:
137
- throw new Error(error.message);
138
- }
139
- }
140
- throw new Error("Failed to resend verification email.");
142
+ const authError = handleFirebaseAuthError(error);
143
+ return {
144
+ success: false,
145
+ message: authError.message,
146
+ error: authError.code,
147
+ user: null
148
+ };
141
149
  }
142
150
  }
143
151
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/client/actions.ts"],"sourcesContent":["import { TernSecureAuth } from '../../utils/client-init'\nimport { signInWithEmailAndPassword, signInWithRedirect, getRedirectResult, GoogleAuthProvider, OAuthProvider, createUserWithEmailAndPassword, sendEmailVerification } from 'firebase/auth'\nimport { createSessionCookie } from '../server/sessionTernSecure'\n\nexport async function createUser(email: string, password: string) {\n const auth = TernSecureAuth()\n try {\n \n const actionCodeSettings = {\n url: `${window.location.origin}/sign-in`,\n handleCodeInApp: true\n };\n\n const userCredential = await createUserWithEmailAndPassword(auth, email, password);\n\n await sendEmailVerification(userCredential.user, actionCodeSettings)\n \n return { success: true, message: 'Account created successfully.', user: userCredential.user };\n\n } catch (error) {\n // Handle specific Firebase auth errors\n if (error instanceof Error) {\n switch (error.message) {\n case 'auth/too-many-requests':\n throw new Error('Too many attempts. Please try again later.');\n case 'auth/network-request-failed':\n throw new Error('Network disconnected. Please try again later.');\n case 'auth/email-already-in-use':\n throw new Error('Email is already registered.');\n case 'auth/invalid-email':\n throw new Error('Invalid email address.');\n case 'auth/operation-not-allowed':\n throw new Error('Email/password accounts are not enabled.');\n case 'auth/weak-password':\n throw new Error('Password is too weak.');\n default:\n throw new Error(error.message);\n }\n }\n throw new Error('Failed to create account');\n }\n}\n\n\nexport async function signInWithEmail(email: string, password: string){\n const auth = TernSecureAuth()\n try {\n const UserCredential = await signInWithEmailAndPassword(auth, email, password)\n const idToken = await UserCredential.user.getIdToken();\n\n const res = await createSessionCookie(idToken);\n\n if(res.success) {\n return { success: true, message: 'Connected.' };\n } else {\n throw new Error(res.message);\n }\n} catch (error){\n const errorMessage = error instanceof Error ? error.message : 'Failed to sign in';\n throw new Error(errorMessage);\n}\n} \n\nexport async function signInWithRedirectGoogle() {\n const auth = TernSecureAuth()\n const provider = new GoogleAuthProvider()\n provider.setCustomParameters({\n login_hint: 'user@example.com',\n prompt: 'select_account'\n })\n\n try {\n await signInWithRedirect(auth, provider)\n return { success: true, message: 'Redirect initiated' }\n } catch (error) {\n console.error('Error during Google sign-in:', error)\n return { success: false, error: 'Failed to sign in with Google' }\n }\n}\n\n\nexport async function signInWithMicrosoft() {\n const auth = TernSecureAuth()\n const provider = new OAuthProvider('microsoft.com')\n provider.setCustomParameters({\n prompt: 'consent'\n })\n\n try {\n await signInWithRedirect(auth, provider)\n return { success: true, message: 'Redirect initiated' }\n } catch (error) {\n console.error('Error during Google sign-in:', error)\n return { success: false, error: 'Failed to sign in with Google' }\n }\n}\n\n\nexport async function handleAuthRedirectResult() {\n const auth = TernSecureAuth()\n try {\n const result = await getRedirectResult(auth)\n if (result) {\n const user = result.user\n return { success: true, user }\n } else {\n return { success: false, error: 'No redirect result' }\n }\n } catch (error: any) {\n console.error('Error handling auth redirect result:', error)\n return { success: false, error: error.message || 'Failed to handle auth redirect', code: error.code }\n }\n}\n\n\nexport async function resendEmailVerification() {\n const auth = TernSecureAuth()\n try {\n const user = auth.currentUser;\n if (!user) {\n throw new Error('No user found. Please try signing up again.');\n }\n\n await user.reload();\n\n if (user.emailVerified) {\n return { \n success: true, \n message: 'Email is already verified. You can sign in.',\n isVerified: true \n };\n }\n\n const actionCodeSettings = {\n url: `${window.location.origin}/sign-in`,\n handleCodeInApp: true,\n };\n\n await sendEmailVerification(user, actionCodeSettings);\n return { \n success: true, \n message: 'Verification email sent successfully.',\n isVerified: false\n };\n } catch (error) {\n if (error instanceof Error) {\n switch (error.message) {\n case 'auth/too-many-requests':\n throw new Error('Too many attempts. Please try again later.');\n case 'auth/network-request-failed':\n throw new Error('Network disconnected. Please try again later.');\n case 'auth/email-already-in-use':\n throw new Error('Email is already registered.');\n case 'auth/invalid-email':\n throw new Error('Invalid email address.');\n case 'auth/operation-not-allowed':\n throw new Error('Email/password accounts are not enabled.');\n case 'auth/weak-password':\n throw new Error('Password is too weak.');\n default:\n throw new Error(error.message);\n }\n }\n throw new Error('Failed to resend verification email.');\n }\n}"],"mappings":"AAAA,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B,oBAAoB,mBAAmB,oBAAoB,eAAe,gCAAgC,6BAA6B;AAC5K,SAAS,2BAA2B;AAEpC,eAAsB,WAAW,OAAe,UAAkB;AAChE,QAAM,OAAO,eAAe;AAC5B,MAAI;AAEF,UAAM,qBAAqB;AAAA,MACzB,KAAK,GAAG,OAAO,SAAS,MAAM;AAAA,MAC9B,iBAAiB;AAAA,IACnB;AAEA,UAAM,iBAAiB,MAAM,+BAA+B,MAAM,OAAO,QAAQ;AAEjF,UAAM,sBAAsB,eAAe,MAAM,kBAAkB;AAEnE,WAAO,EAAE,SAAS,MAAM,SAAS,iCAAiC,MAAM,eAAe,KAAK;AAAA,EAE9F,SAAS,OAAO;AAEd,QAAI,iBAAiB,OAAO;AAC1B,cAAQ,MAAM,SAAS;AAAA,QACrB,KAAK;AACH,gBAAM,IAAI,MAAM,4CAA4C;AAAA,QAC9D,KAAK;AACD,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACnE,KAAK;AACH,gBAAM,IAAI,MAAM,8BAA8B;AAAA,QAChD,KAAK;AACH,gBAAM,IAAI,MAAM,wBAAwB;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D,KAAK;AACH,gBAAM,IAAI,MAAM,uBAAuB;AAAA,QACzC;AACE,gBAAM,IAAI,MAAM,MAAM,OAAO;AAAA,MACjC;AAAA,IACF;AACA,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AACF;AAGA,eAAsB,gBAAgB,OAAe,UAAiB;AACpE,QAAM,OAAO,eAAe;AAC5B,MAAI;AACJ,UAAM,iBAAiB,MAAM,2BAA2B,MAAM,OAAO,QAAQ;AAC7E,UAAM,UAAU,MAAM,eAAe,KAAK,WAAW;AAErD,UAAM,MAAM,MAAM,oBAAoB,OAAO;AAE7C,QAAG,IAAI,SAAS;AACd,aAAO,EAAE,SAAS,MAAM,SAAS,aAAa;AAAA,IAChD,OAAO;AACL,YAAM,IAAI,MAAM,IAAI,OAAO;AAAA,IAC7B;AAAA,EACF,SAAS,OAAM;AACb,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,UAAM,IAAI,MAAM,YAAY;AAAA,EAC9B;AACA;AAEA,eAAsB,2BAA2B;AAC/C,QAAM,OAAO,eAAe;AAC5B,QAAM,WAAW,IAAI,mBAAmB;AACxC,WAAS,oBAAoB;AAAA,IAC3B,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV,CAAC;AAED,MAAI;AACF,UAAM,mBAAmB,MAAM,QAAQ;AACvC,WAAO,EAAE,SAAS,MAAM,SAAS,qBAAqB;AAAA,EACxD,SAAS,OAAO;AACd,YAAQ,MAAM,gCAAgC,KAAK;AACnD,WAAO,EAAE,SAAS,OAAO,OAAO,gCAAgC;AAAA,EAClE;AACF;AAGA,eAAsB,sBAAsB;AAC1C,QAAM,OAAO,eAAe;AAC5B,QAAM,WAAW,IAAI,cAAc,eAAe;AAClD,WAAS,oBAAoB;AAAA,IAC3B,QAAQ;AAAA,EACV,CAAC;AAED,MAAI;AACF,UAAM,mBAAmB,MAAM,QAAQ;AACvC,WAAO,EAAE,SAAS,MAAM,SAAS,qBAAqB;AAAA,EACxD,SAAS,OAAO;AACd,YAAQ,MAAM,gCAAgC,KAAK;AACnD,WAAO,EAAE,SAAS,OAAO,OAAO,gCAAgC;AAAA,EAClE;AACF;AAGA,eAAsB,2BAA2B;AAC/C,QAAM,OAAO,eAAe;AAC5B,MAAI;AACF,UAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,QAAI,QAAQ;AACV,YAAM,OAAO,OAAO;AACpB,aAAO,EAAE,SAAS,MAAM,KAAK;AAAA,IAC/B,OAAO;AACL,aAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB;AAAA,IACvD;AAAA,EACF,SAAS,OAAY;AACnB,YAAQ,MAAM,wCAAwC,KAAK;AAC3D,WAAO,EAAE,SAAS,OAAO,OAAO,MAAM,WAAW,kCAAkC,MAAM,MAAM,KAAK;AAAA,EACtG;AACF;AAGA,eAAsB,0BAA0B;AAC9C,QAAM,OAAO,eAAe;AAC5B,MAAI;AACF,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,UAAM,KAAK,OAAO;AAElB,QAAI,KAAK,eAAe;AACtB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,qBAAqB;AAAA,MACzB,KAAK,GAAG,OAAO,SAAS,MAAM;AAAA,MAC9B,iBAAiB;AAAA,IACnB;AAEA,UAAM,sBAAsB,MAAM,kBAAkB;AACpD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY;AAAA,IACb;AAAA,EACD,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,cAAQ,MAAM,SAAS;AAAA,QACrB,KAAK;AACH,gBAAM,IAAI,MAAM,4CAA4C;AAAA,QAC9D,KAAK;AACD,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACnE,KAAK;AACH,gBAAM,IAAI,MAAM,8BAA8B;AAAA,QAChD,KAAK;AACH,gBAAM,IAAI,MAAM,wBAAwB;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D,KAAK;AACH,gBAAM,IAAI,MAAM,uBAAuB;AAAA,QACzC;AACE,gBAAM,IAAI,MAAM,MAAM,OAAO;AAAA,MACjC;AAAA,IACF;AACA,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/client/actions.ts"],"sourcesContent":["import { TernSecureAuth } from '../../utils/client-init'\nimport { \n signInWithEmailAndPassword, \n signInWithRedirect, \n getRedirectResult, \n GoogleAuthProvider, \n OAuthProvider, \n createUserWithEmailAndPassword, \n sendEmailVerification } from 'firebase/auth'\nimport type { SignInResponse } from '../../types'\nimport { handleFirebaseAuthError } from '../../errors'\n\n\nexport async function createUser(email: string, password: string): Promise<SignInResponse> {\n const auth = TernSecureAuth()\n try {\n \n const actionCodeSettings = {\n url: `${window.location.origin}/sign-in`,\n handleCodeInApp: true\n };\n\n const userCredential = await createUserWithEmailAndPassword(auth, email, password);\n\n await sendEmailVerification(userCredential.user, actionCodeSettings)\n \n return { \n success: true, \n message: 'Account created successfully. Please check your email for verification', \n user: userCredential.user \n };\n\n } catch (error) {\n const authError = handleFirebaseAuthError(error)\n return { \n success: false, \n message: authError.message, \n error: authError.code,\n user: null\n }\n }\n}\n\n\nexport async function signInWithEmail(email: string, password: string): Promise<SignInResponse> {\n const auth = TernSecureAuth()\n try {\n const UserCredential = await signInWithEmailAndPassword(auth, email, password)\n const user = UserCredential.user\n \n return { \n success: true, \n message: 'Authentication successful',\n user: user,\n error: !user.emailVerified ? 'REQUIRES_VERIFICATION' : 'AUTHENTICATED'\n };\n\n} catch (error){\n const authError = handleFirebaseAuthError(error)\n return { \n success: false,\n message: authError.message,\n error: authError.code,\n user: null\n }\n}\n}\n\nexport async function signInWithRedirectGoogle() {\n const auth = TernSecureAuth()\n const provider = new GoogleAuthProvider()\n provider.setCustomParameters({\n login_hint: 'user@example.com',\n prompt: 'select_account'\n })\n\n try {\n await signInWithRedirect(auth, provider)\n return { success: true, message: 'Redirect initiated' }\n } catch (error) {\n const authError = handleFirebaseAuthError(error)\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null\n }\n }\n}\n\n\nexport async function signInWithMicrosoft() {\n const auth = TernSecureAuth()\n const provider = new OAuthProvider('microsoft.com')\n provider.setCustomParameters({\n prompt: 'consent'\n })\n\n try {\n await signInWithRedirect(auth, provider)\n return { success: true, message: 'Redirect initiated' }\n } catch (error) {\n const authError = handleFirebaseAuthError(error)\n return {\n success: false, \n message: authError.message,\n error: authError.code,\n user: null\n }\n }\n}\n\n\nexport async function handleAuthRedirectResult() {\n const auth = TernSecureAuth()\n try {\n const result = await getRedirectResult(auth)\n if (result) {\n const user = result.user\n return { success: true, user }\n } else {\n return { success: false, error: 'No redirect result' }\n }\n } catch (error: any) {\n const authError = handleFirebaseAuthError(error)\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null\n }\n }\n}\n\n\nexport async function resendEmailVerification() {\n const auth = TernSecureAuth()\n try {\n const user = auth.currentUser;\n if (!user) {\n throw new Error('No user found. Please try signing up again.');\n }\n\n await user.reload();\n\n if (user.emailVerified) {\n return { \n success: true, \n message: 'Email is already verified. You can sign in.',\n isVerified: true \n };\n }\n\n const actionCodeSettings = {\n url: `${window.location.origin}/sign-in`,\n handleCodeInApp: true,\n };\n\n await sendEmailVerification(user, actionCodeSettings);\n return { \n success: true, \n message: 'Verification email sent successfully.',\n isVerified: false\n };\n } catch (error) {\n const authError = handleFirebaseAuthError(error)\n return {\n success: false,\n message: authError.message,\n error: authError.code,\n user: null\n }\n }\n}"],"mappings":"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","names":[]}
@@ -1,10 +1,23 @@
1
1
  import { Verify } from "../../components/verify";
2
2
  const internalRoutes = {
3
- verify: {
3
+ signUpVerify: {
4
4
  pattern: /^\/sign-up\/verify$/,
5
5
  component: Verify
6
+ },
7
+ signInVerify: {
8
+ pattern: /^\/sign-in\/verify$/,
9
+ component: Verify
6
10
  }
7
11
  };
12
+ function isInternalRoute(pathname) {
13
+ return Object.values(internalRoutes).some((route) => route.pattern.test(pathname));
14
+ }
15
+ function isAuthRoute(pathname) {
16
+ return pathname.startsWith("/sign-in") || pathname.startsWith("/sign-up");
17
+ }
18
+ function isBaseAuthRoute(pathname) {
19
+ return pathname === "/sign-in" || pathname === "/sign-up";
20
+ }
8
21
  function handleInternalRoute(pathname) {
9
22
  for (const [key, route] of Object.entries(internalRoutes)) {
10
23
  if (route.pattern.test(pathname)) {
@@ -15,6 +28,9 @@ function handleInternalRoute(pathname) {
15
28
  }
16
29
  export {
17
30
  handleInternalRoute,
18
- internalRoutes
31
+ internalRoutes,
32
+ isAuthRoute,
33
+ isBaseAuthRoute,
34
+ isInternalRoute
19
35
  };
20
36
  //# sourceMappingURL=internal-route.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/route-handler/internal-route.tsx"],"sourcesContent":["import { Verify } from \"../../components/verify\"\n\n// Internal route mapping\nexport const internalRoutes = {\n verify: {\n pattern: /^\\/sign-up\\/verify$/,\n component: Verify,\n },\n}\n\n// Internal route handler\nexport function handleInternalRoute(pathname: string) {\n for (const [key, route] of Object.entries(internalRoutes)) {\n if (route.pattern.test(pathname)) {\n return route.component\n }\n }\n return null\n}\n\n"],"mappings":"AAAA,SAAS,cAAc;AAGhB,MAAM,iBAAiB;AAAA,EAC5B,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AACF;AAGO,SAAS,oBAAoB,UAAkB;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,QAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/route-handler/internal-route.tsx"],"sourcesContent":["import { Verify } from \"../../components/verify\"\n\n// Internal route mapping\nexport const internalRoutes = {\n signUpVerify: {\n pattern: /^\\/sign-up\\/verify$/,\n component: Verify,\n },\n signInVerify: {\n pattern: /^\\/sign-in\\/verify$/,\n component: Verify,\n },\n}\n\n// Check if path is an internal route\nexport function isInternalRoute(pathname: string): boolean {\n return Object.values(internalRoutes).some((route) => route.pattern.test(pathname))\n}\n\n// Check if path is within auth routes\nexport function isAuthRoute(pathname: string): boolean {\n return pathname.startsWith(\"/sign-in\") || pathname.startsWith(\"/sign-up\")\n}\n\n// Check if path is exactly the base auth route\nexport function isBaseAuthRoute(pathname: string): boolean {\n return pathname === \"/sign-in\" || pathname === \"/sign-up\"\n}\n\n// Internal route handler\nexport function handleInternalRoute(pathname: string) {\n for (const [key, route] of Object.entries(internalRoutes)) {\n if (route.pattern.test(pathname)) {\n return route.component\n }\n }\n return null\n}"],"mappings":"AAAA,SAAS,cAAc;AAGhB,MAAM,iBAAiB;AAAA,EAC5B,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAAA,EACA,cAAc;AAAA,IACZ,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AACF;AAGO,SAAS,gBAAgB,UAA2B;AACzD,SAAO,OAAO,OAAO,cAAc,EAAE,KAAK,CAAC,UAAU,MAAM,QAAQ,KAAK,QAAQ,CAAC;AACnF;AAGO,SAAS,YAAY,UAA2B;AACrD,SAAO,SAAS,WAAW,UAAU,KAAK,SAAS,WAAW,UAAU;AAC1E;AAGO,SAAS,gBAAgB,UAA2B;AACzD,SAAO,aAAa,cAAc,aAAa;AACjD;AAGO,SAAS,oBAAoB,UAAkB;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,QAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;","names":[]}