@tern-secure/nextjs 3.1.74 → 3.1.76

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 (72) hide show
  1. package/dist/cjs/app-router/client/TernSecureProvider.cjs +3 -84
  2. package/dist/cjs/app-router/server/TernSecureServerProvider.cjs +3 -95
  3. package/dist/cjs/app-router/server/auth.cjs +3 -71
  4. package/dist/cjs/boundary/TernSecureCtx.cjs +1 -17
  5. package/dist/cjs/boundary/hooks/useAuth.cjs +3 -30
  6. package/dist/cjs/components/sign-in.cjs +4 -291
  7. package/dist/cjs/errors.cjs +1 -19
  8. package/dist/cjs/index.cjs +4 -349
  9. package/dist/cjs/types.cjs +1 -4
  10. package/dist/cjs/utils/client-init.cjs +3 -68
  11. package/dist/cjs/utils/config.cjs +3 -50
  12. package/dist/cjs/utils/create-styles.cjs +2 -125
  13. package/dist/esm/app-router/client/TernSecureProvider.d.ts +10 -9
  14. package/dist/esm/app-router/client/TernSecureProvider.js +3 -6
  15. package/dist/esm/app-router/server/TernSecureServerProvider.d.ts +26 -5
  16. package/dist/esm/app-router/server/TernSecureServerProvider.js +3 -7
  17. package/dist/esm/app-router/server/auth.js +3 -5
  18. package/dist/esm/boundary/TernSecureCtx.d.ts +13 -8
  19. package/dist/esm/boundary/TernSecureCtx.js +1 -3
  20. package/dist/esm/boundary/hooks/useAuth.d.ts +3 -2
  21. package/dist/esm/boundary/hooks/useAuth.js +3 -4
  22. package/dist/esm/components/sign-in.js +4 -7
  23. package/dist/esm/errors.js +1 -16
  24. package/dist/esm/index.d.ts +6 -2
  25. package/dist/esm/index.js +4 -11
  26. package/dist/esm/types.js +0 -3
  27. package/dist/esm/utils/client-init.js +3 -4
  28. package/dist/esm/utils/config.js +3 -3
  29. package/dist/esm/utils/create-styles.js +2 -3
  30. package/package.json +2 -14
  31. package/dist/cjs/app-router/client/TernSecureProvider.cjs.map +0 -1
  32. package/dist/cjs/app-router/server/TernSecureServerProvider.cjs.map +0 -1
  33. package/dist/cjs/app-router/server/auth.cjs.map +0 -1
  34. package/dist/cjs/boundary/TernSecureCtx.cjs.map +0 -1
  35. package/dist/cjs/boundary/hooks/useAuth.cjs.map +0 -1
  36. package/dist/cjs/components/sign-in.cjs.map +0 -1
  37. package/dist/cjs/errors.cjs.map +0 -1
  38. package/dist/cjs/index.cjs.map +0 -1
  39. package/dist/cjs/types.cjs.map +0 -1
  40. package/dist/cjs/utils/client-init.cjs.map +0 -1
  41. package/dist/cjs/utils/config.cjs.map +0 -1
  42. package/dist/cjs/utils/create-styles.cjs.map +0 -1
  43. package/dist/esm/app-router/client/TernSecureProvider.js.map +0 -1
  44. package/dist/esm/app-router/server/TernSecureServerProvider.js.map +0 -1
  45. package/dist/esm/app-router/server/auth.js.map +0 -1
  46. package/dist/esm/boundary/TernSecureCtx.js.map +0 -1
  47. package/dist/esm/boundary/hooks/useAuth.js.map +0 -1
  48. package/dist/esm/chunk-27O3JVAU.js +0 -16
  49. package/dist/esm/chunk-27O3JVAU.js.map +0 -1
  50. package/dist/esm/chunk-4XFIX4FL.js +0 -14
  51. package/dist/esm/chunk-4XFIX4FL.js.map +0 -1
  52. package/dist/esm/chunk-7VKPI5HF.js +0 -15
  53. package/dist/esm/chunk-7VKPI5HF.js.map +0 -1
  54. package/dist/esm/chunk-EI37GOD7.js +0 -121
  55. package/dist/esm/chunk-EI37GOD7.js.map +0 -1
  56. package/dist/esm/chunk-EIOZNLP2.js +0 -109
  57. package/dist/esm/chunk-EIOZNLP2.js.map +0 -1
  58. package/dist/esm/chunk-FVV74XVR.js +0 -19
  59. package/dist/esm/chunk-FVV74XVR.js.map +0 -1
  60. package/dist/esm/chunk-ODVOZOJG.js +0 -28
  61. package/dist/esm/chunk-ODVOZOJG.js.map +0 -1
  62. package/dist/esm/chunk-SHRRIEFY.js +0 -19
  63. package/dist/esm/chunk-SHRRIEFY.js.map +0 -1
  64. package/dist/esm/chunk-UHGBSUM6.js +0 -46
  65. package/dist/esm/chunk-UHGBSUM6.js.map +0 -1
  66. package/dist/esm/components/sign-in.js.map +0 -1
  67. package/dist/esm/errors.js.map +0 -1
  68. package/dist/esm/index.js.map +0 -1
  69. package/dist/esm/types.js.map +0 -1
  70. package/dist/esm/utils/client-init.js.map +0 -1
  71. package/dist/esm/utils/config.js.map +0 -1
  72. package/dist/esm/utils/create-styles.js.map +0 -1
