@tern-secure/nextjs 3.3.5 → 3.4.1

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 (197) hide show
  1. package/dist/cjs/app-router/client/TernSecureProvider.js +33 -0
  2. package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -0
  3. package/dist/cjs/app-router/client/actions.js +180 -0
  4. package/dist/cjs/app-router/client/actions.js.map +1 -0
  5. package/dist/cjs/app-router/route-handler/internal-route.js +45 -0
  6. package/dist/cjs/app-router/route-handler/internal-route.js.map +1 -0
  7. package/dist/cjs/app-router/server/auth.js +71 -0
  8. package/dist/cjs/app-router/server/auth.js.map +1 -0
  9. package/dist/cjs/app-router/server/index.js +42 -0
  10. package/dist/cjs/app-router/server/index.js.map +1 -0
  11. package/dist/cjs/app-router/server/sessionTernSecure.js +159 -0
  12. package/dist/cjs/app-router/server/sessionTernSecure.js.map +1 -0
  13. package/dist/cjs/app-router/server/ternSecureMiddleware.js +50 -0
  14. package/dist/cjs/app-router/server/ternSecureMiddleware.js.map +1 -0
  15. package/dist/cjs/boundary/TernSecureClientProvider.js +107 -0
  16. package/dist/cjs/boundary/TernSecureClientProvider.js.map +1 -0
  17. package/dist/cjs/boundary/TernSecureCtx.js +49 -0
  18. package/dist/cjs/boundary/TernSecureCtx.js.map +1 -0
  19. package/dist/cjs/boundary/hooks/useAuth.js +51 -0
  20. package/dist/cjs/boundary/hooks/useAuth.js.map +1 -0
  21. package/dist/cjs/boundary/hooks/useSignUp.js +40 -0
  22. package/dist/cjs/boundary/hooks/useSignUp.js.map +1 -0
  23. package/dist/cjs/boundary/hooks/useUser.js +44 -0
  24. package/dist/cjs/boundary/hooks/useUser.js.map +1 -0
  25. package/dist/cjs/components/background.js +65 -0
  26. package/dist/cjs/components/background.js.map +1 -0
  27. package/dist/cjs/components/sign-in.js +242 -0
  28. package/dist/cjs/components/sign-in.js.map +1 -0
  29. package/dist/cjs/components/sign-out.js +69 -0
  30. package/dist/cjs/components/sign-out.js.map +1 -0
  31. package/dist/cjs/components/sign-up.js +328 -0
  32. package/dist/cjs/components/sign-up.js.map +1 -0
  33. package/dist/cjs/components/ui/alert.js +88 -0
  34. package/dist/cjs/components/ui/alert.js.map +1 -0
  35. package/dist/cjs/components/ui/button.js +84 -0
  36. package/dist/cjs/components/ui/button.js.map +1 -0
  37. package/dist/cjs/components/ui/card.js +101 -0
  38. package/dist/cjs/components/ui/card.js.map +1 -0
  39. package/dist/cjs/components/ui/input.js +58 -0
  40. package/dist/cjs/components/ui/input.js.map +1 -0
  41. package/dist/cjs/components/ui/label.js +55 -0
  42. package/dist/cjs/components/ui/label.js.map +1 -0
  43. package/dist/cjs/components/ui/separator.js +59 -0
  44. package/dist/cjs/components/ui/separator.js.map +1 -0
  45. package/dist/cjs/components/verify.js +195 -0
  46. package/dist/cjs/components/verify.js.map +1 -0
  47. package/dist/cjs/errors.js +41 -0
  48. package/dist/cjs/errors.js.map +1 -0
  49. package/dist/cjs/index.js +59 -0
  50. package/dist/cjs/index.js.map +1 -0
  51. package/dist/cjs/lib/utils.d.js +17 -0
  52. package/dist/cjs/lib/utils.d.js.map +1 -0
  53. package/dist/cjs/lib/utils.js +33 -0
  54. package/dist/cjs/lib/utils.js.map +1 -0
  55. package/dist/cjs/types.js +17 -0
  56. package/dist/cjs/types.js.map +1 -0
  57. package/dist/cjs/utils/admin-init.js +57 -0
  58. package/dist/cjs/utils/admin-init.js.map +1 -0
  59. package/dist/cjs/utils/client-init.js +49 -0
  60. package/dist/cjs/utils/client-init.js.map +1 -0
  61. package/dist/cjs/utils/config.js +113 -0
  62. package/dist/cjs/utils/config.js.map +1 -0
  63. package/dist/cjs/utils/construct.js +63 -0
  64. package/dist/cjs/utils/construct.js.map +1 -0
  65. package/dist/cjs/utils/create-styles.js +149 -0
  66. package/dist/cjs/utils/create-styles.js.map +1 -0
  67. package/dist/esm/app-router/client/TernSecureProvider.js +9 -0
  68. package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -0
  69. package/dist/esm/app-router/client/actions.js +151 -0
  70. package/dist/esm/app-router/client/actions.js.map +1 -0
  71. package/dist/esm/app-router/route-handler/internal-route.js +20 -0
  72. package/dist/esm/app-router/route-handler/internal-route.js.map +1 -0
  73. package/dist/esm/app-router/server/auth.js +47 -0
  74. package/dist/esm/app-router/server/auth.js.map +1 -0
  75. package/dist/esm/app-router/server/index.js +13 -0
  76. package/dist/esm/app-router/server/index.js.map +1 -0
  77. package/dist/esm/app-router/server/sessionTernSecure.js +129 -0
  78. package/dist/esm/app-router/server/sessionTernSecure.js.map +1 -0
  79. package/dist/esm/app-router/server/ternSecureMiddleware.js +26 -0
  80. package/dist/esm/app-router/server/ternSecureMiddleware.js.map +1 -0
  81. package/dist/esm/boundary/TernSecureClientProvider.js +83 -0
  82. package/dist/esm/boundary/TernSecureClientProvider.js.map +1 -0
  83. package/dist/esm/boundary/TernSecureCtx.js +23 -0
  84. package/dist/esm/boundary/TernSecureCtx.js.map +1 -0
  85. package/dist/esm/boundary/hooks/useAuth.js +27 -0
  86. package/dist/esm/boundary/hooks/useAuth.js.map +1 -0
  87. package/dist/esm/boundary/hooks/useSignUp.js +16 -0
  88. package/dist/esm/boundary/hooks/useSignUp.js.map +1 -0
  89. package/dist/esm/boundary/hooks/useUser.js +20 -0
  90. package/dist/esm/boundary/hooks/useUser.js.map +1 -0
  91. package/dist/esm/components/background.js +41 -0
  92. package/dist/esm/components/background.js.map +1 -0
  93. package/dist/esm/components/sign-in.js +218 -0
  94. package/dist/esm/components/sign-in.js.map +1 -0
  95. package/dist/esm/components/sign-out.js +45 -0
  96. package/dist/esm/components/sign-out.js.map +1 -0
  97. package/dist/esm/components/sign-up.js +294 -0
  98. package/dist/esm/components/sign-up.js.map +1 -0
  99. package/dist/esm/components/ui/alert.js +52 -0
  100. package/dist/esm/components/ui/alert.js.map +1 -0
  101. package/dist/esm/components/ui/button.js +49 -0
  102. package/dist/esm/components/ui/button.js.map +1 -0
  103. package/dist/esm/components/ui/card.js +62 -0
  104. package/dist/esm/components/ui/card.js.map +1 -0
  105. package/dist/esm/components/ui/input.js +24 -0
  106. package/dist/esm/components/ui/input.js.map +1 -0
  107. package/dist/esm/components/ui/label.js +21 -0
  108. package/dist/esm/components/ui/label.js.map +1 -0
  109. package/dist/esm/components/ui/separator.js +25 -0
  110. package/dist/esm/components/ui/separator.js.map +1 -0
  111. package/dist/esm/components/verify.js +161 -0
  112. package/dist/esm/components/verify.js.map +1 -0
  113. package/dist/esm/errors.js +16 -0
  114. package/dist/esm/errors.js.map +1 -0
  115. package/dist/esm/index.js +24 -0
  116. package/dist/esm/index.js.map +1 -0
  117. package/dist/esm/lib/utils.d.js +1 -0
  118. package/dist/esm/lib/utils.d.js.map +1 -0
  119. package/dist/esm/lib/utils.js +9 -0
  120. package/dist/esm/lib/utils.js.map +1 -0
  121. package/dist/esm/types.js +1 -0
  122. package/dist/esm/types.js.map +1 -0
  123. package/dist/esm/utils/admin-init.js +22 -0
  124. package/dist/esm/utils/admin-init.js.map +1 -0
  125. package/dist/esm/utils/client-init.js +22 -0
  126. package/dist/esm/utils/client-init.js.map +1 -0
  127. package/dist/esm/utils/config.js +84 -0
  128. package/dist/esm/utils/config.js.map +1 -0
  129. package/dist/esm/utils/construct.js +37 -0
  130. package/dist/esm/utils/construct.js.map +1 -0
  131. package/dist/esm/utils/create-styles.js +123 -0
  132. package/dist/esm/utils/create-styles.js.map +1 -0
  133. package/dist/types/app-router/client/TernSecureProvider.d.ts +26 -0
  134. package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -0
  135. package/dist/types/app-router/client/actions.d.ts +49 -0
  136. package/dist/types/app-router/client/actions.d.ts.map +1 -0
  137. package/dist/types/app-router/route-handler/internal-route.d.ts +9 -0
  138. package/dist/types/app-router/route-handler/internal-route.d.ts.map +1 -0
  139. package/dist/types/app-router/server/auth.d.ts +7 -0
  140. package/dist/types/app-router/server/auth.d.ts.map +1 -0
  141. package/dist/types/app-router/server/index.d.ts +5 -0
  142. package/dist/types/app-router/server/index.d.ts.map +1 -0
  143. package/dist/types/app-router/server/sessionTernSecure.d.ts +37 -0
  144. package/dist/types/app-router/server/sessionTernSecure.d.ts.map +1 -0
  145. package/dist/types/app-router/server/ternSecureMiddleware.d.ts +7 -0
  146. package/dist/types/app-router/server/ternSecureMiddleware.d.ts.map +1 -0
  147. package/dist/types/boundary/TernSecureClientProvider.d.ts +11 -0
  148. package/dist/types/boundary/TernSecureClientProvider.d.ts.map +1 -0
  149. package/dist/types/boundary/TernSecureCtx.d.ts +17 -0
  150. package/dist/types/boundary/TernSecureCtx.d.ts.map +1 -0
  151. package/dist/types/boundary/hooks/useAuth.d.ts +11 -0
  152. package/dist/types/boundary/hooks/useAuth.d.ts.map +1 -0
  153. package/dist/types/boundary/hooks/useSignUp.d.ts +5 -0
  154. package/dist/types/boundary/hooks/useSignUp.d.ts.map +1 -0
  155. package/dist/types/boundary/hooks/useUser.d.ts +7 -0
  156. package/dist/types/boundary/hooks/useUser.d.ts.map +1 -0
  157. package/dist/types/components/background.d.ts +2 -0
  158. package/dist/types/components/background.d.ts.map +1 -0
  159. package/dist/types/components/sign-in.d.ts +18 -0
  160. package/dist/types/components/sign-in.d.ts.map +1 -0
  161. package/dist/types/components/sign-out.d.ts +10 -0
  162. package/dist/types/components/sign-out.d.ts.map +1 -0
  163. package/dist/types/components/sign-up.d.ts +7 -0
  164. package/dist/types/components/sign-up.d.ts.map +1 -0
  165. package/dist/types/components/ui/alert.d.ts +9 -0
  166. package/dist/types/components/ui/alert.d.ts.map +1 -0
  167. package/dist/types/components/ui/button.d.ts +12 -0
  168. package/dist/types/components/ui/button.d.ts.map +1 -0
  169. package/dist/types/components/ui/card.d.ts +9 -0
  170. package/dist/types/components/ui/card.d.ts.map +1 -0
  171. package/dist/types/components/ui/input.d.ts +4 -0
  172. package/dist/types/components/ui/input.d.ts.map +1 -0
  173. package/dist/types/components/ui/label.d.ts +6 -0
  174. package/dist/types/components/ui/label.d.ts.map +1 -0
  175. package/dist/types/components/ui/separator.d.ts +5 -0
  176. package/dist/types/components/ui/separator.d.ts.map +1 -0
  177. package/dist/types/components/verify.d.ts +2 -0
  178. package/dist/types/components/verify.d.ts.map +1 -0
  179. package/dist/types/errors.d.ts +9 -0
  180. package/dist/types/errors.d.ts.map +1 -0
  181. package/dist/types/index.d.ts +1 -0
  182. package/dist/types/index.d.ts.map +1 -0
  183. package/dist/types/lib/utils.d.ts +3 -0
  184. package/dist/types/lib/utils.d.ts.map +1 -0
  185. package/dist/types/types.d.ts +63 -0
  186. package/dist/types/types.d.ts.map +1 -0
  187. package/dist/types/utils/admin-init.d.ts +4 -0
  188. package/dist/types/utils/admin-init.d.ts.map +1 -0
  189. package/dist/types/utils/client-init.d.ts +5 -0
  190. package/dist/types/utils/client-init.d.ts.map +1 -0
  191. package/dist/types/utils/config.d.ts +35 -0
  192. package/dist/types/utils/config.d.ts.map +1 -0
  193. package/dist/types/utils/construct.d.ts +22 -0
  194. package/dist/types/utils/construct.d.ts.map +1 -0
  195. package/dist/types/utils/create-styles.d.ts +99 -0
  196. package/dist/types/utils/create-styles.d.ts.map +1 -0
  197. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/create-styles.ts"],"sourcesContent":["'use client'\n\nconst PREFIX = 'tern'\n\n// Singleton to track style injection\nconst styleInjection = {\n isInjected: false,\n styleElement: null as HTMLStyleElement | null\n}\n\nexport const defaultClassNames = {\n container: `${PREFIX}-container`,\n header: `${PREFIX}-header`,\n title: `${PREFIX}-title`,\n formWrapper: `${PREFIX}-formWrapper`,\n formContainer: `${PREFIX}-formContainer`,\n form: `${PREFIX}-form`,\n label: `${PREFIX}-label`,\n input: `${PREFIX}-input`,\n button: `${PREFIX}-button`,\n error: `${PREFIX}-error`\n} as const\n\n// Create styles once and cache them\nfunction createStyleSheet(styles: Record<string, React.CSSProperties>) {\n if (typeof window === 'undefined') return defaultClassNames\n\n // Return early if styles are already injected\n if (styleInjection.isInjected) {\n return defaultClassNames\n }\n\n // Find existing style element or create new one\n let styleElement = document.querySelector<HTMLStyleElement>('[data-tern-secure]')\n \n if (!styleElement) {\n styleElement = document.createElement('style')\n styleElement.setAttribute('data-tern-secure', '')\n document.head.appendChild(styleElement)\n styleInjection.styleElement = styleElement\n }\n\n // Create CSS rules\n const cssRules = Object.entries(styles).map(([key, rules]) => {\n const className = defaultClassNames[key as keyof typeof defaultClassNames]\n const cssProperties = Object.entries(rules).map(([prop, value]) => {\n const cssProperty = prop.replace(/([A-Z])/g, '-$1').toLowerCase()\n return `${cssProperty}: ${value};`\n }).join(' ')\n\n return `.${className} { ${cssProperties} }`\n }).join('\\n')\n\n // Insert styles only once\n styleElement.textContent = cssRules\n styleInjection.isInjected = true\n\n return defaultClassNames\n}\n\n// Style configuration\nexport const styleConfig = {\n container: {\n display: 'flex',\n minHeight: '100%',\n flex: '1',\n flexDirection: 'column',\n justifyContent: 'center',\n padding: '3rem 1.5rem'\n },\n header: {\n margin: '0 auto',\n width: '100%',\n maxWidth: '28rem'\n },\n title: {\n marginTop: '1.5rem',\n textAlign: 'center',\n fontSize: '1.875rem',\n fontWeight: '700',\n lineHeight: '2.25rem',\n letterSpacing: '-0.025em',\n color: 'var(--tern-text-primary, #111827)'\n },\n formWrapper: {\n marginTop: '2.5rem',\n margin: '0 auto',\n width: '100%',\n maxWidth: '30rem'\n },\n formContainer: {\n padding: '3rem 1.5rem',\n boxShadow: '0 1px 3px 0 rgb(0 0 0 / 0.1)',\n borderRadius: '0.5rem',\n backgroundColor: 'var(--tern-background, white)'\n },\n form: {\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem'\n },\n label: {\n display: 'block',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: 'var(--tern-text-secondary, #374151)'\n },\n input: {\n marginTop: '0.25rem',\n display: 'block',\n width: '100%',\n padding: '0.5rem 0.75rem',\n borderRadius: '0.375rem',\n border: '1px solid var(--tern-border, #D1D5DB)',\n backgroundColor: 'var(--tern-input-background, white)',\n color: 'var(--tern-text-primary, #111827)'\n },\n button: {\n display: 'flex',\n width: '100%',\n justifyContent: 'center',\n padding: '0.5rem 1rem',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: 'white',\n backgroundColor: 'var(--tern-primary, #2563EB)',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer'\n },\n error: {\n color: 'var(--tern-error, #DC2626)',\n fontSize: '0.875rem'\n }\n} as const\n\n// Export pre-created styles\nexport const styles = createStyleSheet(styleConfig)\n\n"],"mappings":"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","names":["styles"]}
