@cyberia-auth/auth 0.1.0 → 0.1.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.
- package/README.md +2 -0
- package/dist/index.cjs +125 -67
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +125 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,7 @@ Props:
|
|
|
69
69
|
- `apiToken: string` - app API token
|
|
70
70
|
- `oauthRedirectUri?: string` - redirect URL for Google/Microsoft OAuth
|
|
71
71
|
- `initialMode?: 'login' | 'register'` - default mode
|
|
72
|
+
- `theme?: 'system' | 'light' | 'dark'` - color mode (`system` by default)
|
|
72
73
|
- `hideModeSwitch?: boolean` - hide sign-in/sign-up toggle footer
|
|
73
74
|
- `onAuthSuccess?: (result) => void` - callback with `{ token, user }`
|
|
74
75
|
|
|
@@ -81,6 +82,7 @@ Props:
|
|
|
81
82
|
- `backendUrl: string`
|
|
82
83
|
- `apiToken: string`
|
|
83
84
|
- `oauthRedirectUri?: string`
|
|
85
|
+
- `theme?: 'system' | 'light' | 'dark'` - applies to modal + `UserButton` UI
|
|
84
86
|
- `children: ReactNode`
|
|
85
87
|
- `storageKey?: string` - localStorage key override (default `cyberia_auth_session`)
|
|
86
88
|
|
package/dist/index.cjs
CHANGED
|
@@ -60,10 +60,13 @@ function CyberiaAuth({
|
|
|
60
60
|
apiToken,
|
|
61
61
|
oauthRedirectUri,
|
|
62
62
|
initialMode = "register",
|
|
63
|
+
theme = "system",
|
|
63
64
|
hideModeSwitch = false,
|
|
64
65
|
onAuthSuccess
|
|
65
66
|
}) {
|
|
66
67
|
const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
|
|
68
|
+
const resolvedTheme = useResolvedTheme(theme);
|
|
69
|
+
const palette = getThemePalette(resolvedTheme);
|
|
67
70
|
const [mode, setMode] = (0, import_react.useState)(initialMode);
|
|
68
71
|
const [config, setConfig] = (0, import_react.useState)(() => getCachedAppConfig(apiToken));
|
|
69
72
|
const [isBrandingResolved, setIsBrandingResolved] = (0, import_react.useState)(
|
|
@@ -140,15 +143,15 @@ function CyberiaAuth({
|
|
|
140
143
|
"div",
|
|
141
144
|
{
|
|
142
145
|
style: {
|
|
143
|
-
border:
|
|
146
|
+
border: `1px solid ${palette.border}`,
|
|
144
147
|
borderRadius: 14,
|
|
145
148
|
padding: 20,
|
|
146
|
-
background:
|
|
149
|
+
background: palette.surface,
|
|
147
150
|
fontFamily: "Inter, Arial, sans-serif",
|
|
148
151
|
minHeight: 320,
|
|
149
152
|
display: "grid",
|
|
150
153
|
placeItems: "center",
|
|
151
|
-
color:
|
|
154
|
+
color: palette.textMuted
|
|
152
155
|
},
|
|
153
156
|
children: "Loading sign-in..."
|
|
154
157
|
}
|
|
@@ -158,15 +161,16 @@ function CyberiaAuth({
|
|
|
158
161
|
"div",
|
|
159
162
|
{
|
|
160
163
|
style: {
|
|
161
|
-
border:
|
|
164
|
+
border: `1px solid ${palette.border}`,
|
|
162
165
|
borderRadius: 14,
|
|
163
166
|
padding: 0,
|
|
164
|
-
background:
|
|
167
|
+
background: palette.surface,
|
|
165
168
|
overflow: "hidden",
|
|
166
169
|
fontFamily: "Inter, Arial, sans-serif",
|
|
167
170
|
width: "100%",
|
|
168
171
|
maxWidth: 500,
|
|
169
|
-
margin: "0 auto"
|
|
172
|
+
margin: "0 auto",
|
|
173
|
+
color: palette.text
|
|
170
174
|
},
|
|
171
175
|
children: [
|
|
172
176
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: 20, display: "grid", gap: 14 }, children: [
|
|
@@ -190,15 +194,15 @@ function CyberiaAuth({
|
|
|
190
194
|
),
|
|
191
195
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { textAlign: "center" }, children: [
|
|
192
196
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: "0 0 6px 0", fontSize: 16 }, children: title }),
|
|
193
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { margin: 0, color:
|
|
197
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { margin: 0, color: palette.textMuted, fontSize: 13 }, children: subtitle })
|
|
194
198
|
] })
|
|
195
199
|
] }),
|
|
196
200
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: [
|
|
197
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("google"), children: [
|
|
201
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("google"), children: [
|
|
198
202
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GoogleIcon, {}),
|
|
199
203
|
"Google"
|
|
200
204
|
] }),
|
|
201
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("microsoft"), children: [
|
|
205
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("microsoft"), children: [
|
|
202
206
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MicrosoftIcon, {}),
|
|
203
207
|
"Microsoft"
|
|
204
208
|
] })
|
|
@@ -213,14 +217,14 @@ function CyberiaAuth({
|
|
|
213
217
|
gap: 12
|
|
214
218
|
},
|
|
215
219
|
children: [
|
|
216
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background:
|
|
217
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color:
|
|
218
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background:
|
|
220
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: palette.border } }),
|
|
221
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: palette.textMuted, fontSize: 14 }, children: "or" }),
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { height: 1, background: palette.border } })
|
|
219
223
|
]
|
|
220
224
|
}
|
|
221
225
|
),
|
|
222
226
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, style: { display: "grid", gap: 10 }, children: [
|
|
223
|
-
mode === "register" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
|
|
227
|
+
mode === "register" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
|
|
224
228
|
"Full name",
|
|
225
229
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
226
230
|
"input",
|
|
@@ -228,15 +232,15 @@ function CyberiaAuth({
|
|
|
228
232
|
name: "displayName",
|
|
229
233
|
placeholder: "Enter your full name",
|
|
230
234
|
required: true,
|
|
231
|
-
style: inputStyle
|
|
235
|
+
style: inputStyle(palette)
|
|
232
236
|
}
|
|
233
237
|
)
|
|
234
238
|
] }),
|
|
235
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
|
|
239
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
|
|
236
240
|
"Email address",
|
|
237
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle })
|
|
241
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle(palette) })
|
|
238
242
|
] }),
|
|
239
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle, children: [
|
|
243
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: fieldLabelStyle(palette), children: [
|
|
240
244
|
"Password",
|
|
241
245
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
242
246
|
"input",
|
|
@@ -246,7 +250,7 @@ function CyberiaAuth({
|
|
|
246
250
|
placeholder: "Enter your password",
|
|
247
251
|
minLength: 8,
|
|
248
252
|
required: true,
|
|
249
|
-
style: inputStyle
|
|
253
|
+
style: inputStyle(palette)
|
|
250
254
|
}
|
|
251
255
|
)
|
|
252
256
|
] }),
|
|
@@ -274,10 +278,11 @@ function CyberiaAuth({
|
|
|
274
278
|
"div",
|
|
275
279
|
{
|
|
276
280
|
style: {
|
|
277
|
-
borderTop:
|
|
281
|
+
borderTop: `1px solid ${palette.border}`,
|
|
278
282
|
padding: 14,
|
|
279
283
|
textAlign: "center",
|
|
280
|
-
|
|
284
|
+
fontSize: 13,
|
|
285
|
+
background: palette.surfaceAlt
|
|
281
286
|
},
|
|
282
287
|
children: [
|
|
283
288
|
mode === "login" ? "Don't have an account? " : "Already have an account? ",
|
|
@@ -289,7 +294,7 @@ function CyberiaAuth({
|
|
|
289
294
|
style: {
|
|
290
295
|
border: "none",
|
|
291
296
|
background: "transparent",
|
|
292
|
-
color:
|
|
297
|
+
color: palette.text,
|
|
293
298
|
textDecoration: "underline",
|
|
294
299
|
fontWeight: 600,
|
|
295
300
|
cursor: "pointer",
|
|
@@ -310,10 +315,12 @@ function CyberiaAuthProvider({
|
|
|
310
315
|
backendUrl,
|
|
311
316
|
apiToken,
|
|
312
317
|
oauthRedirectUri,
|
|
318
|
+
theme = "system",
|
|
313
319
|
children,
|
|
314
320
|
storageKey = "cyberia_auth_session"
|
|
315
321
|
}) {
|
|
316
322
|
const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
|
|
323
|
+
const resolvedTheme = useResolvedTheme(theme);
|
|
317
324
|
const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
|
|
318
325
|
const [session, setSession] = (0, import_react.useState)(null);
|
|
319
326
|
const [modalOpen, setModalOpen] = (0, import_react.useState)(false);
|
|
@@ -386,9 +393,10 @@ function CyberiaAuthProvider({
|
|
|
386
393
|
setModalOpen(true);
|
|
387
394
|
},
|
|
388
395
|
signOut,
|
|
389
|
-
setSessionFromAuth
|
|
396
|
+
setSessionFromAuth,
|
|
397
|
+
theme: resolvedTheme
|
|
390
398
|
}),
|
|
391
|
-
[isLoaded, session, setSessionFromAuth]
|
|
399
|
+
[isLoaded, resolvedTheme, session, setSessionFromAuth]
|
|
392
400
|
);
|
|
393
401
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CyberiaAuthContext.Provider, { value, children: [
|
|
394
402
|
children,
|
|
@@ -416,6 +424,7 @@ function CyberiaAuthProvider({
|
|
|
416
424
|
backendUrl: backendBaseUrl,
|
|
417
425
|
apiToken,
|
|
418
426
|
oauthRedirectUri,
|
|
427
|
+
theme,
|
|
419
428
|
initialMode: modalMode,
|
|
420
429
|
hideModeSwitch: false,
|
|
421
430
|
onAuthSuccess: (result) => {
|
|
@@ -474,7 +483,8 @@ function SignOutButton({ children }) {
|
|
|
474
483
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: signOut, children: children ?? "Sign out" });
|
|
475
484
|
}
|
|
476
485
|
function UserButton() {
|
|
477
|
-
const { user, signOut, openSignIn, openSignUp } = useCyberiaAuth();
|
|
486
|
+
const { user, signOut, openSignIn, openSignUp, theme } = useCyberiaAuth();
|
|
487
|
+
const palette = getThemePalette(theme);
|
|
478
488
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
479
489
|
const [manageOpen, setManageOpen] = (0, import_react.useState)(false);
|
|
480
490
|
const [tab, setTab] = (0, import_react.useState)("profile");
|
|
@@ -505,8 +515,9 @@ function UserButton() {
|
|
|
505
515
|
width: 36,
|
|
506
516
|
height: 36,
|
|
507
517
|
borderRadius: 999,
|
|
508
|
-
border:
|
|
509
|
-
background:
|
|
518
|
+
border: `1px solid ${palette.border}`,
|
|
519
|
+
background: palette.surface,
|
|
520
|
+
color: palette.text,
|
|
510
521
|
fontWeight: 700,
|
|
511
522
|
cursor: "pointer"
|
|
512
523
|
},
|
|
@@ -522,8 +533,8 @@ function UserButton() {
|
|
|
522
533
|
right: 0,
|
|
523
534
|
top: 42,
|
|
524
535
|
minWidth: 320,
|
|
525
|
-
background:
|
|
526
|
-
border:
|
|
536
|
+
background: palette.surface,
|
|
537
|
+
border: `1px solid ${palette.border}`,
|
|
527
538
|
borderRadius: 12,
|
|
528
539
|
boxShadow: "0 12px 24px rgba(0,0,0,0.08)",
|
|
529
540
|
padding: 0,
|
|
@@ -538,22 +549,22 @@ function UserButton() {
|
|
|
538
549
|
width: 44,
|
|
539
550
|
height: 44,
|
|
540
551
|
borderRadius: 999,
|
|
541
|
-
border:
|
|
552
|
+
border: `1px solid ${palette.border}`,
|
|
542
553
|
display: "grid",
|
|
543
554
|
placeItems: "center",
|
|
544
555
|
fontWeight: 700,
|
|
545
|
-
color:
|
|
546
|
-
background:
|
|
556
|
+
color: palette.text,
|
|
557
|
+
background: palette.surfaceAlt
|
|
547
558
|
},
|
|
548
559
|
children: initials
|
|
549
560
|
}
|
|
550
561
|
),
|
|
551
562
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid" }, children: [
|
|
552
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 16, color:
|
|
553
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color:
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { fontSize: 16, color: palette.text, lineHeight: 1.2 }, children: profileName }),
|
|
564
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: palette.text, fontSize: 14 }, children: profileEmail })
|
|
554
565
|
] })
|
|
555
566
|
] }),
|
|
556
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop:
|
|
567
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: 0 } }),
|
|
557
568
|
!user && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
558
569
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
559
570
|
"button",
|
|
@@ -607,9 +618,9 @@ function UserButton() {
|
|
|
607
618
|
}
|
|
608
619
|
)
|
|
609
620
|
] }),
|
|
610
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop:
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop: `1px solid ${palette.border}`, textAlign: "center", padding: "12px 10px", color: palette.textMuted, fontSize: 13 }, children: [
|
|
611
622
|
"Secured by ",
|
|
612
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "
|
|
623
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Cyberia Auth" })
|
|
613
624
|
] })
|
|
614
625
|
]
|
|
615
626
|
}
|
|
@@ -634,9 +645,9 @@ function UserButton() {
|
|
|
634
645
|
width: "100%",
|
|
635
646
|
maxWidth: 940,
|
|
636
647
|
minHeight: 540,
|
|
637
|
-
background:
|
|
648
|
+
background: palette.surface,
|
|
638
649
|
borderRadius: 10,
|
|
639
|
-
border:
|
|
650
|
+
border: `1px solid ${palette.border}`,
|
|
640
651
|
display: "grid",
|
|
641
652
|
gridTemplateColumns: "220px 1fr",
|
|
642
653
|
overflow: "hidden"
|
|
@@ -647,15 +658,15 @@ function UserButton() {
|
|
|
647
658
|
"aside",
|
|
648
659
|
{
|
|
649
660
|
style: {
|
|
650
|
-
borderRight:
|
|
661
|
+
borderRight: `1px solid ${palette.border}`,
|
|
651
662
|
padding: 22,
|
|
652
|
-
background:
|
|
663
|
+
background: palette.surfaceAlt,
|
|
653
664
|
display: "flex",
|
|
654
665
|
flexDirection: "column"
|
|
655
666
|
},
|
|
656
667
|
children: [
|
|
657
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: { margin: 0, fontSize: 30, color:
|
|
658
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { marginTop: 6, color:
|
|
668
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: { margin: 0, fontSize: 30, color: palette.text }, children: "Account" }),
|
|
669
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { marginTop: 6, color: palette.textMuted, fontSize: 12 }, children: "Manage your account info." }),
|
|
659
670
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: 20, display: "grid", gap: 8 }, children: [
|
|
660
671
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
661
672
|
"button",
|
|
@@ -664,8 +675,8 @@ function UserButton() {
|
|
|
664
675
|
onClick: () => setTab("profile"),
|
|
665
676
|
style: {
|
|
666
677
|
...tabButtonStyle,
|
|
667
|
-
background: tab === "profile" ? "#
|
|
668
|
-
color: tab === "profile" ? "#
|
|
678
|
+
background: tab === "profile" ? "#ffe8e8" : "transparent",
|
|
679
|
+
color: tab === "profile" ? "#d92828" : palette.textMuted
|
|
669
680
|
},
|
|
670
681
|
children: "Profile"
|
|
671
682
|
}
|
|
@@ -677,14 +688,14 @@ function UserButton() {
|
|
|
677
688
|
onClick: () => setTab("security"),
|
|
678
689
|
style: {
|
|
679
690
|
...tabButtonStyle,
|
|
680
|
-
background: tab === "security" ? "#
|
|
681
|
-
color: tab === "security" ? "#
|
|
691
|
+
background: tab === "security" ? "#ffe8e8" : "transparent",
|
|
692
|
+
color: tab === "security" ? "#d92828" : palette.textMuted
|
|
682
693
|
},
|
|
683
694
|
children: "Security"
|
|
684
695
|
}
|
|
685
696
|
)
|
|
686
697
|
] }),
|
|
687
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "auto", paddingTop: 24, color:
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "auto", paddingTop: 24, color: palette.textMuted, fontSize: 15 }, children: [
|
|
688
699
|
"Secure by ",
|
|
689
700
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Cyberia Auth" })
|
|
690
701
|
] })
|
|
@@ -693,7 +704,7 @@ function UserButton() {
|
|
|
693
704
|
),
|
|
694
705
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { style: { padding: 26 }, children: [
|
|
695
706
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
696
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: 0, fontSize: 22, color:
|
|
707
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: { margin: 0, fontSize: 22, color: palette.text }, children: tab === "profile" ? "Profile details" : "Security" }),
|
|
697
708
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
698
709
|
"button",
|
|
699
710
|
{
|
|
@@ -704,10 +715,10 @@ function UserButton() {
|
|
|
704
715
|
}
|
|
705
716
|
)
|
|
706
717
|
] }),
|
|
707
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop:
|
|
718
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: "16px 0 20px" } }),
|
|
708
719
|
tab === "profile" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 20 }, children: [
|
|
709
720
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
|
|
710
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#
|
|
721
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Profile" }),
|
|
711
722
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
712
723
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: avatarLargeStyle, children: initials }),
|
|
713
724
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: profileName })
|
|
@@ -715,25 +726,25 @@ function UserButton() {
|
|
|
715
726
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Update profile" })
|
|
716
727
|
] }),
|
|
717
728
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
|
|
718
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Email addresses" }),
|
|
719
730
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: profileEmail }),
|
|
720
731
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#6b7280", fontSize: 14 }, children: "Primary" })
|
|
721
732
|
] }),
|
|
722
733
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
|
|
723
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Connected accounts" }),
|
|
724
735
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 16 }, children: "Google / Microsoft" }),
|
|
725
736
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Connect account" })
|
|
726
737
|
] })
|
|
727
738
|
] }),
|
|
728
739
|
tab === "security" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 20 }, children: [
|
|
729
740
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
|
|
730
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#
|
|
741
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Password" }),
|
|
731
742
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {}),
|
|
732
743
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: linkButtonStyle, children: "Set password" })
|
|
733
744
|
] }),
|
|
734
745
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...profileRowStyle, alignItems: "start" }, children: [
|
|
735
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#
|
|
736
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 14, color: "#
|
|
746
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Active devices" }),
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 14, color: "#c5c7ca", maxWidth: 430 }, children: userAgent }),
|
|
737
748
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#6b7280", fontSize: 14 }, children: "This device" })
|
|
738
749
|
] }),
|
|
739
750
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: profileRowStyle, children: [
|
|
@@ -787,25 +798,28 @@ var menuItemButtonStyle = {
|
|
|
787
798
|
background: "transparent",
|
|
788
799
|
cursor: "pointer"
|
|
789
800
|
};
|
|
790
|
-
var inputStyle = {
|
|
801
|
+
var inputStyle = (palette) => ({
|
|
791
802
|
width: "100%",
|
|
792
803
|
padding: 11,
|
|
793
804
|
borderRadius: 9,
|
|
794
|
-
border:
|
|
805
|
+
border: `1px solid ${palette.border}`,
|
|
806
|
+
background: palette.surface,
|
|
807
|
+
color: palette.text,
|
|
795
808
|
fontSize: 13
|
|
796
|
-
};
|
|
797
|
-
var fieldLabelStyle = {
|
|
809
|
+
});
|
|
810
|
+
var fieldLabelStyle = (palette) => ({
|
|
798
811
|
display: "grid",
|
|
799
812
|
gap: 6,
|
|
800
813
|
fontSize: 14,
|
|
801
|
-
color:
|
|
814
|
+
color: palette.text,
|
|
802
815
|
fontWeight: 600
|
|
803
|
-
};
|
|
804
|
-
var socialButtonStyle = {
|
|
805
|
-
border:
|
|
816
|
+
});
|
|
817
|
+
var socialButtonStyle = (palette) => ({
|
|
818
|
+
border: `1px solid ${palette.border}`,
|
|
806
819
|
borderRadius: 9,
|
|
807
820
|
padding: "10px 12px",
|
|
808
|
-
background:
|
|
821
|
+
background: palette.surface,
|
|
822
|
+
color: palette.text,
|
|
809
823
|
cursor: "pointer",
|
|
810
824
|
fontSize: 16,
|
|
811
825
|
fontWeight: 300,
|
|
@@ -813,7 +827,7 @@ var socialButtonStyle = {
|
|
|
813
827
|
alignItems: "center",
|
|
814
828
|
justifyContent: "center",
|
|
815
829
|
gap: 8
|
|
816
|
-
};
|
|
830
|
+
});
|
|
817
831
|
function GoogleIcon() {
|
|
818
832
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", height: "20", viewBox: "0 0 20 20", width: "20", "aria-hidden": "true", children: [
|
|
819
833
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19.9905 10.1871C19.9905 9.36773 19.9224 8.7698 19.7752 8.14972H10.1992V11.848H15.8201C15.7068 12.7671 15.0948 14.1512 13.7349 15.0813L13.7159 15.2051L16.7436 17.497L16.9534 17.5174C18.8798 15.779 19.9905 13.2211 19.9905 10.1871Z", fill: "#4285F4" }),
|
|
@@ -841,6 +855,50 @@ function resolveBackendBaseUrl(backendUrl) {
|
|
|
841
855
|
const candidate = backendUrl?.trim() || DEFAULT_BACKEND_URL;
|
|
842
856
|
return candidate.replace(/\/+$/, "");
|
|
843
857
|
}
|
|
858
|
+
function getThemePalette(theme) {
|
|
859
|
+
if (theme === "dark") {
|
|
860
|
+
return {
|
|
861
|
+
surface: "#445364",
|
|
862
|
+
surfaceAlt: "#1f2937",
|
|
863
|
+
border: "#374151",
|
|
864
|
+
text: "#f9fafb",
|
|
865
|
+
textMuted: "#9ca3af"
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
return {
|
|
869
|
+
surface: "#ffffff",
|
|
870
|
+
surfaceAlt: "#fafafa",
|
|
871
|
+
border: "#e5e7eb",
|
|
872
|
+
text: "#111827",
|
|
873
|
+
textMuted: "#6b7280"
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
function useResolvedTheme(theme) {
|
|
877
|
+
const [resolvedTheme, setResolvedTheme] = (0, import_react.useState)(() => {
|
|
878
|
+
if (theme === "light" || theme === "dark") {
|
|
879
|
+
return theme;
|
|
880
|
+
}
|
|
881
|
+
if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
882
|
+
return "dark";
|
|
883
|
+
}
|
|
884
|
+
return "light";
|
|
885
|
+
});
|
|
886
|
+
(0, import_react.useEffect)(() => {
|
|
887
|
+
if (theme === "light" || theme === "dark") {
|
|
888
|
+
setResolvedTheme(theme);
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
if (typeof window === "undefined") {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
895
|
+
const updateTheme = () => setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
896
|
+
updateTheme();
|
|
897
|
+
mediaQuery.addEventListener("change", updateTheme);
|
|
898
|
+
return () => mediaQuery.removeEventListener("change", updateTheme);
|
|
899
|
+
}, [theme]);
|
|
900
|
+
return resolvedTheme;
|
|
901
|
+
}
|
|
844
902
|
function getBrandingCacheKey(apiToken) {
|
|
845
903
|
return `cyberia_auth_branding:${apiToken}`;
|
|
846
904
|
}
|
|
@@ -887,7 +945,7 @@ var tabButtonStyle = {
|
|
|
887
945
|
};
|
|
888
946
|
var profileRowStyle = {
|
|
889
947
|
display: "grid",
|
|
890
|
-
gridTemplateColumns: "
|
|
948
|
+
gridTemplateColumns: "150px 1fr auto",
|
|
891
949
|
alignItems: "center",
|
|
892
950
|
gap: 12,
|
|
893
951
|
paddingBottom: 12,
|
|
@@ -907,7 +965,7 @@ var avatarLargeStyle = {
|
|
|
907
965
|
var linkButtonStyle = {
|
|
908
966
|
border: "none",
|
|
909
967
|
background: "transparent",
|
|
910
|
-
color: "#
|
|
968
|
+
color: "#d92828",
|
|
911
969
|
cursor: "pointer",
|
|
912
970
|
fontSize: 14
|
|
913
971
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
type AuthMode = 'register' | 'login';
|
|
5
|
+
type ThemeMode = 'system' | 'light' | 'dark';
|
|
6
|
+
type ResolvedTheme = 'light' | 'dark';
|
|
5
7
|
type AuthUser = {
|
|
6
8
|
id: string;
|
|
7
9
|
email: string;
|
|
@@ -16,10 +18,11 @@ type CyberiaAuthProps = {
|
|
|
16
18
|
apiToken: string;
|
|
17
19
|
oauthRedirectUri?: string;
|
|
18
20
|
initialMode?: AuthMode;
|
|
21
|
+
theme?: ThemeMode;
|
|
19
22
|
hideModeSwitch?: boolean;
|
|
20
23
|
onAuthSuccess?: (data: AuthResult) => void;
|
|
21
24
|
};
|
|
22
|
-
declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, theme, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
|
|
23
26
|
type CyberiaAuthContextValue = {
|
|
24
27
|
isLoaded: boolean;
|
|
25
28
|
isSignedIn: boolean;
|
|
@@ -29,15 +32,17 @@ type CyberiaAuthContextValue = {
|
|
|
29
32
|
openSignUp: () => void;
|
|
30
33
|
signOut: () => void;
|
|
31
34
|
setSessionFromAuth: (result: AuthResult) => void;
|
|
35
|
+
theme: ResolvedTheme;
|
|
32
36
|
};
|
|
33
37
|
type CyberiaAuthProviderProps = {
|
|
34
38
|
backendUrl?: string;
|
|
35
39
|
apiToken: string;
|
|
36
40
|
oauthRedirectUri?: string;
|
|
41
|
+
theme?: ThemeMode;
|
|
37
42
|
children: ReactNode;
|
|
38
43
|
storageKey?: string;
|
|
39
44
|
};
|
|
40
|
-
declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
45
|
+
declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, theme, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
41
46
|
declare function useCyberiaAuth(): CyberiaAuthContextValue;
|
|
42
47
|
declare function Show({ when, children }: {
|
|
43
48
|
when: 'signed-in' | 'signed-out';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
type AuthMode = 'register' | 'login';
|
|
5
|
+
type ThemeMode = 'system' | 'light' | 'dark';
|
|
6
|
+
type ResolvedTheme = 'light' | 'dark';
|
|
5
7
|
type AuthUser = {
|
|
6
8
|
id: string;
|
|
7
9
|
email: string;
|
|
@@ -16,10 +18,11 @@ type CyberiaAuthProps = {
|
|
|
16
18
|
apiToken: string;
|
|
17
19
|
oauthRedirectUri?: string;
|
|
18
20
|
initialMode?: AuthMode;
|
|
21
|
+
theme?: ThemeMode;
|
|
19
22
|
hideModeSwitch?: boolean;
|
|
20
23
|
onAuthSuccess?: (data: AuthResult) => void;
|
|
21
24
|
};
|
|
22
|
-
declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
declare function CyberiaAuth({ backendUrl, apiToken, oauthRedirectUri, initialMode, theme, hideModeSwitch, onAuthSuccess, }: CyberiaAuthProps): react_jsx_runtime.JSX.Element;
|
|
23
26
|
type CyberiaAuthContextValue = {
|
|
24
27
|
isLoaded: boolean;
|
|
25
28
|
isSignedIn: boolean;
|
|
@@ -29,15 +32,17 @@ type CyberiaAuthContextValue = {
|
|
|
29
32
|
openSignUp: () => void;
|
|
30
33
|
signOut: () => void;
|
|
31
34
|
setSessionFromAuth: (result: AuthResult) => void;
|
|
35
|
+
theme: ResolvedTheme;
|
|
32
36
|
};
|
|
33
37
|
type CyberiaAuthProviderProps = {
|
|
34
38
|
backendUrl?: string;
|
|
35
39
|
apiToken: string;
|
|
36
40
|
oauthRedirectUri?: string;
|
|
41
|
+
theme?: ThemeMode;
|
|
37
42
|
children: ReactNode;
|
|
38
43
|
storageKey?: string;
|
|
39
44
|
};
|
|
40
|
-
declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
45
|
+
declare function CyberiaAuthProvider({ backendUrl, apiToken, oauthRedirectUri, theme, children, storageKey, }: CyberiaAuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
41
46
|
declare function useCyberiaAuth(): CyberiaAuthContextValue;
|
|
42
47
|
declare function Show({ when, children }: {
|
|
43
48
|
when: 'signed-in' | 'signed-out';
|
package/dist/index.js
CHANGED
|
@@ -21,10 +21,13 @@ function CyberiaAuth({
|
|
|
21
21
|
apiToken,
|
|
22
22
|
oauthRedirectUri,
|
|
23
23
|
initialMode = "register",
|
|
24
|
+
theme = "system",
|
|
24
25
|
hideModeSwitch = false,
|
|
25
26
|
onAuthSuccess
|
|
26
27
|
}) {
|
|
27
28
|
const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
|
|
29
|
+
const resolvedTheme = useResolvedTheme(theme);
|
|
30
|
+
const palette = getThemePalette(resolvedTheme);
|
|
28
31
|
const [mode, setMode] = useState(initialMode);
|
|
29
32
|
const [config, setConfig] = useState(() => getCachedAppConfig(apiToken));
|
|
30
33
|
const [isBrandingResolved, setIsBrandingResolved] = useState(
|
|
@@ -101,15 +104,15 @@ function CyberiaAuth({
|
|
|
101
104
|
"div",
|
|
102
105
|
{
|
|
103
106
|
style: {
|
|
104
|
-
border:
|
|
107
|
+
border: `1px solid ${palette.border}`,
|
|
105
108
|
borderRadius: 14,
|
|
106
109
|
padding: 20,
|
|
107
|
-
background:
|
|
110
|
+
background: palette.surface,
|
|
108
111
|
fontFamily: "Inter, Arial, sans-serif",
|
|
109
112
|
minHeight: 320,
|
|
110
113
|
display: "grid",
|
|
111
114
|
placeItems: "center",
|
|
112
|
-
color:
|
|
115
|
+
color: palette.textMuted
|
|
113
116
|
},
|
|
114
117
|
children: "Loading sign-in..."
|
|
115
118
|
}
|
|
@@ -119,15 +122,16 @@ function CyberiaAuth({
|
|
|
119
122
|
"div",
|
|
120
123
|
{
|
|
121
124
|
style: {
|
|
122
|
-
border:
|
|
125
|
+
border: `1px solid ${palette.border}`,
|
|
123
126
|
borderRadius: 14,
|
|
124
127
|
padding: 0,
|
|
125
|
-
background:
|
|
128
|
+
background: palette.surface,
|
|
126
129
|
overflow: "hidden",
|
|
127
130
|
fontFamily: "Inter, Arial, sans-serif",
|
|
128
131
|
width: "100%",
|
|
129
132
|
maxWidth: 500,
|
|
130
|
-
margin: "0 auto"
|
|
133
|
+
margin: "0 auto",
|
|
134
|
+
color: palette.text
|
|
131
135
|
},
|
|
132
136
|
children: [
|
|
133
137
|
/* @__PURE__ */ jsxs("div", { style: { padding: 20, display: "grid", gap: 14 }, children: [
|
|
@@ -151,15 +155,15 @@ function CyberiaAuth({
|
|
|
151
155
|
),
|
|
152
156
|
/* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
|
|
153
157
|
/* @__PURE__ */ jsx("h3", { style: { margin: "0 0 6px 0", fontSize: 16 }, children: title }),
|
|
154
|
-
/* @__PURE__ */ jsx("p", { style: { margin: 0, color:
|
|
158
|
+
/* @__PURE__ */ jsx("p", { style: { margin: 0, color: palette.textMuted, fontSize: 13 }, children: subtitle })
|
|
155
159
|
] })
|
|
156
160
|
] }),
|
|
157
161
|
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: [
|
|
158
|
-
/* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("google"), children: [
|
|
162
|
+
/* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("google"), children: [
|
|
159
163
|
/* @__PURE__ */ jsx(GoogleIcon, {}),
|
|
160
164
|
"Google"
|
|
161
165
|
] }),
|
|
162
|
-
/* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle, onClick: () => startOAuth("microsoft"), children: [
|
|
166
|
+
/* @__PURE__ */ jsxs("button", { type: "button", style: socialButtonStyle(palette), onClick: () => startOAuth("microsoft"), children: [
|
|
163
167
|
/* @__PURE__ */ jsx(MicrosoftIcon, {}),
|
|
164
168
|
"Microsoft"
|
|
165
169
|
] })
|
|
@@ -174,14 +178,14 @@ function CyberiaAuth({
|
|
|
174
178
|
gap: 12
|
|
175
179
|
},
|
|
176
180
|
children: [
|
|
177
|
-
/* @__PURE__ */ jsx("div", { style: { height: 1, background:
|
|
178
|
-
/* @__PURE__ */ jsx("span", { style: { color:
|
|
179
|
-
/* @__PURE__ */ jsx("div", { style: { height: 1, background:
|
|
181
|
+
/* @__PURE__ */ jsx("div", { style: { height: 1, background: palette.border } }),
|
|
182
|
+
/* @__PURE__ */ jsx("span", { style: { color: palette.textMuted, fontSize: 14 }, children: "or" }),
|
|
183
|
+
/* @__PURE__ */ jsx("div", { style: { height: 1, background: palette.border } })
|
|
180
184
|
]
|
|
181
185
|
}
|
|
182
186
|
),
|
|
183
187
|
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: { display: "grid", gap: 10 }, children: [
|
|
184
|
-
mode === "register" && /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
|
|
188
|
+
mode === "register" && /* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
|
|
185
189
|
"Full name",
|
|
186
190
|
/* @__PURE__ */ jsx(
|
|
187
191
|
"input",
|
|
@@ -189,15 +193,15 @@ function CyberiaAuth({
|
|
|
189
193
|
name: "displayName",
|
|
190
194
|
placeholder: "Enter your full name",
|
|
191
195
|
required: true,
|
|
192
|
-
style: inputStyle
|
|
196
|
+
style: inputStyle(palette)
|
|
193
197
|
}
|
|
194
198
|
)
|
|
195
199
|
] }),
|
|
196
|
-
/* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
|
|
200
|
+
/* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
|
|
197
201
|
"Email address",
|
|
198
|
-
/* @__PURE__ */ jsx("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle })
|
|
202
|
+
/* @__PURE__ */ jsx("input", { type: "email", name: "email", placeholder: "Enter your email address", required: true, style: inputStyle(palette) })
|
|
199
203
|
] }),
|
|
200
|
-
/* @__PURE__ */ jsxs("label", { style: fieldLabelStyle, children: [
|
|
204
|
+
/* @__PURE__ */ jsxs("label", { style: fieldLabelStyle(palette), children: [
|
|
201
205
|
"Password",
|
|
202
206
|
/* @__PURE__ */ jsx(
|
|
203
207
|
"input",
|
|
@@ -207,7 +211,7 @@ function CyberiaAuth({
|
|
|
207
211
|
placeholder: "Enter your password",
|
|
208
212
|
minLength: 8,
|
|
209
213
|
required: true,
|
|
210
|
-
style: inputStyle
|
|
214
|
+
style: inputStyle(palette)
|
|
211
215
|
}
|
|
212
216
|
)
|
|
213
217
|
] }),
|
|
@@ -235,10 +239,11 @@ function CyberiaAuth({
|
|
|
235
239
|
"div",
|
|
236
240
|
{
|
|
237
241
|
style: {
|
|
238
|
-
borderTop:
|
|
242
|
+
borderTop: `1px solid ${palette.border}`,
|
|
239
243
|
padding: 14,
|
|
240
244
|
textAlign: "center",
|
|
241
|
-
|
|
245
|
+
fontSize: 13,
|
|
246
|
+
background: palette.surfaceAlt
|
|
242
247
|
},
|
|
243
248
|
children: [
|
|
244
249
|
mode === "login" ? "Don't have an account? " : "Already have an account? ",
|
|
@@ -250,7 +255,7 @@ function CyberiaAuth({
|
|
|
250
255
|
style: {
|
|
251
256
|
border: "none",
|
|
252
257
|
background: "transparent",
|
|
253
|
-
color:
|
|
258
|
+
color: palette.text,
|
|
254
259
|
textDecoration: "underline",
|
|
255
260
|
fontWeight: 600,
|
|
256
261
|
cursor: "pointer",
|
|
@@ -271,10 +276,12 @@ function CyberiaAuthProvider({
|
|
|
271
276
|
backendUrl,
|
|
272
277
|
apiToken,
|
|
273
278
|
oauthRedirectUri,
|
|
279
|
+
theme = "system",
|
|
274
280
|
children,
|
|
275
281
|
storageKey = "cyberia_auth_session"
|
|
276
282
|
}) {
|
|
277
283
|
const backendBaseUrl = resolveBackendBaseUrl(backendUrl);
|
|
284
|
+
const resolvedTheme = useResolvedTheme(theme);
|
|
278
285
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
279
286
|
const [session, setSession] = useState(null);
|
|
280
287
|
const [modalOpen, setModalOpen] = useState(false);
|
|
@@ -347,9 +354,10 @@ function CyberiaAuthProvider({
|
|
|
347
354
|
setModalOpen(true);
|
|
348
355
|
},
|
|
349
356
|
signOut,
|
|
350
|
-
setSessionFromAuth
|
|
357
|
+
setSessionFromAuth,
|
|
358
|
+
theme: resolvedTheme
|
|
351
359
|
}),
|
|
352
|
-
[isLoaded, session, setSessionFromAuth]
|
|
360
|
+
[isLoaded, resolvedTheme, session, setSessionFromAuth]
|
|
353
361
|
);
|
|
354
362
|
return /* @__PURE__ */ jsxs(CyberiaAuthContext.Provider, { value, children: [
|
|
355
363
|
children,
|
|
@@ -377,6 +385,7 @@ function CyberiaAuthProvider({
|
|
|
377
385
|
backendUrl: backendBaseUrl,
|
|
378
386
|
apiToken,
|
|
379
387
|
oauthRedirectUri,
|
|
388
|
+
theme,
|
|
380
389
|
initialMode: modalMode,
|
|
381
390
|
hideModeSwitch: false,
|
|
382
391
|
onAuthSuccess: (result) => {
|
|
@@ -435,7 +444,8 @@ function SignOutButton({ children }) {
|
|
|
435
444
|
return /* @__PURE__ */ jsx("button", { type: "button", onClick: signOut, children: children ?? "Sign out" });
|
|
436
445
|
}
|
|
437
446
|
function UserButton() {
|
|
438
|
-
const { user, signOut, openSignIn, openSignUp } = useCyberiaAuth();
|
|
447
|
+
const { user, signOut, openSignIn, openSignUp, theme } = useCyberiaAuth();
|
|
448
|
+
const palette = getThemePalette(theme);
|
|
439
449
|
const [open, setOpen] = useState(false);
|
|
440
450
|
const [manageOpen, setManageOpen] = useState(false);
|
|
441
451
|
const [tab, setTab] = useState("profile");
|
|
@@ -466,8 +476,9 @@ function UserButton() {
|
|
|
466
476
|
width: 36,
|
|
467
477
|
height: 36,
|
|
468
478
|
borderRadius: 999,
|
|
469
|
-
border:
|
|
470
|
-
background:
|
|
479
|
+
border: `1px solid ${palette.border}`,
|
|
480
|
+
background: palette.surface,
|
|
481
|
+
color: palette.text,
|
|
471
482
|
fontWeight: 700,
|
|
472
483
|
cursor: "pointer"
|
|
473
484
|
},
|
|
@@ -483,8 +494,8 @@ function UserButton() {
|
|
|
483
494
|
right: 0,
|
|
484
495
|
top: 42,
|
|
485
496
|
minWidth: 320,
|
|
486
|
-
background:
|
|
487
|
-
border:
|
|
497
|
+
background: palette.surface,
|
|
498
|
+
border: `1px solid ${palette.border}`,
|
|
488
499
|
borderRadius: 12,
|
|
489
500
|
boxShadow: "0 12px 24px rgba(0,0,0,0.08)",
|
|
490
501
|
padding: 0,
|
|
@@ -499,22 +510,22 @@ function UserButton() {
|
|
|
499
510
|
width: 44,
|
|
500
511
|
height: 44,
|
|
501
512
|
borderRadius: 999,
|
|
502
|
-
border:
|
|
513
|
+
border: `1px solid ${palette.border}`,
|
|
503
514
|
display: "grid",
|
|
504
515
|
placeItems: "center",
|
|
505
516
|
fontWeight: 700,
|
|
506
|
-
color:
|
|
507
|
-
background:
|
|
517
|
+
color: palette.text,
|
|
518
|
+
background: palette.surfaceAlt
|
|
508
519
|
},
|
|
509
520
|
children: initials
|
|
510
521
|
}
|
|
511
522
|
),
|
|
512
523
|
/* @__PURE__ */ jsxs("div", { style: { display: "grid" }, children: [
|
|
513
|
-
/* @__PURE__ */ jsx("strong", { style: { fontSize: 16, color:
|
|
514
|
-
/* @__PURE__ */ jsx("span", { style: { color:
|
|
524
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 16, color: palette.text, lineHeight: 1.2 }, children: profileName }),
|
|
525
|
+
/* @__PURE__ */ jsx("span", { style: { color: palette.text, fontSize: 14 }, children: profileEmail })
|
|
515
526
|
] })
|
|
516
527
|
] }),
|
|
517
|
-
/* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop:
|
|
528
|
+
/* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: 0 } }),
|
|
518
529
|
!user && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
519
530
|
/* @__PURE__ */ jsx(
|
|
520
531
|
"button",
|
|
@@ -568,9 +579,9 @@ function UserButton() {
|
|
|
568
579
|
}
|
|
569
580
|
)
|
|
570
581
|
] }),
|
|
571
|
-
/* @__PURE__ */ jsxs("div", { style: { borderTop:
|
|
582
|
+
/* @__PURE__ */ jsxs("div", { style: { borderTop: `1px solid ${palette.border}`, textAlign: "center", padding: "12px 10px", color: palette.textMuted, fontSize: 13 }, children: [
|
|
572
583
|
"Secured by ",
|
|
573
|
-
/* @__PURE__ */ jsx("strong", { children: "
|
|
584
|
+
/* @__PURE__ */ jsx("strong", { children: "Cyberia Auth" })
|
|
574
585
|
] })
|
|
575
586
|
]
|
|
576
587
|
}
|
|
@@ -595,9 +606,9 @@ function UserButton() {
|
|
|
595
606
|
width: "100%",
|
|
596
607
|
maxWidth: 940,
|
|
597
608
|
minHeight: 540,
|
|
598
|
-
background:
|
|
609
|
+
background: palette.surface,
|
|
599
610
|
borderRadius: 10,
|
|
600
|
-
border:
|
|
611
|
+
border: `1px solid ${palette.border}`,
|
|
601
612
|
display: "grid",
|
|
602
613
|
gridTemplateColumns: "220px 1fr",
|
|
603
614
|
overflow: "hidden"
|
|
@@ -608,15 +619,15 @@ function UserButton() {
|
|
|
608
619
|
"aside",
|
|
609
620
|
{
|
|
610
621
|
style: {
|
|
611
|
-
borderRight:
|
|
622
|
+
borderRight: `1px solid ${palette.border}`,
|
|
612
623
|
padding: 22,
|
|
613
|
-
background:
|
|
624
|
+
background: palette.surfaceAlt,
|
|
614
625
|
display: "flex",
|
|
615
626
|
flexDirection: "column"
|
|
616
627
|
},
|
|
617
628
|
children: [
|
|
618
|
-
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: 30, color:
|
|
619
|
-
/* @__PURE__ */ jsx("p", { style: { marginTop: 6, color:
|
|
629
|
+
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: 30, color: palette.text }, children: "Account" }),
|
|
630
|
+
/* @__PURE__ */ jsx("p", { style: { marginTop: 6, color: palette.textMuted, fontSize: 12 }, children: "Manage your account info." }),
|
|
620
631
|
/* @__PURE__ */ jsxs("div", { style: { marginTop: 20, display: "grid", gap: 8 }, children: [
|
|
621
632
|
/* @__PURE__ */ jsx(
|
|
622
633
|
"button",
|
|
@@ -625,8 +636,8 @@ function UserButton() {
|
|
|
625
636
|
onClick: () => setTab("profile"),
|
|
626
637
|
style: {
|
|
627
638
|
...tabButtonStyle,
|
|
628
|
-
background: tab === "profile" ? "#
|
|
629
|
-
color: tab === "profile" ? "#
|
|
639
|
+
background: tab === "profile" ? "#ffe8e8" : "transparent",
|
|
640
|
+
color: tab === "profile" ? "#d92828" : palette.textMuted
|
|
630
641
|
},
|
|
631
642
|
children: "Profile"
|
|
632
643
|
}
|
|
@@ -638,14 +649,14 @@ function UserButton() {
|
|
|
638
649
|
onClick: () => setTab("security"),
|
|
639
650
|
style: {
|
|
640
651
|
...tabButtonStyle,
|
|
641
|
-
background: tab === "security" ? "#
|
|
642
|
-
color: tab === "security" ? "#
|
|
652
|
+
background: tab === "security" ? "#ffe8e8" : "transparent",
|
|
653
|
+
color: tab === "security" ? "#d92828" : palette.textMuted
|
|
643
654
|
},
|
|
644
655
|
children: "Security"
|
|
645
656
|
}
|
|
646
657
|
)
|
|
647
658
|
] }),
|
|
648
|
-
/* @__PURE__ */ jsxs("div", { style: { marginTop: "auto", paddingTop: 24, color:
|
|
659
|
+
/* @__PURE__ */ jsxs("div", { style: { marginTop: "auto", paddingTop: 24, color: palette.textMuted, fontSize: 15 }, children: [
|
|
649
660
|
"Secure by ",
|
|
650
661
|
/* @__PURE__ */ jsx("strong", { children: "Cyberia Auth" })
|
|
651
662
|
] })
|
|
@@ -654,7 +665,7 @@ function UserButton() {
|
|
|
654
665
|
),
|
|
655
666
|
/* @__PURE__ */ jsxs("main", { style: { padding: 26 }, children: [
|
|
656
667
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
657
|
-
/* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: 22, color:
|
|
668
|
+
/* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: 22, color: palette.text }, children: tab === "profile" ? "Profile details" : "Security" }),
|
|
658
669
|
/* @__PURE__ */ jsx(
|
|
659
670
|
"button",
|
|
660
671
|
{
|
|
@@ -665,10 +676,10 @@ function UserButton() {
|
|
|
665
676
|
}
|
|
666
677
|
)
|
|
667
678
|
] }),
|
|
668
|
-
/* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop:
|
|
679
|
+
/* @__PURE__ */ jsx("hr", { style: { border: 0, borderTop: `1px solid ${palette.border}`, margin: "16px 0 20px" } }),
|
|
669
680
|
tab === "profile" && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 20 }, children: [
|
|
670
681
|
/* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
|
|
671
|
-
/* @__PURE__ */ jsx("div", { style: { color: "#
|
|
682
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Profile" }),
|
|
672
683
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
673
684
|
/* @__PURE__ */ jsx("div", { style: avatarLargeStyle, children: initials }),
|
|
674
685
|
/* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: profileName })
|
|
@@ -676,25 +687,25 @@ function UserButton() {
|
|
|
676
687
|
/* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Update profile" })
|
|
677
688
|
] }),
|
|
678
689
|
/* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
|
|
679
|
-
/* @__PURE__ */ jsx("div", { style: { color: "#
|
|
690
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Email addresses" }),
|
|
680
691
|
/* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: profileEmail }),
|
|
681
692
|
/* @__PURE__ */ jsx("span", { style: { color: "#6b7280", fontSize: 14 }, children: "Primary" })
|
|
682
693
|
] }),
|
|
683
694
|
/* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
|
|
684
|
-
/* @__PURE__ */ jsx("div", { style: { color: "#
|
|
695
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Connected accounts" }),
|
|
685
696
|
/* @__PURE__ */ jsx("div", { style: { fontSize: 16 }, children: "Google / Microsoft" }),
|
|
686
697
|
/* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Connect account" })
|
|
687
698
|
] })
|
|
688
699
|
] }),
|
|
689
700
|
tab === "security" && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 20 }, children: [
|
|
690
701
|
/* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
|
|
691
|
-
/* @__PURE__ */ jsx("div", { style: { color: "#
|
|
702
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Password" }),
|
|
692
703
|
/* @__PURE__ */ jsx("div", {}),
|
|
693
704
|
/* @__PURE__ */ jsx("button", { type: "button", style: linkButtonStyle, children: "Set password" })
|
|
694
705
|
] }),
|
|
695
706
|
/* @__PURE__ */ jsxs("div", { style: { ...profileRowStyle, alignItems: "start" }, children: [
|
|
696
|
-
/* @__PURE__ */ jsx("div", { style: { color: "#
|
|
697
|
-
/* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: "#
|
|
707
|
+
/* @__PURE__ */ jsx("div", { style: { color: "#c5c7ca", fontSize: 14 }, children: "Active devices" }),
|
|
708
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: 14, color: "#c5c7ca", maxWidth: 430 }, children: userAgent }),
|
|
698
709
|
/* @__PURE__ */ jsx("span", { style: { color: "#6b7280", fontSize: 14 }, children: "This device" })
|
|
699
710
|
] }),
|
|
700
711
|
/* @__PURE__ */ jsxs("div", { style: profileRowStyle, children: [
|
|
@@ -748,25 +759,28 @@ var menuItemButtonStyle = {
|
|
|
748
759
|
background: "transparent",
|
|
749
760
|
cursor: "pointer"
|
|
750
761
|
};
|
|
751
|
-
var inputStyle = {
|
|
762
|
+
var inputStyle = (palette) => ({
|
|
752
763
|
width: "100%",
|
|
753
764
|
padding: 11,
|
|
754
765
|
borderRadius: 9,
|
|
755
|
-
border:
|
|
766
|
+
border: `1px solid ${palette.border}`,
|
|
767
|
+
background: palette.surface,
|
|
768
|
+
color: palette.text,
|
|
756
769
|
fontSize: 13
|
|
757
|
-
};
|
|
758
|
-
var fieldLabelStyle = {
|
|
770
|
+
});
|
|
771
|
+
var fieldLabelStyle = (palette) => ({
|
|
759
772
|
display: "grid",
|
|
760
773
|
gap: 6,
|
|
761
774
|
fontSize: 14,
|
|
762
|
-
color:
|
|
775
|
+
color: palette.text,
|
|
763
776
|
fontWeight: 600
|
|
764
|
-
};
|
|
765
|
-
var socialButtonStyle = {
|
|
766
|
-
border:
|
|
777
|
+
});
|
|
778
|
+
var socialButtonStyle = (palette) => ({
|
|
779
|
+
border: `1px solid ${palette.border}`,
|
|
767
780
|
borderRadius: 9,
|
|
768
781
|
padding: "10px 12px",
|
|
769
|
-
background:
|
|
782
|
+
background: palette.surface,
|
|
783
|
+
color: palette.text,
|
|
770
784
|
cursor: "pointer",
|
|
771
785
|
fontSize: 16,
|
|
772
786
|
fontWeight: 300,
|
|
@@ -774,7 +788,7 @@ var socialButtonStyle = {
|
|
|
774
788
|
alignItems: "center",
|
|
775
789
|
justifyContent: "center",
|
|
776
790
|
gap: 8
|
|
777
|
-
};
|
|
791
|
+
});
|
|
778
792
|
function GoogleIcon() {
|
|
779
793
|
return /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", height: "20", viewBox: "0 0 20 20", width: "20", "aria-hidden": "true", children: [
|
|
780
794
|
/* @__PURE__ */ jsx("path", { d: "M19.9905 10.1871C19.9905 9.36773 19.9224 8.7698 19.7752 8.14972H10.1992V11.848H15.8201C15.7068 12.7671 15.0948 14.1512 13.7349 15.0813L13.7159 15.2051L16.7436 17.497L16.9534 17.5174C18.8798 15.779 19.9905 13.2211 19.9905 10.1871Z", fill: "#4285F4" }),
|
|
@@ -802,6 +816,50 @@ function resolveBackendBaseUrl(backendUrl) {
|
|
|
802
816
|
const candidate = backendUrl?.trim() || DEFAULT_BACKEND_URL;
|
|
803
817
|
return candidate.replace(/\/+$/, "");
|
|
804
818
|
}
|
|
819
|
+
function getThemePalette(theme) {
|
|
820
|
+
if (theme === "dark") {
|
|
821
|
+
return {
|
|
822
|
+
surface: "#445364",
|
|
823
|
+
surfaceAlt: "#1f2937",
|
|
824
|
+
border: "#374151",
|
|
825
|
+
text: "#f9fafb",
|
|
826
|
+
textMuted: "#9ca3af"
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
return {
|
|
830
|
+
surface: "#ffffff",
|
|
831
|
+
surfaceAlt: "#fafafa",
|
|
832
|
+
border: "#e5e7eb",
|
|
833
|
+
text: "#111827",
|
|
834
|
+
textMuted: "#6b7280"
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
function useResolvedTheme(theme) {
|
|
838
|
+
const [resolvedTheme, setResolvedTheme] = useState(() => {
|
|
839
|
+
if (theme === "light" || theme === "dark") {
|
|
840
|
+
return theme;
|
|
841
|
+
}
|
|
842
|
+
if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
843
|
+
return "dark";
|
|
844
|
+
}
|
|
845
|
+
return "light";
|
|
846
|
+
});
|
|
847
|
+
useEffect(() => {
|
|
848
|
+
if (theme === "light" || theme === "dark") {
|
|
849
|
+
setResolvedTheme(theme);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (typeof window === "undefined") {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
856
|
+
const updateTheme = () => setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
857
|
+
updateTheme();
|
|
858
|
+
mediaQuery.addEventListener("change", updateTheme);
|
|
859
|
+
return () => mediaQuery.removeEventListener("change", updateTheme);
|
|
860
|
+
}, [theme]);
|
|
861
|
+
return resolvedTheme;
|
|
862
|
+
}
|
|
805
863
|
function getBrandingCacheKey(apiToken) {
|
|
806
864
|
return `cyberia_auth_branding:${apiToken}`;
|
|
807
865
|
}
|
|
@@ -848,7 +906,7 @@ var tabButtonStyle = {
|
|
|
848
906
|
};
|
|
849
907
|
var profileRowStyle = {
|
|
850
908
|
display: "grid",
|
|
851
|
-
gridTemplateColumns: "
|
|
909
|
+
gridTemplateColumns: "150px 1fr auto",
|
|
852
910
|
alignItems: "center",
|
|
853
911
|
gap: 12,
|
|
854
912
|
paddingBottom: 12,
|
|
@@ -868,7 +926,7 @@ var avatarLargeStyle = {
|
|
|
868
926
|
var linkButtonStyle = {
|
|
869
927
|
border: "none",
|
|
870
928
|
background: "transparent",
|
|
871
|
-
color: "#
|
|
929
|
+
color: "#d92828",
|
|
872
930
|
cursor: "pointer",
|
|
873
931
|
fontSize: 14
|
|
874
932
|
};
|