@@ -1,349 +1,4 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var app = require('firebase/app');
5
- var auth$1 = require('firebase/auth');
6
- var firestore$1 = require('firebase/firestore');
7
- var storage = require('firebase/storage');
8
- var jsxRuntime = require('react/jsx-runtime');
9
-
10
- // src/app-router/client/TernSecureProvider.tsx
11
-
12
- // src/utils/config.ts
13
- var loadFireConfig = () => ({
14
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || "",
15
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || "",
16
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || "",
17
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
18
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
19
- appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
20
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || void 0
21
- });
22
- var validateConfig = (config2) => {
23
- const requiredFields = [
24
- "apiKey",
25
- "authDomain",
26
- "projectId",
27
- "storageBucket",
28
- "messagingSenderId",
29
- "appId"
30
- ];
31
- const errors = [];
32
- requiredFields.forEach((field) => {
33
- if (!config2[field]) {
34
- errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`);
35
- }
36
- });
37
- return {
38
- isValid: errors.length === 0,
39
- errors,
40
- config: config2
41
- };
42
- };
43
- var initializeConfig = () => {
44
- const config2 = loadFireConfig();
45
- const validationResult = validateConfig(config2);
46
- if (!validationResult.isValid) {
47
- throw new Error(
48
- `Firebase configuration validation failed:
49
- ${validationResult.errors.join("\n")}`
50
- );
51
- }
52
- return config2;
53
- };
54
-
55
- // src/utils/client-init.ts
56
- var config = initializeConfig();
57
- var clientApp = app.initializeApp(config);
58
- var auth = auth$1.getAuth(clientApp);
59
- auth$1.setPersistence(auth, auth$1.browserSessionPersistence);
60
- var firestore = firestore$1.getFirestore(clientApp);
61
- storage.getStorage(clientApp);
62
- var TernSecureAuth = () => auth;
63
- var TernSecureFirestore = () => firestore;
64
- var TernSecureContext = react.createContext(null);
65
- var useTernSecure = () => {
66
- const context = react.useContext(TernSecureContext);
67
- if (!context) {
68
- throw new Error("useTernSecure must be used within a TernSecureProvider");
69
- }
70
- return context.authState;
71
- };
72
- var TernSecureClientProvider = ({
73
- children,
74
- initialState
75
- }) => {
76
- const [authState, setAuthState] = react.useState(initialState);
77
- react.useEffect(() => {
78
- const auth2 = TernSecureAuth();
79
- const unsubscribe = auth2.onAuthStateChanged(
80
- (user) => {
81
- setAuthState({ userId: user?.uid || null, isSignedIn: !!user, loading: false, error: null });
82
- },
83
- (error) => {
84
- setAuthState({ userId: null, isSignedIn: false, loading: false, error: null });
85
- }
86
- );
87
- return () => unsubscribe();
88
- }, []);
89
- return /* @__PURE__ */ jsxRuntime.jsx(TernSecureContext.Provider, { value: { authState }, children });
90
- };
91
- function TernSecureProvider({ children }) {
92
- const initialState = {
93
- userId: null,
94
- loading: true,
95
- error: null,
96
- isSignedIn: false
97
- };
98
- return /* @__PURE__ */ jsxRuntime.jsx(TernSecureClientProvider, { initialState, children });
99
- }
100
- async function signInWithEmail({
101
- email,
102
- password
103
- }) {
104
- const auth2 = TernSecureAuth();
105
- return auth$1.signInWithEmailAndPassword(auth2, email, password);
106
- }
107
-
108
- // src/boundary/hooks/useAuth.ts
109
- function useAuth() {
110
- const authState = useTernSecure();
111
- if (!authState) {
112
- throw new Error("Auth state not found");
113
- }
114
- return {
115
- userId: authState.userId,
116
- loading: authState.loading,
117
- error: authState.error,
118
- isSignedIn: authState.isSignedIn
119
- };
120
- }
121
-
122
- // src/utils/create-styles.ts
123
- var PREFIX = "tern";
124
- var styleInjection = {
125
- isInjected: false,
126
- styleElement: null
127
- };
128
- var defaultClassNames = {
129
- container: `${PREFIX}-container`,
130
- header: `${PREFIX}-header`,
131
- title: `${PREFIX}-title`,
132
- formWrapper: `${PREFIX}-formWrapper`,
133
- formContainer: `${PREFIX}-formContainer`,
134
- form: `${PREFIX}-form`,
135
- label: `${PREFIX}-label`,
136
- input: `${PREFIX}-input`,
137
- button: `${PREFIX}-button`,
138
- error: `${PREFIX}-error`
139
- };
140
- function createStyleSheet(styles2) {
141
- if (typeof window === "undefined") return defaultClassNames;
142
- if (styleInjection.isInjected) {
143
- return defaultClassNames;
144
- }
145
- let styleElement = document.querySelector("[data-tern-secure]");
146
- if (!styleElement) {
147
- styleElement = document.createElement("style");
148
- styleElement.setAttribute("data-tern-secure", "");
149
- document.head.appendChild(styleElement);
150
- styleInjection.styleElement = styleElement;
151
- }
152
- const cssRules = Object.entries(styles2).map(([key, rules]) => {
153
- const className = defaultClassNames[key];
154
- const cssProperties = Object.entries(rules).map(([prop, value]) => {
155
- const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
156
- return `${cssProperty}: ${value};`;
157
- }).join(" ");
158
- return `.${className} { ${cssProperties} }`;
159
- }).join("\n");
160
- styleElement.textContent = cssRules;
161
- styleInjection.isInjected = true;
162
- return defaultClassNames;
163
- }
164
- var styleConfig = {
165
- container: {
166
- display: "flex",
167
- minHeight: "100%",
168
- flex: "1",
169
- flexDirection: "column",
170
- justifyContent: "center",
171
- padding: "3rem 1.5rem"
172
- },
173
- header: {
174
- margin: "0 auto",
175
- width: "100%",
176
- maxWidth: "28rem"
177
- },
178
- title: {
179
- marginTop: "1.5rem",
180
- textAlign: "center",
181
- fontSize: "1.875rem",
182
- fontWeight: "700",
183
- lineHeight: "2.25rem",
184
- letterSpacing: "-0.025em",
185
- color: "var(--tern-text-primary, #111827)"
186
- },
187
- formWrapper: {
188
- marginTop: "2.5rem",
189
- margin: "0 auto",
190
- width: "100%",
191
- maxWidth: "30rem"
192
- },
193
- formContainer: {
194
- padding: "3rem 1.5rem",
195
- boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
196
- borderRadius: "0.5rem",
197
- backgroundColor: "var(--tern-background, white)"
198
- },
199
- form: {
200
- display: "flex",
201
- flexDirection: "column",
202
- gap: "1rem"
203
- },
204
- label: {
205
- display: "block",
206
- fontSize: "0.875rem",
207
- fontWeight: "500",
208
- color: "var(--tern-text-secondary, #374151)"
209
- },
210
- input: {
211
- marginTop: "0.25rem",
212
- display: "block",
213
- width: "100%",
214
- padding: "0.5rem 0.75rem",
215
- borderRadius: "0.375rem",
216
- border: "1px solid var(--tern-border, #D1D5DB)",
217
- backgroundColor: "var(--tern-input-background, white)",
218
- color: "var(--tern-text-primary, #111827)"
219
- },
220
- button: {
221
- display: "flex",
222
- width: "100%",
223
- justifyContent: "center",
224
- padding: "0.5rem 1rem",
225
- fontSize: "0.875rem",
226
- fontWeight: "500",
227
- color: "white",
228
- backgroundColor: "var(--tern-primary, #2563EB)",
229
- border: "none",
230
- borderRadius: "0.375rem",
231
- cursor: "pointer"
232
- },
233
- error: {
234
- color: "var(--tern-error, #DC2626)",
235
- fontSize: "0.875rem"
236
- }
237
- };
238
- var styles = createStyleSheet(styleConfig);
239
- function SignIn({
240
- onSuccess,
241
- onError,
242
- redirectUrl,
243
- className = "",
244
- style,
245
- customStyles = {}
246
- }) {
247
- const [email, setEmail] = react.useState("");
248
- const [password, setPassword] = react.useState("");
249
- const [loading, setLoading] = react.useState(false);
250
- const [error, setError] = react.useState("");
251
- const handleSubmit = async (e) => {
252
- e.preventDefault();
253
- setLoading(true);
254
- setError("");
255
- try {
256
- await signInWithEmail({ email, password });
257
- onSuccess?.();
258
- if (redirectUrl) {
259
- window.location.href = redirectUrl;
260
- }
261
- } catch (err) {
262
- const errorMessage = err instanceof Error ? err.message : "Failed to sign in";
263
- setError(errorMessage);
264
- onError?.(err instanceof Error ? err : new Error("Failed to sign in"));
265
- } finally {
266
- setLoading(false);
267
- }
268
- };
269
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles.container} ${customStyles.container || ""}`, style, children: [
270
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles.header} ${customStyles.header || ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: `${styles.title} ${customStyles.title || ""}`, children: "Sign in to your account" }) }),
271
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles.formWrapper} ${customStyles.formWrapper || ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles.formContainer} ${customStyles.formContainer || ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs(
272
- "form",
273
- {
274
- onSubmit: handleSubmit,
275
- className: `${styles.form} ${customStyles.form || ""} ${className}`,
276
- role: "form",
277
- "aria-label": "Sign in form",
278
- children: [
279
- error && /* @__PURE__ */ jsxRuntime.jsx(
280
- "div",
281
- {
282
- className: `${styles.error} ${customStyles.errorText || ""}`,
283
- role: "alert",
284
- "aria-live": "polite",
285
- children: error
286
- }
287
- ),
288
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
289
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "email", className: `${styles.label} ${customStyles.label || ""}`, children: "Email" }),
290
- /* @__PURE__ */ jsxRuntime.jsx(
291
- "input",
292
- {
293
- id: "email",
294
- type: "email",
295
- value: email,
296
- onChange: (e) => setEmail(e.target.value),
297
- placeholder: "Enter your email",
298
- required: true,
299
- className: `${styles.input} ${customStyles.input || ""}`,
300
- disabled: loading,
301
- "aria-required": "true",
302
- "aria-invalid": !!error
303
- }
304
- )
305
- ] }),
306
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
307
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "password", className: `${styles.label} ${customStyles.label || ""}`, children: "Password" }),
308
- /* @__PURE__ */ jsxRuntime.jsx(
309
- "input",
310
- {
311
- id: "password",
312
- type: "password",
313
- value: password,
314
- onChange: (e) => setPassword(e.target.value),
315
- placeholder: "Enter your password",
316
- required: true,
317
- className: `${styles.input} ${customStyles.input || ""}`,
318
- disabled: loading,
319
- "aria-required": "true",
320
- "aria-invalid": !!error
321
- }
322
- )
323
- ] }),
324
- /* @__PURE__ */ jsxRuntime.jsx(
325
- "button",
326
- {
327
- type: "submit",
328
- disabled: loading,
329
- className: `${styles.button} ${customStyles.button || ""}`,
330
- "data-testid": "sign-in-submit",
331
- children: loading ? "Signing in..." : "Sign in"
332
- }
333
- )
334
- ]
335
- }
336
- ) }) })
337
- ] });
338
- }
339
-
340
- exports.SignIn = SignIn;
341
- exports.TernSecureAuth = TernSecureAuth;
342
- exports.TernSecureFirestore = TernSecureFirestore;
343
- exports.TernSecureProvider = TernSecureProvider;
344
- exports.loadFireConfig = loadFireConfig;
345
- exports.signInWithEmail = signInWithEmail;
346
- exports.useAuth = useAuth;
347
- exports.validateConfig = validateConfig;
348
- //# sourceMappingURL=index.cjs.map
349
- //# sourceMappingURL=index.cjs.map
1
+ 'use strict';var Q=require('react'),app=require('firebase/app'),auth=require('firebase/auth'),firestore=require('firebase/firestore'),storage=require('firebase/storage'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Q__default=/*#__PURE__*/_interopDefault(Q);var _=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY||"",authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN||"",projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID||"",storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET||"",messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID||"",appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID||"",measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID||void 0}),R=e=>{let r=["apiKey","authDomain","projectId","storageBucket","messagingSenderId","appId"],o=[];return r.forEach(s=>{e[s]||o.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(s).toUpperCase()}`);}),{isValid:o.length===0,errors:o,config:e}},A=()=>{let e=_(),r=R(e);if(!r.isValid)throw new Error(`Firebase configuration validation failed:
2
+ ${r.errors.join(`
3
+ `)}`);return e};var O=A(),E=app.initializeApp(O),w=auth.getAuth(E);auth.setPersistence(w,auth.browserSessionPersistence);var V=firestore.getFirestore(E);storage.getStorage(E);var u=()=>w,H=()=>V;var J=Symbol("TERN_SECURE_CONTEXT"),x=Q.createContext(null);x.displayName="TernSecureContext";var F=e=>{let r=Q.useContext(x);if(!r)throw new Error(`${e} must be used within TernSecureProvider`);return r};function B({children:e}){return jsxRuntime.jsx(x.Provider,{value:{_contextKey:J},children:e})}var I=Q__default.default.createContext(null),ne=u();function D({children:e,initialState:r}){let[o,s]=Q.useState(r);return Q.useEffect(()=>{let l=auth.onAuthStateChanged(ne,t=>{s(t?{loading:!1,isSignedIn:!0,userId:t.uid,error:null}:{loading:!1,isSignedIn:!1,userId:null,error:null});});return ()=>l()},[]),jsxRuntime.jsx(B,{children:jsxRuntime.jsx(I.Provider,{value:o,children:e})})}function ie(){return jsxRuntime.jsx("div",{"aria-label":"Loading authentication",role:"status",className:"tern-secure-loading",children:jsxRuntime.jsx("span",{className:"sr-only",children:"Loading authentication..."})})}function U({children:e}){let r={loading:!0,isSignedIn:!1,userId:null,error:null};return jsxRuntime.jsx(Q__default.default.Suspense,{fallback:jsxRuntime.jsx(ie,{}),children:jsxRuntime.jsx(D,{initialState:r,children:e})})}async function b({email:e,password:r}){let o=u();return auth.signInWithEmailAndPassword(o,e,r)}function le(){F("useAuth");let e=Q.useContext(I);if(!e)throw new Error("Auth state not found");return {userId:e.userId,loading:e.loading,error:e.error,isSignedIn:e.isSignedIn}}var i="tern",P={isInjected:!1,styleElement:null},C={container:`${i}-container`,header:`${i}-header`,title:`${i}-title`,formWrapper:`${i}-formWrapper`,formContainer:`${i}-formContainer`,form:`${i}-form`,label:`${i}-label`,input:`${i}-input`,button:`${i}-button`,error:`${i}-error`};function ce(e){if(typeof window>"u"||P.isInjected)return C;let r=document.querySelector("[data-tern-secure]");r||(r=document.createElement("style"),r.setAttribute("data-tern-secure",""),document.head.appendChild(r),P.styleElement=r);let o=Object.entries(e).map(([s,l])=>{let t=C[s],p=Object.entries(l).map(([T,m])=>`${T.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${m};`).join(" ");return `.${t} { ${p} }`}).join(`
4
+ `);return r.textContent=o,P.isInjected=!0,C}var ue={container:{display:"flex",minHeight:"100%",flex:"1",flexDirection:"column",justifyContent:"center",padding:"3rem 1.5rem"},header:{margin:"0 auto",width:"100%",maxWidth:"28rem"},title:{marginTop:"1.5rem",textAlign:"center",fontSize:"1.875rem",fontWeight:"700",lineHeight:"2.25rem",letterSpacing:"-0.025em",color:"var(--tern-text-primary, #111827)"},formWrapper:{marginTop:"2.5rem",margin:"0 auto",width:"100%",maxWidth:"30rem"},formContainer:{padding:"3rem 1.5rem",boxShadow:"0 1px 3px 0 rgb(0 0 0 / 0.1)",borderRadius:"0.5rem",backgroundColor:"var(--tern-background, white)"},form:{display:"flex",flexDirection:"column",gap:"1rem"},label:{display:"block",fontSize:"0.875rem",fontWeight:"500",color:"var(--tern-text-secondary, #374151)"},input:{marginTop:"0.25rem",display:"block",width:"100%",padding:"0.5rem 0.75rem",borderRadius:"0.375rem",border:"1px solid var(--tern-border, #D1D5DB)",backgroundColor:"var(--tern-input-background, white)",color:"var(--tern-text-primary, #111827)"},button:{display:"flex",width:"100%",justifyContent:"center",padding:"0.5rem 1rem",fontSize:"0.875rem",fontWeight:"500",color:"white",backgroundColor:"var(--tern-primary, #2563EB)",border:"none",borderRadius:"0.375rem",cursor:"pointer"},error:{color:"var(--tern-error, #DC2626)",fontSize:"0.875rem"}},n=ce(ue);function de({onSuccess:e,onError:r,redirectUrl:o,className:s="",style:l,customStyles:t={}}){let[p,T]=Q.useState(""),[m,y]=Q.useState(""),[f,$]=Q.useState(!1),[S,N]=Q.useState(""),W=async c=>{c.preventDefault(),$(!0),N("");try{await b({email:p,password:m}),e?.(),o&&(window.location.href=o);}catch(g){let k=g instanceof Error?g.message:"Failed to sign in";N(k),r?.(g instanceof Error?g:new Error("Failed to sign in"));}finally{$(!1);}};return jsxRuntime.jsxs("div",{className:`${n.container} ${t.container||""}`,style:l,children:[jsxRuntime.jsx("div",{className:`${n.header} ${t.header||""}`,children:jsxRuntime.jsx("h2",{className:`${n.title} ${t.title||""}`,children:"Sign in to your account"})}),jsxRuntime.jsx("div",{className:`${n.formWrapper} ${t.formWrapper||""}`,children:jsxRuntime.jsx("div",{className:`${n.formContainer} ${t.formContainer||""}`,children:jsxRuntime.jsxs("form",{onSubmit:W,className:`${n.form} ${t.form||""} ${s}`,role:"form","aria-label":"Sign in form",children:[S&&jsxRuntime.jsx("div",{className:`${n.error} ${t.errorText||""}`,role:"alert","aria-live":"polite",children:S}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("label",{htmlFor:"email",className:`${n.label} ${t.label||""}`,children:"Email"}),jsxRuntime.jsx("input",{id:"email",type:"email",value:p,onChange:c=>T(c.target.value),placeholder:"Enter your email",required:!0,className:`${n.input} ${t.input||""}`,disabled:f,"aria-required":"true","aria-invalid":!!S})]}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("label",{htmlFor:"password",className:`${n.label} ${t.label||""}`,children:"Password"}),jsxRuntime.jsx("input",{id:"password",type:"password",value:m,onChange:c=>y(c.target.value),placeholder:"Enter your password",required:!0,className:`${n.input} ${t.input||""}`,disabled:f,"aria-required":"true","aria-invalid":!!S})]}),jsxRuntime.jsx("button",{type:"submit",disabled:f,className:`${n.button} ${t.button||""}`,"data-testid":"sign-in-submit",children:f?"Signing in...":"Sign in"})]})})})]})}var Ge=U;exports.SignIn=de;exports.TernSecureAuth=u;exports.TernSecureFirestore=H;exports.TernSecureProvider=Ge;exports.loadFireConfig=_;exports.signInWithEmail=b;exports.useAuth=le;exports.validateConfig=R;
@@ -1,4 +1 @@
1
- 'use strict';
2
-
3
- //# sourceMappingURL=types.cjs.map
4
- //# sourceMappingURL=types.cjs.map
1
+ 'use strict';
@@ -1,68 +1,3 @@
1
- 'use strict';
2
-
3
- var app = require('firebase/app');
4
- var auth$1 = require('firebase/auth');
5
- var firestore$1 = require('firebase/firestore');
6
- var storage$1 = require('firebase/storage');
7
-
8
- // src/utils/client-init.ts
9
-
10
- // src/utils/config.ts
11
- var loadFireConfig = () => ({
12
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || "",
13
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || "",
14
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || "",
15
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
16
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
17
- appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
18
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || void 0
19
- });
20
- var validateConfig = (config2) => {
21
- const requiredFields = [
22
- "apiKey",
23
- "authDomain",
24
- "projectId",
25
- "storageBucket",
26
- "messagingSenderId",
27
- "appId"
28
- ];
29
- const errors = [];
30
- requiredFields.forEach((field) => {
31
- if (!config2[field]) {
32
- errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`);
33
- }
34
- });
35
- return {
36
- isValid: errors.length === 0,
37
- errors,
38
- config: config2
39
- };
40
- };
41
- var initializeConfig = () => {
42
- const config2 = loadFireConfig();
43
- const validationResult = validateConfig(config2);
44
- if (!validationResult.isValid) {
45
- throw new Error(
46
- `Firebase configuration validation failed:
47
- ${validationResult.errors.join("\n")}`
48
- );
49
- }
50
- return config2;
51
- };
52
-
53
- // src/utils/client-init.ts
54
- var config = initializeConfig();
55
- var clientApp = app.initializeApp(config);
56
- var auth = auth$1.getAuth(clientApp);
57
- auth$1.setPersistence(auth, auth$1.browserSessionPersistence);
58
- var firestore = firestore$1.getFirestore(clientApp);
59
- var storage = storage$1.getStorage(clientApp);
60
- var TernSecureAuth = () => auth;
61
- var TernSecureFirestore = () => firestore;
62
- var TernSecureStorage = () => storage;
63
-
64
- exports.TernSecureAuth = TernSecureAuth;
65
- exports.TernSecureFirestore = TernSecureFirestore;
66
- exports.TernSecureStorage = TernSecureStorage;
67
- //# sourceMappingURL=client-init.cjs.map
68
- //# sourceMappingURL=client-init.cjs.map
1
+ 'use strict';var app=require('firebase/app'),auth=require('firebase/auth'),firestore=require('firebase/firestore'),storage=require('firebase/storage');var c=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY||"",authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN||"",projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID||"",storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET||"",messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID||"",appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID||"",measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID||void 0}),a=e=>{let r=["apiKey","authDomain","projectId","storageBucket","messagingSenderId","appId"],o=[];return r.forEach(i=>{e[i]||o.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(i).toUpperCase()}`);}),{isValid:o.length===0,errors:o,config:e}},t=()=>{let e=c(),r=a(e);if(!r.isValid)throw new Error(`Firebase configuration validation failed:
2
+ ${r.errors.join(`
3
+ `)}`);return e};var f=t(),n=app.initializeApp(f),s=auth.getAuth(n);auth.setPersistence(s,auth.browserSessionPersistence);var u=firestore.getFirestore(n),d=storage.getStorage(n),R=()=>s,P=()=>u,F=()=>d;exports.TernSecureAuth=R;exports.TernSecureFirestore=P;exports.TernSecureStorage=F;
@@ -1,50 +1,3 @@
1
- 'use strict';
2
-
3
- // src/utils/config.ts
4
- var loadFireConfig = () => ({
5
- apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || "",
6
- authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || "",
7
- projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || "",
8
- storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
9
- messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
10
- appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
11
- measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || void 0
12
- });
13
- var validateConfig = (config) => {
14
- const requiredFields = [
15
- "apiKey",
16
- "authDomain",
17
- "projectId",
18
- "storageBucket",
19
- "messagingSenderId",
20
- "appId"
21
- ];
22
- const errors = [];
23
- requiredFields.forEach((field) => {
24
- if (!config[field]) {
25
- errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`);
26
- }
27
- });
28
- return {
29
- isValid: errors.length === 0,
30
- errors,
31
- config
32
- };
33
- };
34
- var initializeConfig = () => {
35
- const config = loadFireConfig();
36
- const validationResult = validateConfig(config);
37
- if (!validationResult.isValid) {
38
- throw new Error(
39
- `Firebase configuration validation failed:
40
- ${validationResult.errors.join("\n")}`
41
- );
42
- }
43
- return config;
44
- };
45
-
46
- exports.initializeConfig = initializeConfig;
47
- exports.loadFireConfig = loadFireConfig;
48
- exports.validateConfig = validateConfig;
49
- //# sourceMappingURL=config.cjs.map
50
- //# sourceMappingURL=config.cjs.map
1
+ 'use strict';var o=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY||"",authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN||"",projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID||"",storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET||"",messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID||"",appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID||"",measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID||void 0}),s=e=>{let n=["apiKey","authDomain","projectId","storageBucket","messagingSenderId","appId"],r=[];return n.forEach(i=>{e[i]||r.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(i).toUpperCase()}`);}),{isValid:r.length===0,errors:r,config:e}},t=()=>{let e=o(),n=s(e);if(!n.isValid)throw new Error(`Firebase configuration validation failed:
2
+ ${n.errors.join(`
3
+ `)}`);return e};exports.initializeConfig=t;exports.loadFireConfig=o;exports.validateConfig=s;
@@ -1,125 +1,2 @@
1
- 'use strict';
2
-
3
- // src/utils/create-styles.ts
4
- var PREFIX = "tern";
5
- var styleInjection = {
6
- isInjected: false,
7
- styleElement: null
8
- };
9
- var defaultClassNames = {
10
- container: `${PREFIX}-container`,
11
- header: `${PREFIX}-header`,
12
- title: `${PREFIX}-title`,
13
- formWrapper: `${PREFIX}-formWrapper`,
14
- formContainer: `${PREFIX}-formContainer`,
15
- form: `${PREFIX}-form`,
16
- label: `${PREFIX}-label`,
17
- input: `${PREFIX}-input`,
18
- button: `${PREFIX}-button`,
19
- error: `${PREFIX}-error`
20
- };
21
- function createStyleSheet(styles2) {
22
- if (typeof window === "undefined") return defaultClassNames;
23
- if (styleInjection.isInjected) {
24
- return defaultClassNames;
25
- }
26
- let styleElement = document.querySelector("[data-tern-secure]");
27
- if (!styleElement) {
28
- styleElement = document.createElement("style");
29
- styleElement.setAttribute("data-tern-secure", "");
30
- document.head.appendChild(styleElement);
31
- styleInjection.styleElement = styleElement;
32
- }
33
- const cssRules = Object.entries(styles2).map(([key, rules]) => {
34
- const className = defaultClassNames[key];
35
- const cssProperties = Object.entries(rules).map(([prop, value]) => {
36
- const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
37
- return `${cssProperty}: ${value};`;
38
- }).join(" ");
39
- return `.${className} { ${cssProperties} }`;
40
- }).join("\n");
41
- styleElement.textContent = cssRules;
42
- styleInjection.isInjected = true;
43
- return defaultClassNames;
44
- }
45
- var styleConfig = {
46
- container: {
47
- display: "flex",
48
- minHeight: "100%",
49
- flex: "1",
50
- flexDirection: "column",
51
- justifyContent: "center",
52
- padding: "3rem 1.5rem"
53
- },
54
- header: {
55
- margin: "0 auto",
56
- width: "100%",
57
- maxWidth: "28rem"
58
- },
59
- title: {
60
- marginTop: "1.5rem",
61
- textAlign: "center",
62
- fontSize: "1.875rem",
63
- fontWeight: "700",
64
- lineHeight: "2.25rem",
65
- letterSpacing: "-0.025em",
66
- color: "var(--tern-text-primary, #111827)"
67
- },
68
- formWrapper: {
69
- marginTop: "2.5rem",
70
- margin: "0 auto",
71
- width: "100%",
72
- maxWidth: "30rem"
73
- },
74
- formContainer: {
75
- padding: "3rem 1.5rem",
76
- boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)",
77
- borderRadius: "0.5rem",
78
- backgroundColor: "var(--tern-background, white)"
79
- },
80
- form: {
81
- display: "flex",
82
- flexDirection: "column",
83
- gap: "1rem"
84
- },
85
- label: {
86
- display: "block",
87
- fontSize: "0.875rem",
88
- fontWeight: "500",
89
- color: "var(--tern-text-secondary, #374151)"
90
- },
91
- input: {
92
- marginTop: "0.25rem",
93
- display: "block",
94
- width: "100%",
95
- padding: "0.5rem 0.75rem",
96
- borderRadius: "0.375rem",
97
- border: "1px solid var(--tern-border, #D1D5DB)",
98
- backgroundColor: "var(--tern-input-background, white)",
99
- color: "var(--tern-text-primary, #111827)"
100
- },
101
- button: {
102
- display: "flex",
103
- width: "100%",
104
- justifyContent: "center",
105
- padding: "0.5rem 1rem",
106
- fontSize: "0.875rem",
107
- fontWeight: "500",
108
- color: "white",
109
- backgroundColor: "var(--tern-primary, #2563EB)",
110
- border: "none",
111
- borderRadius: "0.375rem",
112
- cursor: "pointer"
113
- },
114
- error: {
115
- color: "var(--tern-error, #DC2626)",
116
- fontSize: "0.875rem"
117
- }
118
- };
119
- var styles = createStyleSheet(styleConfig);
120
-
121
- exports.defaultClassNames = defaultClassNames;
122
- exports.styleConfig = styleConfig;
123
- exports.styles = styles;
124
- //# sourceMappingURL=create-styles.cjs.map
125
- //# sourceMappingURL=create-styles.cjs.map
1
+ 'use strict';var e="tern",n={isInjected:!1,styleElement:null},t={container:`${e}-container`,header:`${e}-header`,title:`${e}-title`,formWrapper:`${e}-formWrapper`,formContainer:`${e}-formContainer`,form:`${e}-form`,label:`${e}-label`,input:`${e}-input`,button:`${e}-button`,error:`${e}-error`};function p(o){if(typeof window>"u"||n.isInjected)return t;let r=document.querySelector("[data-tern-secure]");r||(r=document.createElement("style"),r.setAttribute("data-tern-secure",""),document.head.appendChild(r),n.styleElement=r);let i=Object.entries(o).map(([a,l])=>{let s=t[a],c=Object.entries(l).map(([m,d])=>`${m.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${d};`).join(" ");return `.${s} { ${c} }`}).join(`
2
+ `);return r.textContent=i,n.isInjected=!0,t}var u={container:{display:"flex",minHeight:"100%",flex:"1",flexDirection:"column",justifyContent:"center",padding:"3rem 1.5rem"},header:{margin:"0 auto",width:"100%",maxWidth:"28rem"},title:{marginTop:"1.5rem",textAlign:"center",fontSize:"1.875rem",fontWeight:"700",lineHeight:"2.25rem",letterSpacing:"-0.025em",color:"var(--tern-text-primary, #111827)"},formWrapper:{marginTop:"2.5rem",margin:"0 auto",width:"100%",maxWidth:"30rem"},formContainer:{padding:"3rem 1.5rem",boxShadow:"0 1px 3px 0 rgb(0 0 0 / 0.1)",borderRadius:"0.5rem",backgroundColor:"var(--tern-background, white)"},form:{display:"flex",flexDirection:"column",gap:"1rem"},label:{display:"block",fontSize:"0.875rem",fontWeight:"500",color:"var(--tern-text-secondary, #374151)"},input:{marginTop:"0.25rem",display:"block",width:"100%",padding:"0.5rem 0.75rem",borderRadius:"0.375rem",border:"1px solid var(--tern-border, #D1D5DB)",backgroundColor:"var(--tern-input-background, white)",color:"var(--tern-text-primary, #111827)"},button:{display:"flex",width:"100%",justifyContent:"center",padding:"0.5rem 1rem",fontSize:"0.875rem",fontWeight:"500",color:"white",backgroundColor:"var(--tern-primary, #2563EB)",border:"none",borderRadius:"0.375rem",cursor:"pointer"},error:{color:"var(--tern-error, #DC2626)",fontSize:"0.875rem"}},y=p(u);exports.defaultClassNames=t;exports.styleConfig=u;exports.styles=y;
@@ -1,16 +1,17 @@
1
- import React__default, { ReactNode } from 'react';
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
2
3
 
3
- interface AuthState {
4
+ type TernSecureState = {
4
5
  userId: string | null;
5
6
  loading: boolean;
6
7
  error: string | null;
7
8
  isSignedIn: boolean;
9
+ };
10
+ declare const AuthStateContext: React__default.Context<TernSecureState | null>;
11
+ interface TernSecureClientProps {
12
+ children: React__default.ReactNode;
13
+ initialState: TernSecureState;
8
14
  }
9
- interface TernSecureProviderProps {
10
- children: ReactNode;
11
- }
12
- declare const TernSecureClientProvider: React__default.FC<TernSecureProviderProps & {
13
- initialState: AuthState;
14
- }>;
15
+ declare function TernSecureClientProvider({ children, initialState }: TernSecureClientProps): react_jsx_runtime.JSX.Element;
15
16
 
16
- export { type AuthState, TernSecureClientProvider, type TernSecureProviderProps };
17
+ export { AuthStateContext, TernSecureClientProvider, type TernSecureState };
@@ -1,6 +1,3 @@
1
- export { TernSecureClientProvider } from '../../chunk-ODVOZOJG.js';
2
- import '../../chunk-7VKPI5HF.js';
3
- import '../../chunk-FVV74XVR.js';
4
- import '../../chunk-UHGBSUM6.js';
5
- //# sourceMappingURL=TernSecureProvider.js.map
6
- //# sourceMappingURL=TernSecureProvider.js.map
1
+ import R,{createContext,useState,useEffect}from'react';import {initializeApp}from'firebase/app';import {getAuth,setPersistence,browserSessionPersistence,onAuthStateChanged}from'firebase/auth';import {getFirestore}from'firebase/firestore';import {getStorage}from'firebase/storage';import {jsx}from'react/jsx-runtime';var d=()=>({apiKey:process.env.NEXT_PUBLIC_FIREBASE_API_KEY||"",authDomain:process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN||"",projectId:process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID||"",storageBucket:process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET||"",messagingSenderId:process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID||"",appId:process.env.NEXT_PUBLIC_FIREBASE_APP_ID||"",measurementId:process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID||void 0}),E=e=>{let r=["apiKey","authDomain","projectId","storageBucket","messagingSenderId","appId"],t=[];return r.forEach(n=>{e[n]||t.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(n).toUpperCase()}`);}),{isValid:t.length===0,errors:t,config:e}},s=()=>{let e=d(),r=E(e);if(!r.isValid)throw new Error(`Firebase configuration validation failed:
2
+ ${r.errors.join(`
3
+ `)}`);return e};var m=s(),o=initializeApp(m),c=getAuth(o);setPersistence(c,browserSessionPersistence);getFirestore(o);getStorage(o);var u=()=>c;var A=Symbol("TERN_SECURE_CONTEXT"),a=createContext(null);a.displayName="TernSecureContext";function l({children:e}){return jsx(a.Provider,{value:{_contextKey:A},children:e})}var B=R.createContext(null),F=u();function H({children:e,initialState:r}){let[t,n]=useState(r);return useEffect(()=>{let p=onAuthStateChanged(F,i=>{n(i?{loading:!1,isSignedIn:!0,userId:i.uid,error:null}:{loading:!1,isSignedIn:!1,userId:null,error:null});});return ()=>p()},[]),jsx(l,{children:jsx(B.Provider,{value:t,children:e})})}export{B as AuthStateContext,H as TernSecureClientProvider};