@@ -0,0 +1,9 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { TernSecureClientProvider } from "../../boundary/TernSecureClientProvider";
3
+ async function TernSecureProvider({ children }) {
4
+ return /* @__PURE__ */ jsx(TernSecureClientProvider, { children });
5
+ }
6
+ export {
7
+ TernSecureProvider
8
+ };
9
+ //# sourceMappingURL=TernSecureProvider.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,151 @@
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";
4
+ async function createUser(email, password) {
5
+ const auth = TernSecureAuth();
6
+ try {
7
+ const actionCodeSettings = {
8
+ url: `${window.location.origin}/sign-in`,
9
+ handleCodeInApp: true
10
+ };
11
+ const userCredential = await createUserWithEmailAndPassword(auth, email, password);
12
+ await sendEmailVerification(userCredential.user, actionCodeSettings);
13
+ return { success: true, message: "Account created successfully.", user: userCredential.user };
14
+ } 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");
34
+ }
35
+ }
36
+ async function signInWithEmail(email, password) {
37
+ const auth = TernSecureAuth();
38
+ try {
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
+ }
47
+ } catch (error) {
48
+ const errorMessage = error instanceof Error ? error.message : "Failed to sign in";
49
+ throw new Error(errorMessage);
50
+ }
51
+ }
52
+ async function signInWithRedirectGoogle() {
53
+ const auth = TernSecureAuth();
54
+ const provider = new GoogleAuthProvider();
55
+ provider.setCustomParameters({
56
+ login_hint: "user@example.com",
57
+ prompt: "select_account"
58
+ });
59
+ try {
60
+ await signInWithRedirect(auth, provider);
61
+ return { success: true, message: "Redirect initiated" };
62
+ } catch (error) {
63
+ console.error("Error during Google sign-in:", error);
64
+ return { success: false, error: "Failed to sign in with Google" };
65
+ }
66
+ }
67
+ async function signInWithMicrosoft() {
68
+ const auth = TernSecureAuth();
69
+ const provider = new OAuthProvider("microsoft.com");
70
+ provider.setCustomParameters({
71
+ prompt: "consent"
72
+ });
73
+ try {
74
+ await signInWithRedirect(auth, provider);
75
+ return { success: true, message: "Redirect initiated" };
76
+ } catch (error) {
77
+ console.error("Error during Google sign-in:", error);
78
+ return { success: false, error: "Failed to sign in with Google" };
79
+ }
80
+ }
81
+ async function handleAuthRedirectResult() {
82
+ const auth = TernSecureAuth();
83
+ try {
84
+ const result = await getRedirectResult(auth);
85
+ if (result) {
86
+ const user = result.user;
87
+ return { success: true, user };
88
+ } else {
89
+ return { success: false, error: "No redirect result" };
90
+ }
91
+ } 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 };
94
+ }
95
+ }
96
+ async function resendEmailVerification() {
97
+ const auth = TernSecureAuth();
98
+ try {
99
+ const user = auth.currentUser;
100
+ if (!user) {
101
+ throw new Error("No user found. Please try signing up again.");
102
+ }
103
+ await user.reload();
104
+ if (user.emailVerified) {
105
+ return {
106
+ success: true,
107
+ message: "Email is already verified. You can sign in.",
108
+ isVerified: true
109
+ };
110
+ }
111
+ const actionCodeSettings = {
112
+ url: `${window.location.origin}/sign-in`,
113
+ handleCodeInApp: true
114
+ };
115
+ await sendEmailVerification(user, actionCodeSettings);
116
+ return {
117
+ success: true,
118
+ message: "Verification email sent successfully.",
119
+ isVerified: false
120
+ };
121
+ } 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.");
141
+ }
142
+ }
143
+ export {
144
+ createUser,
145
+ handleAuthRedirectResult,
146
+ resendEmailVerification,
147
+ signInWithEmail,
148
+ signInWithMicrosoft,
149
+ signInWithRedirectGoogle
150
+ };
151
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +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":"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","names":[]}
@@ -0,0 +1,20 @@
1
+ import { Verify } from "../../components/verify";
2
+ const internalRoutes = {
3
+ verify: {
4
+ pattern: /^\/sign-up\/verify$/,
5
+ component: Verify
6
+ }
7
+ };
8
+ function handleInternalRoute(pathname) {
9
+ for (const [key, route] of Object.entries(internalRoutes)) {
10
+ if (route.pattern.test(pathname)) {
11
+ return route.component;
12
+ }
13
+ }
14
+ return null;
15
+ }
16
+ export {
17
+ handleInternalRoute,
18
+ internalRoutes
19
+ };
20
+ //# sourceMappingURL=internal-route.js.map
@@ -0,0 +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":[]}
@@ -0,0 +1,47 @@
1
+ "use server";
2
+ import { cookies } from "next/headers";
3
+ import { verifyTernIdToken, verifyTernSessionCookie } from "./sessionTernSecure";
4
+ async function auth() {
5
+ var _a, _b, _c;
6
+ try {
7
+ const cookieStore = await cookies();
8
+ const sessionCookie = (_a = cookieStore.get("_session_cookie")) == null ? void 0 : _a.value;
9
+ if (sessionCookie) {
10
+ const sessionResult = await verifyTernSessionCookie(sessionCookie);
11
+ if (sessionResult.valid) {
12
+ return {
13
+ userId: sessionResult.uid,
14
+ token: sessionCookie,
15
+ error: null
16
+ };
17
+ }
18
+ }
19
+ const idToken = (_b = cookieStore.get("_session_token")) == null ? void 0 : _b.value;
20
+ if (idToken) {
21
+ const tokenResult = await verifyTernIdToken(idToken);
22
+ if (tokenResult.valid) {
23
+ return {
24
+ userId: (_c = tokenResult.uid) != null ? _c : null,
25
+ token: idToken,
26
+ error: null
27
+ };
28
+ }
29
+ }
30
+ return {
31
+ userId: null,
32
+ token: null,
33
+ error: new Error("No valid session or token found")
34
+ };
35
+ } catch (error) {
36
+ console.error("Error in auth function:", error);
37
+ return {
38
+ userId: null,
39
+ token: null,
40
+ error: error instanceof Error ? error : new Error("An unknown error occurred")
41
+ };
42
+ }
43
+ }
44
+ export {
45
+ auth
46
+ };
47
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app-router/server/auth.ts"],"sourcesContent":["'use server'\n\nimport { cookies } from 'next/headers';\nimport { verifyTernIdToken, verifyTernSessionCookie } from './sessionTernSecure';\n\nexport interface AuthResult {\n userId: string | null;\n token: string | null;\n error: Error | null;\n}\n\nexport async function auth(): Promise<AuthResult> {\n try {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get('_session_cookie')?.value;\n if (sessionCookie) {\n const sessionResult = await verifyTernSessionCookie(sessionCookie);\n if (sessionResult.valid) {\n return {\n userId: sessionResult.uid,\n token: sessionCookie,\n error: null\n };\n }\n }\n\n // If session cookie is not present or invalid, try the ID token\n const idToken = cookieStore.get('_session_token')?.value;\n if (idToken) {\n const tokenResult = await verifyTernIdToken(idToken);\n if (tokenResult.valid) {\n return {\n userId: tokenResult.uid ?? null,\n token: idToken,\n error: null\n };\n }\n }\n\n /// If both checks fail, return null values\n return {\n userId: null,\n token: null,\n error: new Error('No valid session or token found')\n };\n } catch (error) {\n console.error('Error in auth function:', error);\n return {\n userId: null,\n token: null,\n error: error instanceof Error ? error : new Error('An unknown error occurred')\n };\n }\n}\n\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAU,mBAAmB,+BAA+B;AAQ5D,eAAsB,OAA4B;AAXlD;AAYE,MAAI;AACF,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,iBAAgB,iBAAY,IAAI,iBAAiB,MAAjC,mBAAoC;AAC1D,QAAI,eAAe;AACjB,YAAM,gBAAgB,MAAM,wBAAwB,aAAa;AACjE,UAAI,cAAc,OAAO;AACvB,eAAO;AAAA,UACL,QAAQ,cAAc;AAAA,UACtB,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAU,iBAAY,IAAI,gBAAgB,MAAhC,mBAAmC;AACnD,QAAI,SAAS;AACX,YAAM,cAAc,MAAM,kBAAkB,OAAO;AACnD,UAAI,YAAY,OAAO;AACrB,eAAO;AAAA,UACL,SAAQ,iBAAY,QAAZ,YAAmB;AAAA,UAC3B,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAGA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO,IAAI,MAAM,iCAAiC;AAAA,IACpD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,2BAA2B,KAAK;AAC9C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,2BAA2B;AAAA,IAC/E;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,13 @@
1
+ import { adminTernSecureAuth, adminTernSecureDb } from "../../utils/admin-init";
2
+ import { ternSecureMiddleware } from "./ternSecureMiddleware";
3
+ import { verifyTernSessionCookie, createSessionCookie } from "./sessionTernSecure";
4
+ import { auth } from "./auth";
5
+ export {
6
+ adminTernSecureAuth,
7
+ adminTernSecureDb,
8
+ auth,
9
+ createSessionCookie,
10
+ ternSecureMiddleware,
11
+ verifyTernSessionCookie
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app-router/server/index.ts"],"sourcesContent":["export { adminTernSecureAuth, adminTernSecureDb } from '../../utils/admin-init'\nexport { ternSecureMiddleware } from './ternSecureMiddleware'\nexport { verifyTernSessionCookie, createSessionCookie } from './sessionTernSecure'\nexport { auth } from './auth'"],"mappings":"AAAA,SAAS,qBAAqB,yBAAyB;AACvD,SAAS,4BAA4B;AACrC,SAAS,yBAAyB,2BAA2B;AAC7D,SAAS,YAAY;","names":[]}
@@ -0,0 +1,129 @@
1
+ "use server";
2
+ import { cookies } from "next/headers";
3
+ import { adminTernSecureAuth as adminAuth } from "../../utils/admin-init";
4
+ async function createSessionCookie(idToken) {
5
+ try {
6
+ const expiresIn = 60 * 60 * 24 * 5 * 1e3;
7
+ const sessionCookie = await adminAuth.createSessionCookie(idToken, { expiresIn });
8
+ const cookieStore = await cookies();
9
+ cookieStore.set("_session_cookie", sessionCookie, {
10
+ maxAge: expiresIn,
11
+ httpOnly: true,
12
+ secure: process.env.NODE_ENV === "production",
13
+ path: "/"
14
+ });
15
+ return { success: true, message: "Session created" };
16
+ } catch (error) {
17
+ return { success: false, message: "Failed to create session" };
18
+ }
19
+ }
20
+ async function getServerSessionCookie() {
21
+ var _a;
22
+ const cookieStore = await cookies();
23
+ const sessionCookie = (_a = cookieStore.get("_session_cookie")) == null ? void 0 : _a.value;
24
+ if (!sessionCookie) {
25
+ throw new Error("No session cookie found");
26
+ }
27
+ try {
28
+ const decondeClaims = await adminAuth.verifySessionCookie(sessionCookie, true);
29
+ return {
30
+ token: sessionCookie,
31
+ userId: decondeClaims.uid
32
+ };
33
+ } catch (error) {
34
+ console.error("Error verifying session:", error);
35
+ throw new Error("Invalid Session");
36
+ }
37
+ }
38
+ async function getIdToken() {
39
+ var _a;
40
+ const cookieStore = await cookies();
41
+ const token = (_a = cookieStore.get("_session_token")) == null ? void 0 : _a.value;
42
+ if (!token) {
43
+ throw new Error("No session cookie found");
44
+ }
45
+ try {
46
+ const decodedClaims = await adminAuth.verifyIdToken(token);
47
+ return {
48
+ token,
49
+ userId: decodedClaims.uid
50
+ };
51
+ } catch (error) {
52
+ console.error("Error verifying session:", error);
53
+ throw new Error("Invalid Session");
54
+ }
55
+ }
56
+ async function setServerSession(token) {
57
+ const cookieStore = await cookies();
58
+ cookieStore.set("_session", token, {
59
+ httpOnly: true,
60
+ secure: process.env.NODE_ENV === "production",
61
+ sameSite: "strict",
62
+ maxAge: 60 * 60,
63
+ // 1 hour
64
+ path: "/"
65
+ });
66
+ }
67
+ async function verifyTernIdToken(token) {
68
+ try {
69
+ const decodedToken = await adminAuth.verifyIdToken(token, true);
70
+ return { valid: true, uid: decodedToken.uid };
71
+ } catch (error) {
72
+ if (error instanceof Error) {
73
+ const firebaseError = error;
74
+ if (error.name === "FirebaseAuthError") {
75
+ switch (firebaseError.code) {
76
+ case "auth/id-token-expired":
77
+ return { valid: false, error: "Token has expired" };
78
+ case "auth/id-token-revoked":
79
+ return { valid: false, error: "Token has been revoked" };
80
+ case "auth/user-disabled":
81
+ return { valid: false, error: "User account has been disabled" };
82
+ default:
83
+ return { valid: false, error: "Invalid token" };
84
+ }
85
+ }
86
+ }
87
+ return { valid: false, error: "Error verifying token" };
88
+ }
89
+ }
90
+ async function verifyTernSessionCookie(session) {
91
+ try {
92
+ const res = await adminAuth.verifySessionCookie(session, true);
93
+ if (res) {
94
+ return { valid: true, uid: res.uid };
95
+ } else {
96
+ return { valid: false, error: "Invalid session" };
97
+ }
98
+ } catch (error) {
99
+ return { error, valid: false };
100
+ }
101
+ }
102
+ async function clearSessionCookie() {
103
+ var _a;
104
+ const cookieStore = await cookies();
105
+ cookieStore.delete("_session_cookie");
106
+ cookieStore.delete("_session_token");
107
+ cookieStore.delete("_session");
108
+ try {
109
+ const sessionCookie = (_a = cookieStore.get("_session_cookie")) == null ? void 0 : _a.value;
110
+ if (sessionCookie) {
111
+ const decodedClaims = await adminAuth.verifySessionCookie(sessionCookie);
112
+ await adminAuth.revokeRefreshTokens(decodedClaims.uid);
113
+ }
114
+ return { success: true, message: "Session cleared successfully" };
115
+ } catch (error) {
116
+ console.error("Error clearing session:", error);
117
+ return { success: true, message: "Session cookies cleared" };
118
+ }
119
+ }
120
+ export {
121
+ clearSessionCookie,
122
+ createSessionCookie,
123
+ getIdToken,
124
+ getServerSessionCookie,
125
+ setServerSession,
126
+ verifyTernIdToken,
127
+ verifyTernSessionCookie
128
+ };
129
+ //# sourceMappingURL=sessionTernSecure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app-router/server/sessionTernSecure.ts"],"sourcesContent":["'use server'\n\nimport { cookies } from 'next/headers';\nimport { adminTernSecureAuth as adminAuth } from '../../utils/admin-init';\n\ninterface FirebaseAuthError extends Error {\n code?: string;\n}\n\nexport interface User {\n uid: string | null;\n email: string | null;\n }\n\nexport interface Session {\n user: User | null;\n token: string | null;\n error: Error | null;\n}\n\nexport async function createSessionCookie(idToken: string) {\n try {\n const expiresIn = 60 * 60 * 24 * 5 * 1000;\n const sessionCookie = await adminAuth.createSessionCookie(idToken, { expiresIn });\n\n const cookieStore = await cookies();\n cookieStore.set('_session_cookie', sessionCookie, {\n maxAge: expiresIn,\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n path: '/',\n });\n return { success: true, message: 'Session created' };\n } catch (error) {\n return { success: false, message: 'Failed to create session' };\n }\n}\n\n\n\nexport async function getServerSessionCookie() {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get('_session_cookie')?.value;\n\n if (!sessionCookie) {\n throw new Error('No session cookie found')\n }\n \n try {\n const decondeClaims = await adminAuth.verifySessionCookie(sessionCookie, true)\n return {\n token: sessionCookie,\n userId: decondeClaims.uid\n }\n } catch (error) {\n console.error('Error verifying session:', error)\n throw new Error('Invalid Session')\n }\n}\n\n\nexport async function getIdToken() {\n const cookieStore = await cookies();\n const token = cookieStore.get('_session_token')?.value;\n\n if (!token) {\n throw new Error('No session cookie found')\n }\n \n try {\n const decodedClaims = await adminAuth.verifyIdToken(token)\n return {\n token: token,\n userId: decodedClaims.uid\n }\n } catch (error) {\n console.error('Error verifying session:', error)\n throw new Error('Invalid Session')\n }\n}\n\nexport async function setServerSession(token: string) {\n const cookieStore = await cookies();\n cookieStore.set('_session', token, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 60 * 60, // 1 hour\n path: '/',\n });\n }\n\n export async function verifyTernIdToken(token: string): Promise<{ valid: boolean; uid?: string; error?: string }> {\n try {\n const decodedToken = await adminAuth.verifyIdToken(token, true);\n return { valid: true, uid: decodedToken.uid };\n } catch (error) {\n if (error instanceof Error) {\n const firebaseError = error as FirebaseAuthError;\n if (error.name === 'FirebaseAuthError') {\n // Handle specific Firebase Auth errors\n switch (firebaseError.code) {\n case 'auth/id-token-expired':\n return { valid: false, error: 'Token has expired' };\n case 'auth/id-token-revoked':\n return { valid: false, error: 'Token has been revoked' };\n case 'auth/user-disabled':\n return { valid: false, error: 'User account has been disabled' };\n default:\n return { valid: false, error: 'Invalid token' };\n }\n }\n }\n return { valid: false, error: 'Error verifying token' };\n }\n }\n \n\n export async function verifyTernSessionCookie(session: string): Promise<{ valid: boolean; uid?: any; error?: any }>{\n try {\n const res = await adminAuth.verifySessionCookie(session, true);\n if (res) {\n return { valid: true, uid: res.uid };\n } else {\n return { valid: false, error: 'Invalid session'};\n }\n } catch (error) {\n return {error: error, valid: false}\n }\n }\n\n\n export async function clearSessionCookie() {\n const cookieStore = await cookies()\n \n cookieStore.delete('_session_cookie')\n cookieStore.delete('_session_token')\n cookieStore.delete('_session')\n \n try {\n // Verify if there's an active session before revoking\n const sessionCookie = cookieStore.get('_session_cookie')?.value\n if (sessionCookie) {\n // Get the decoded claims to get the user's ID\n const decodedClaims = await adminAuth.verifySessionCookie(sessionCookie)\n \n // Revoke all sessions for the user\n await adminAuth.revokeRefreshTokens(decodedClaims.uid)\n }\n \n return { success: true, message: 'Session cleared successfully' }\n } catch (error) {\n console.error('Error clearing session:', error)\n // Still return success even if revoking fails, as cookies are cleared\n return { success: true, message: 'Session cookies cleared' }\n }\n }\n\n\n\n/*\n export async function GET(request: NextRequest) {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get('session')?.value\n \n if (!sessionCookie) {\n return NextResponse.json({ isAuthenticated: false }, { status: 401 })\n }\n \n try {\n const decodedClaims = await adminAuth.verifySessionCookie(sessionCookie, true)\n return NextResponse.json({ isAuthenticated: true, user: decodedClaims }, { status: 200 })\n } catch (error) {\n console.error('Error verifying session cookie:', error)\n return NextResponse.json({ isAuthenticated: false }, { status: 401 })\n }\n }\n\n*/"],"mappings":"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","names":[]}
@@ -0,0 +1,26 @@
1
+ import { NextResponse } from "next/server";
2
+ import { auth } from "./auth";
3
+ function ternSecureMiddleware(options = {}) {
4
+ const { publicPaths = [], redirectTo = "/login" } = options;
5
+ return async function middleware(request) {
6
+ const { pathname } = request.nextUrl;
7
+ if (publicPaths.includes(pathname)) {
8
+ return NextResponse.next();
9
+ }
10
+ try {
11
+ const { userId, token, error } = await auth();
12
+ if (error || !userId || !token) {
13
+ return NextResponse.redirect(new URL(redirectTo, request.url));
14
+ }
15
+ const response = NextResponse.next();
16
+ return response;
17
+ } catch (error) {
18
+ console.error("Error in ternSecureMiddleware:", error);
19
+ return NextResponse.redirect(new URL(redirectTo, request.url));
20
+ }
21
+ };
22
+ }
23
+ export {
24
+ ternSecureMiddleware
25
+ };
26
+ //# sourceMappingURL=ternSecureMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/app-router/server/ternSecureMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport { auth } from './auth';\n\nexport interface TernSecureMiddlewareOptions {\n publicPaths?: string[];\n redirectTo?: string;\n}\n\nexport function ternSecureMiddleware(options: TernSecureMiddlewareOptions = {}) {\n const { publicPaths = [], redirectTo = '/login' } = options;\n\n return async function middleware(request: NextRequest) {\n const { pathname } = request.nextUrl;\n\n // Check if the path is public\n if (publicPaths.includes(pathname)) {\n return NextResponse.next();\n }\n\n try {\n const { userId, token, error } = await auth();\n\n if (error || !userId || !token) {\n // If there's no valid session, redirect to login\n return NextResponse.redirect(new URL(redirectTo, request.url));\n }\n\n // If there's a valid session, allow the request to proceed\n const response = NextResponse.next();\n \n // Optionally, you can set headers here if needed\n // response.headers.set('X-User-ID', userId);\n\n return response;\n } catch (error) {\n console.error('Error in ternSecureMiddleware:', error);\n return NextResponse.redirect(new URL(redirectTo, request.url));\n }\n };\n}\n\n"],"mappings":"AAAA,SAAsB,oBAAoB;AAC1C,SAAS,YAAY;AAOd,SAAS,qBAAqB,UAAuC,CAAC,GAAG;AAC9E,QAAM,EAAE,cAAc,CAAC,GAAG,aAAa,SAAS,IAAI;AAEpD,SAAO,eAAe,WAAW,SAAsB;AACrD,UAAM,EAAE,SAAS,IAAI,QAAQ;AAG7B,QAAI,YAAY,SAAS,QAAQ,GAAG;AAClC,aAAO,aAAa,KAAK;AAAA,IAC3B;AAEA,QAAI;AACF,YAAM,EAAE,QAAQ,OAAO,MAAM,IAAI,MAAM,KAAK;AAE5C,UAAI,SAAS,CAAC,UAAU,CAAC,OAAO;AAE9B,eAAO,aAAa,SAAS,IAAI,IAAI,YAAY,QAAQ,GAAG,CAAC;AAAA,MAC/D;AAGA,YAAM,WAAW,aAAa,KAAK;AAKnC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AACrD,aAAO,aAAa,SAAS,IAAI,IAAI,YAAY,QAAQ,GAAG,CAAC;AAAA,IAC/D;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useState, useEffect, useMemo, useCallback } from "react";
4
+ import { ternSecureAuth } from "../utils/client-init";
5
+ import { onAuthStateChanged } from "firebase/auth";
6
+ import { TernSecureCtx } from "./TernSecureCtx";
7
+ import { useRouter } from "next/navigation";
8
+ function TernSecureClientProvider({
9
+ children,
10
+ loginPath = "/sign-in",
11
+ loadingComponent
12
+ }) {
13
+ const auth = useMemo(() => ternSecureAuth, []);
14
+ const router = useRouter();
15
+ const [authState, setAuthState] = useState(() => ({
16
+ userId: null,
17
+ isLoaded: false,
18
+ error: null,
19
+ isValid: false,
20
+ token: null,
21
+ email: null
22
+ }));
23
+ const handleSignOut = useCallback(async (error) => {
24
+ await auth.signOut();
25
+ setAuthState({
26
+ isLoaded: true,
27
+ userId: null,
28
+ error: error || null,
29
+ isValid: false,
30
+ token: null,
31
+ email: null
32
+ });
33
+ router.push(loginPath);
34
+ }, [auth, router, loginPath]);
35
+ const setEmail = useCallback((email) => {
36
+ setAuthState((prev) => ({
37
+ ...prev,
38
+ email
39
+ }));
40
+ }, []);
41
+ useEffect(() => {
42
+ const unsubscribe = onAuthStateChanged(auth, async (user) => {
43
+ if (user) {
44
+ setAuthState({
45
+ isLoaded: true,
46
+ userId: user.uid,
47
+ isValid: true,
48
+ token: user.getIdToken(),
49
+ error: null,
50
+ email: user.email
51
+ });
52
+ } else {
53
+ setAuthState({
54
+ isLoaded: true,
55
+ userId: null,
56
+ isValid: false,
57
+ token: null,
58
+ error: new Error("User is not authenticated"),
59
+ email: null
60
+ });
61
+ if (!window.location.pathname.includes("/sign-up")) {
62
+ router.push(loginPath);
63
+ }
64
+ }
65
+ }, (error) => {
66
+ handleSignOut(error instanceof Error ? error : new Error("Authentication error occurred"));
67
+ });
68
+ return () => unsubscribe();
69
+ }, [auth, handleSignOut, router, loginPath]);
70
+ const contextValue = useMemo(() => ({
71
+ ...authState,
72
+ signOut: handleSignOut,
73
+ setEmail
74
+ }), [authState, auth, handleSignOut, setEmail]);
75
+ if (!authState.isLoaded) {
76
+ return /* @__PURE__ */ jsx(TernSecureCtx.Provider, { value: contextValue, children: loadingComponent || /* @__PURE__ */ jsx("div", { "aria-live": "polite", "aria-busy": "true", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading authentication state..." }) }) });
77
+ }
78
+ return /* @__PURE__ */ jsx(TernSecureCtx.Provider, { value: contextValue, children });
79
+ }
80
+ export {
81
+ TernSecureClientProvider
82
+ };
83
+ //# sourceMappingURL=TernSecureClientProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/boundary/TernSecureClientProvider.tsx"],"sourcesContent":["\"use client\"\n\nimport React, { useState, useEffect, useMemo, useCallback } from 'react'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { onAuthStateChanged, User } from \"firebase/auth\"\nimport { TernSecureCtx, TernSecureCtxValue, TernSecureState } from './TernSecureCtx'\nimport { useRouter } from 'next/navigation'\n\ninterface TernSecureClientProviderProps {\n children: React.ReactNode;\n onUserChanged?: (user: User | null) => Promise<void>;\n loginPath?: string;\n loadingComponent?: React.ReactNode;\n}\n\nexport function TernSecureClientProvider({ \n children, \n loginPath = '/sign-in',\n loadingComponent\n}: TernSecureClientProviderProps) {\n const auth = useMemo(() => ternSecureAuth, []);\n const router = useRouter();\n const [authState, setAuthState] = useState<TernSecureState>(() => ({\n userId: null,\n isLoaded: false,\n error: null,\n isValid: false,\n token: null,\n email: null\n }));\n\n const handleSignOut = useCallback(async (error?: Error) => {\n await auth.signOut();\n setAuthState({\n isLoaded: true,\n userId: null,\n error: error || null,\n isValid: false,\n token: null,\n email: null\n });\n router.push(loginPath);\n }, [auth, router, loginPath]);\n\n const setEmail = useCallback((email: string) => {\n setAuthState((prev) => ({\n ...prev,\n email,\n }))\n }, [])\n\nuseEffect(() => {\n const unsubscribe = onAuthStateChanged(auth, async (user: User | null) => {\n if (user) {\n setAuthState({\n isLoaded: true,\n userId: user.uid,\n isValid: true,\n token: user.getIdToken(),\n error: null,\n email: user.email,\n })\n } else {\n setAuthState({\n isLoaded: true,\n userId: null,\n isValid: false,\n token: null,\n error: new Error('User is not authenticated'),\n email: null\n })\n if (!window.location.pathname.includes(\"/sign-up\")) {\n router.push(loginPath)\n }\n }\n }, (error) => {\n handleSignOut(error instanceof Error ? error : new Error('Authentication error occurred'));\n })\n \n return () => unsubscribe()\n }, [auth, handleSignOut, router, loginPath])\n\n const contextValue: TernSecureCtxValue = useMemo(() => ({\n ...authState,\n signOut: handleSignOut,\n setEmail\n }), [authState, auth, handleSignOut, setEmail]);\n\n if (!authState.isLoaded) {\n return (\n <TernSecureCtx.Provider value={contextValue}>\n {loadingComponent || (\n <div aria-live=\"polite\" aria-busy=\"true\">\n <span className=\"sr-only\">Loading authentication state...</span>\n </div>\n )}\n </TernSecureCtx.Provider>\n );\n }\n\n return (\n <TernSecureCtx.Provider value={contextValue}>\n {children}\n </TernSecureCtx.Provider>\n )\n}"],"mappings":";AA6FY;AA3FZ,SAAgB,UAAU,WAAW,SAAS,mBAAmB;AACjE,SAAS,sBAAsB;AAC/B,SAAS,0BAAgC;AACzC,SAAS,qBAA0D;AACnE,SAAS,iBAAiB;AASnB,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAkC;AAChC,QAAM,OAAO,QAAQ,MAAM,gBAAgB,CAAC,CAAC;AAC7C,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,WAAW,YAAY,IAAI,SAA0B,OAAO;AAAA,IACjE,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT,EAAE;AAEF,QAAM,gBAAgB,YAAY,OAAO,UAAkB;AACzD,UAAM,KAAK,QAAQ;AACnB,iBAAa;AAAA,MACX,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,SAAS;AAAA,MAChB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AACD,WAAO,KAAK,SAAS;AAAA,EACvB,GAAG,CAAC,MAAM,QAAQ,SAAS,CAAC;AAE5B,QAAM,WAAW,YAAY,CAAC,UAAkB;AAC9C,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,IACF,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEP,YAAU,MAAM;AACZ,UAAM,cAAc,mBAAmB,MAAM,OAAO,SAAsB;AACxE,UAAI,MAAM;AACR,qBAAa;AAAA,UACX,UAAU;AAAA,UACV,QAAQ,KAAK;AAAA,UACb,SAAS;AAAA,UACT,OAAO,KAAK,WAAW;AAAA,UACvB,OAAO;AAAA,UACP,OAAO,KAAK;AAAA,QACd,CAAC;AAAA,MACH,OAAO;AACL,qBAAa;AAAA,UACX,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,OAAO;AAAA,UACP,OAAO,IAAI,MAAM,2BAA2B;AAAA,UAC5C,OAAO;AAAA,QACT,CAAC;AACD,YAAI,CAAC,OAAO,SAAS,SAAS,SAAS,UAAU,GAAG;AAClD,iBAAO,KAAK,SAAS;AAAA,QACvB;AAAA,MACF;AAAA,IACF,GAAG,CAAC,UAAU;AACZ,oBAAc,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,+BAA+B,CAAC;AAAA,IAC3F,CAAC;AAED,WAAO,MAAM,YAAY;AAAA,EAC3B,GAAG,CAAC,MAAM,eAAe,QAAQ,SAAS,CAAC;AAE3C,QAAM,eAAmC,QAAQ,OAAO;AAAA,IACtD,GAAG;AAAA,IACH,SAAS;AAAA,IACT;AAAA,EACF,IAAI,CAAC,WAAW,MAAM,eAAe,QAAQ,CAAC;AAE9C,MAAI,CAAC,UAAU,UAAU;AACvB,WACE,oBAAC,cAAc,UAAd,EAAuB,OAAO,cAC5B,8BACC,oBAAC,SAAI,aAAU,UAAS,aAAU,QAChC,8BAAC,UAAK,WAAU,WAAU,6CAA+B,GAC3D,GAEJ;AAAA,EAEJ;AAEA,SACI,oBAAC,cAAc,UAAd,EAAuB,OAAO,cAC7B,UACF;AAEN;","names":[]}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { createContext, useContext } from "react";
3
+ import { ternSecureAuth } from "../utils/client-init";
4
+ const TernSecureUser = () => {
5
+ return ternSecureAuth.currentUser;
6
+ };
7
+ const TernSecureCtx = createContext(null);
8
+ TernSecureCtx.displayName = "TernSecureCtx";
9
+ const useTernSecure = (hookName) => {
10
+ const context = useContext(TernSecureCtx);
11
+ if (!context) {
12
+ throw new Error(
13
+ `${hookName} must be used within TernSecureProvider`
14
+ );
15
+ }
16
+ return context;
17
+ };
18
+ export {
19
+ TernSecureCtx,
20
+ TernSecureUser,
21
+ useTernSecure
22
+ };
23
+ //# sourceMappingURL=TernSecureCtx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/boundary/TernSecureCtx.tsx"],"sourcesContent":["\"use client\"\n\nimport { createContext, useContext } from 'react'\nimport { ternSecureAuth } from '../utils/client-init';\nimport { User } from 'firebase/auth';\n\nexport const TernSecureUser = (): User | null => {\n return ternSecureAuth.currentUser;\n}\n\nexport interface TernSecureState {\n userId: string | null\n isLoaded: boolean\n error: Error | null\n isValid: boolean\n token: any | null\n email: string | null\n}\n\nexport interface TernSecureCtxValue extends TernSecureState {\n signOut: () => Promise<void>\n setEmail: (email: string) => void\n}\n\nexport const TernSecureCtx = createContext<TernSecureCtxValue | null>(null)\n\nTernSecureCtx.displayName = 'TernSecureCtx'\n\nexport const useTernSecure = (hookName: string) => {\n const context = useContext(TernSecureCtx)\n \n if (!context) {\n throw new Error(\n `${hookName} must be used within TernSecureProvider`\n )\n }\n\n return context\n}\n\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkB;AAC1C,SAAS,sBAAsB;AAGxB,MAAM,iBAAiB,MAAmB;AAC/C,SAAO,eAAe;AACxB;AAgBO,MAAM,gBAAgB,cAAyC,IAAI;AAE1E,cAAc,cAAc;AAErB,MAAM,gBAAgB,CAAC,aAAqB;AACjD,QAAM,UAAU,WAAW,aAAa;AAExC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { useTernSecure } from "../TernSecureCtx";
3
+ import { TernSecureUser } from "../TernSecureCtx";
4
+ function useAuth() {
5
+ const {
6
+ userId,
7
+ isLoaded,
8
+ error,
9
+ isValid,
10
+ token,
11
+ signOut
12
+ } = useTernSecure("useAuth");
13
+ const user = TernSecureUser();
14
+ return {
15
+ user,
16
+ userId,
17
+ isLoaded,
18
+ error,
19
+ isAuthenticated: isValid,
20
+ token,
21
+ signOut
22
+ };
23
+ }
24
+ export {
25
+ useAuth
26
+ };
27
+ //# sourceMappingURL=useAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/boundary/hooks/useAuth.ts"],"sourcesContent":["\"use client\"\n\nimport { useTernSecure } from '../TernSecureCtx'\nimport { User } from 'firebase/auth'\nimport { TernSecureUser } from '../TernSecureCtx'\n\nexport function useAuth() {\n const {\n userId,\n isLoaded,\n error,\n isValid,\n token,\n signOut\n } = useTernSecure('useAuth')\n\n const user: User | null = TernSecureUser()\n\n return {\n user,\n userId,\n isLoaded,\n error,\n isAuthenticated: isValid,\n token,\n signOut\n }\n}\n"],"mappings":";AAEA,SAAS,qBAAqB;AAE9B,SAAS,sBAAsB;AAExB,SAAS,UAAU;AACxB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,cAAc,SAAS;AAE3B,QAAM,OAAoB,eAAe;AAEzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;","names":[]}