@kendevelops/auth-flow-kit 1.4.9 → 1.5.5
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/dist/index.cjs +25 -222
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +25 -222
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,9 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
// src/http.ts
|
|
11
11
|
function makeURL(baseURL, path) {
|
|
12
|
-
|
|
13
|
-
const suffix = path.startsWith("/") ? path : `/${path}`;
|
|
14
|
-
return `${base}${suffix}`;
|
|
12
|
+
return `${baseURL.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
|
|
15
13
|
}
|
|
16
14
|
function getStoredAccessToken() {
|
|
17
15
|
try {
|
|
@@ -22,11 +20,8 @@ function getStoredAccessToken() {
|
|
|
22
20
|
}
|
|
23
21
|
function setStoredAccessToken(token) {
|
|
24
22
|
try {
|
|
25
|
-
if (token)
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
localStorage.removeItem("afk_access_token");
|
|
23
|
+
if (token) localStorage.setItem("afk_access_token", token);
|
|
24
|
+
else localStorage.removeItem("afk_access_token");
|
|
30
25
|
} catch {
|
|
31
26
|
}
|
|
32
27
|
}
|
|
@@ -35,27 +30,20 @@ async function httpJSON(url, opts = {}, withAuth = false) {
|
|
|
35
30
|
"Content-Type": "application/json"
|
|
36
31
|
};
|
|
37
32
|
if (withAuth) {
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
headers["Authorization"] = `Bearer ${storedToken}`;
|
|
41
|
-
}
|
|
33
|
+
const tok = getStoredAccessToken();
|
|
34
|
+
if (tok) headers["Authorization"] = `Bearer ${tok}`;
|
|
42
35
|
}
|
|
43
36
|
const res = await fetch(url, {
|
|
44
37
|
...opts,
|
|
45
|
-
headers: {
|
|
46
|
-
...headers,
|
|
47
|
-
...opts.headers || {}
|
|
48
|
-
}
|
|
38
|
+
headers: { ...headers, ...opts.headers || {} }
|
|
49
39
|
});
|
|
50
40
|
if (!res.ok) {
|
|
51
41
|
let message = `Request failed (${res.status})`;
|
|
52
42
|
const contentType = res.headers.get("content-type") || "";
|
|
53
43
|
if (contentType.includes("application/json")) {
|
|
54
44
|
try {
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
message = body.message;
|
|
58
|
-
}
|
|
45
|
+
const data = await res.json();
|
|
46
|
+
if (data?.message) message = data.message;
|
|
59
47
|
} catch {
|
|
60
48
|
}
|
|
61
49
|
}
|
|
@@ -175,29 +163,18 @@ function PasswordResetScreen() {
|
|
|
175
163
|
const [email, setEmail] = useState2("");
|
|
176
164
|
const [sent, setSent] = useState2(false);
|
|
177
165
|
const [error, setError] = useState2(null);
|
|
178
|
-
const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
179
166
|
const requestReset = async (e) => {
|
|
180
167
|
e.preventDefault();
|
|
181
168
|
setError(null);
|
|
182
|
-
const trimmedEmail = email.trim();
|
|
183
|
-
if (!trimmedEmail) {
|
|
184
|
-
setError("Email is required.");
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (!isValidEmail(trimmedEmail)) {
|
|
188
|
-
setError("Enter a valid email address.");
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
169
|
try {
|
|
192
170
|
const url = makeURL(config.baseURL, config.endpoints.forgot);
|
|
193
171
|
await httpJSON(url, {
|
|
194
172
|
method: "POST",
|
|
195
|
-
body: JSON.stringify({ email
|
|
173
|
+
body: JSON.stringify({ email })
|
|
196
174
|
});
|
|
197
175
|
setSent(true);
|
|
198
176
|
} catch (err) {
|
|
199
|
-
|
|
200
|
-
setError(message);
|
|
177
|
+
setError(err?.message || "Failed to request reset");
|
|
201
178
|
}
|
|
202
179
|
};
|
|
203
180
|
return /* @__PURE__ */ jsxs(
|
|
@@ -237,7 +214,6 @@ function PasswordResetScreen() {
|
|
|
237
214
|
/* @__PURE__ */ jsx3(
|
|
238
215
|
"label",
|
|
239
216
|
{
|
|
240
|
-
htmlFor: "afk-reset-email",
|
|
241
217
|
style: {
|
|
242
218
|
position: "absolute",
|
|
243
219
|
top: sent ? "-18px" : "-10px",
|
|
@@ -254,7 +230,6 @@ function PasswordResetScreen() {
|
|
|
254
230
|
/* @__PURE__ */ jsx3(
|
|
255
231
|
"input",
|
|
256
232
|
{
|
|
257
|
-
id: "afk-reset-email",
|
|
258
233
|
value: email,
|
|
259
234
|
onChange: (e) => setEmail(e.target.value),
|
|
260
235
|
type: "email",
|
|
@@ -317,8 +292,6 @@ function PasswordResetScreen() {
|
|
|
317
292
|
error && /* @__PURE__ */ jsx3(
|
|
318
293
|
"p",
|
|
319
294
|
{
|
|
320
|
-
role: "alert",
|
|
321
|
-
"aria-live": "polite",
|
|
322
295
|
style: {
|
|
323
296
|
marginTop: 20,
|
|
324
297
|
color: "crimson",
|
|
@@ -369,26 +342,15 @@ function LoginScreen() {
|
|
|
369
342
|
setError(null);
|
|
370
343
|
const trimmedEmail = email.trim();
|
|
371
344
|
const trimmedPassword = password.trim();
|
|
372
|
-
if (!trimmedEmail) {
|
|
373
|
-
setError("Email
|
|
374
|
-
setSubmitting(false);
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmedEmail)) {
|
|
378
|
-
setError("Enter a valid email address.");
|
|
379
|
-
setSubmitting(false);
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
if (!trimmedPassword) {
|
|
383
|
-
setError("Password is required.");
|
|
345
|
+
if (!trimmedEmail || !trimmedPassword) {
|
|
346
|
+
setError("Email and password cannot be empty.");
|
|
384
347
|
setSubmitting(false);
|
|
385
348
|
return;
|
|
386
349
|
}
|
|
387
350
|
try {
|
|
388
351
|
await login(trimmedEmail, trimmedPassword);
|
|
389
352
|
} catch (err) {
|
|
390
|
-
|
|
391
|
-
setError(message);
|
|
353
|
+
setError(err?.message || "Login failed");
|
|
392
354
|
} finally {
|
|
393
355
|
setSubmitting(false);
|
|
394
356
|
}
|
|
@@ -429,7 +391,6 @@ function LoginScreen() {
|
|
|
429
391
|
/* @__PURE__ */ jsx4(
|
|
430
392
|
"label",
|
|
431
393
|
{
|
|
432
|
-
htmlFor: "afk-login-email",
|
|
433
394
|
style: {
|
|
434
395
|
position: "absolute",
|
|
435
396
|
top: "-10px",
|
|
@@ -446,7 +407,6 @@ function LoginScreen() {
|
|
|
446
407
|
/* @__PURE__ */ jsx4(
|
|
447
408
|
"input",
|
|
448
409
|
{
|
|
449
|
-
id: "afk-login-email",
|
|
450
410
|
value: email,
|
|
451
411
|
onChange: (e) => setEmail(e.target.value),
|
|
452
412
|
type: "email",
|
|
@@ -476,7 +436,6 @@ function LoginScreen() {
|
|
|
476
436
|
/* @__PURE__ */ jsx4(
|
|
477
437
|
"label",
|
|
478
438
|
{
|
|
479
|
-
htmlFor: "afk-login-password",
|
|
480
439
|
style: {
|
|
481
440
|
position: "absolute",
|
|
482
441
|
top: "-10px",
|
|
@@ -493,7 +452,6 @@ function LoginScreen() {
|
|
|
493
452
|
/* @__PURE__ */ jsx4(
|
|
494
453
|
"input",
|
|
495
454
|
{
|
|
496
|
-
id: "afk-login-password",
|
|
497
455
|
value: password,
|
|
498
456
|
onChange: (e) => setPassword(e.target.value),
|
|
499
457
|
type: "password",
|
|
@@ -520,28 +478,17 @@ function LoginScreen() {
|
|
|
520
478
|
)
|
|
521
479
|
] }),
|
|
522
480
|
/* @__PURE__ */ jsx4(
|
|
523
|
-
"
|
|
481
|
+
"p",
|
|
524
482
|
{
|
|
483
|
+
onClick: () => setShowReset(true),
|
|
525
484
|
style: {
|
|
526
|
-
textAlign: "right"
|
|
485
|
+
textAlign: "right",
|
|
486
|
+
fontSize: 13,
|
|
487
|
+
color: "#4b4bff",
|
|
488
|
+
cursor: "pointer",
|
|
489
|
+
marginBottom: 24
|
|
527
490
|
},
|
|
528
|
-
children:
|
|
529
|
-
"button",
|
|
530
|
-
{
|
|
531
|
-
onClick: () => setShowReset(true),
|
|
532
|
-
style: {
|
|
533
|
-
textAlign: "right",
|
|
534
|
-
fontSize: 13,
|
|
535
|
-
color: "#4b4bff",
|
|
536
|
-
cursor: "pointer",
|
|
537
|
-
marginBottom: 24,
|
|
538
|
-
width: "fit-content",
|
|
539
|
-
border: "none",
|
|
540
|
-
background: "none"
|
|
541
|
-
},
|
|
542
|
-
children: "Forgot password?"
|
|
543
|
-
}
|
|
544
|
-
)
|
|
491
|
+
children: "Forgot password?"
|
|
545
492
|
}
|
|
546
493
|
),
|
|
547
494
|
/* @__PURE__ */ jsx4(
|
|
@@ -569,8 +516,6 @@ function LoginScreen() {
|
|
|
569
516
|
error && /* @__PURE__ */ jsx4(
|
|
570
517
|
"p",
|
|
571
518
|
{
|
|
572
|
-
role: "alert",
|
|
573
|
-
"aria-live": "polite",
|
|
574
519
|
style: {
|
|
575
520
|
marginTop: 18,
|
|
576
521
|
color: "crimson",
|
|
@@ -594,21 +539,8 @@ function SignupScreen() {
|
|
|
594
539
|
const [name, setName] = useState4("");
|
|
595
540
|
const [email, setEmail] = useState4("");
|
|
596
541
|
const [password, setPassword] = useState4("");
|
|
597
|
-
const [confirmPassword, setConfirmPassword] = useState4("");
|
|
598
542
|
const [submitting, setSubmitting] = useState4(false);
|
|
599
543
|
const [error, setError] = useState4(null);
|
|
600
|
-
const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
601
|
-
const getPasswordStrength = (value) => {
|
|
602
|
-
let score = 0;
|
|
603
|
-
if (value.length >= 8) score++;
|
|
604
|
-
if (/[A-Z]/.test(value)) score++;
|
|
605
|
-
if (/[0-9]/.test(value)) score++;
|
|
606
|
-
if (/[^A-Za-z0-9]/.test(value)) score++;
|
|
607
|
-
if (!value) return { label: "", color: "" };
|
|
608
|
-
if (score <= 1) return { label: "Weak", color: "crimson" };
|
|
609
|
-
if (score === 2) return { label: "Medium", color: "#f39c12" };
|
|
610
|
-
return { label: "Strong", color: "#2ecc71" };
|
|
611
|
-
};
|
|
612
544
|
const onSubmit = async (e) => {
|
|
613
545
|
e.preventDefault();
|
|
614
546
|
setSubmitting(true);
|
|
@@ -616,47 +548,15 @@ function SignupScreen() {
|
|
|
616
548
|
const trimmedEmail = email.trim();
|
|
617
549
|
const trimmedPassword = password.trim();
|
|
618
550
|
const trimmedName = name.trim();
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
setError("Name is required.");
|
|
622
|
-
setSubmitting(false);
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
if (!trimmedEmail) {
|
|
626
|
-
setError("Email is required.");
|
|
627
|
-
setSubmitting(false);
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
if (!isValidEmail(trimmedEmail)) {
|
|
631
|
-
setError("Enter a valid email address.");
|
|
632
|
-
setSubmitting(false);
|
|
633
|
-
return;
|
|
634
|
-
}
|
|
635
|
-
if (!trimmedPassword) {
|
|
636
|
-
setError("Password is required.");
|
|
637
|
-
setSubmitting(false);
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
if (trimmedPassword.length < 8) {
|
|
641
|
-
setError("Password must be at least 8 characters long.");
|
|
642
|
-
setSubmitting(false);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (!trimmedConfirm) {
|
|
646
|
-
setError("Please confirm your password.");
|
|
647
|
-
setSubmitting(false);
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
if (trimmedPassword !== trimmedConfirm) {
|
|
651
|
-
setError("Passwords do not match.");
|
|
551
|
+
if (!trimmedEmail || !trimmedPassword || !trimmedName) {
|
|
552
|
+
setError("Email and password cannot be empty.");
|
|
652
553
|
setSubmitting(false);
|
|
653
554
|
return;
|
|
654
555
|
}
|
|
655
556
|
try {
|
|
656
|
-
await signup({ name
|
|
557
|
+
await signup({ name, email, password });
|
|
657
558
|
} catch (err) {
|
|
658
|
-
|
|
659
|
-
setError(message);
|
|
559
|
+
setError(err?.message || "Signup failed");
|
|
660
560
|
} finally {
|
|
661
561
|
setSubmitting(false);
|
|
662
562
|
}
|
|
@@ -698,7 +598,6 @@ function SignupScreen() {
|
|
|
698
598
|
/* @__PURE__ */ jsx5(
|
|
699
599
|
"label",
|
|
700
600
|
{
|
|
701
|
-
htmlFor: "afk-signup-name",
|
|
702
601
|
style: {
|
|
703
602
|
position: "absolute",
|
|
704
603
|
top: "-10px",
|
|
@@ -715,7 +614,6 @@ function SignupScreen() {
|
|
|
715
614
|
/* @__PURE__ */ jsx5(
|
|
716
615
|
"input",
|
|
717
616
|
{
|
|
718
|
-
id: "afk-signup-name",
|
|
719
617
|
value: name,
|
|
720
618
|
onChange: (e) => setName(e.target.value),
|
|
721
619
|
placeholder: "Your name",
|
|
@@ -744,7 +642,6 @@ function SignupScreen() {
|
|
|
744
642
|
/* @__PURE__ */ jsx5(
|
|
745
643
|
"label",
|
|
746
644
|
{
|
|
747
|
-
htmlFor: "afk-signup-email",
|
|
748
645
|
style: {
|
|
749
646
|
position: "absolute",
|
|
750
647
|
top: "-10px",
|
|
@@ -761,7 +658,6 @@ function SignupScreen() {
|
|
|
761
658
|
/* @__PURE__ */ jsx5(
|
|
762
659
|
"input",
|
|
763
660
|
{
|
|
764
|
-
id: "afk-signup-email",
|
|
765
661
|
value: email,
|
|
766
662
|
onChange: (e) => setEmail(e.target.value),
|
|
767
663
|
type: "email",
|
|
@@ -791,7 +687,6 @@ function SignupScreen() {
|
|
|
791
687
|
/* @__PURE__ */ jsx5(
|
|
792
688
|
"label",
|
|
793
689
|
{
|
|
794
|
-
htmlFor: "afk-signup-password",
|
|
795
690
|
style: {
|
|
796
691
|
position: "absolute",
|
|
797
692
|
top: "-10px",
|
|
@@ -808,7 +703,6 @@ function SignupScreen() {
|
|
|
808
703
|
/* @__PURE__ */ jsx5(
|
|
809
704
|
"input",
|
|
810
705
|
{
|
|
811
|
-
id: "afk-signup-password",
|
|
812
706
|
value: password,
|
|
813
707
|
onChange: (e) => setPassword(e.target.value),
|
|
814
708
|
type: "password",
|
|
@@ -834,95 +728,6 @@ function SignupScreen() {
|
|
|
834
728
|
}
|
|
835
729
|
)
|
|
836
730
|
] }),
|
|
837
|
-
/* @__PURE__ */ jsxs3("div", { style: { position: "relative", marginBottom: 18 }, children: [
|
|
838
|
-
/* @__PURE__ */ jsx5(
|
|
839
|
-
"label",
|
|
840
|
-
{
|
|
841
|
-
htmlFor: "afk-signup-confirm-password",
|
|
842
|
-
style: {
|
|
843
|
-
position: "absolute",
|
|
844
|
-
top: "-10px",
|
|
845
|
-
left: "14px",
|
|
846
|
-
background: "rgba(255,255,255,0.85)",
|
|
847
|
-
padding: "0 6px",
|
|
848
|
-
fontSize: 13,
|
|
849
|
-
color: "#444",
|
|
850
|
-
borderRadius: 6
|
|
851
|
-
},
|
|
852
|
-
children: "Confirm password"
|
|
853
|
-
}
|
|
854
|
-
),
|
|
855
|
-
/* @__PURE__ */ jsx5(
|
|
856
|
-
"input",
|
|
857
|
-
{
|
|
858
|
-
id: "afk-signup-confirm-password",
|
|
859
|
-
value: confirmPassword,
|
|
860
|
-
onChange: (e) => setConfirmPassword(e.target.value),
|
|
861
|
-
type: "password",
|
|
862
|
-
placeholder: "Repeat your password",
|
|
863
|
-
style: {
|
|
864
|
-
width: "80%",
|
|
865
|
-
padding: "14px 16px",
|
|
866
|
-
borderRadius: 12,
|
|
867
|
-
border: "1px solid #d2d2d2",
|
|
868
|
-
fontSize: 15,
|
|
869
|
-
outline: "none",
|
|
870
|
-
transition: "0.25s",
|
|
871
|
-
background: "rgba(255,255,255,0.85)"
|
|
872
|
-
},
|
|
873
|
-
onFocus: (e) => {
|
|
874
|
-
e.currentTarget.style.border = "1px solid #4b4bff";
|
|
875
|
-
e.currentTarget.style.boxShadow = "0 0 0 3px rgba(75,75,255,0.25)";
|
|
876
|
-
},
|
|
877
|
-
onBlur: (e) => {
|
|
878
|
-
e.currentTarget.style.border = "1px solid #d2d2d2";
|
|
879
|
-
e.currentTarget.style.boxShadow = "0 0 0 transparent";
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
)
|
|
883
|
-
] }),
|
|
884
|
-
/* @__PURE__ */ jsxs3(
|
|
885
|
-
"div",
|
|
886
|
-
{
|
|
887
|
-
style: {
|
|
888
|
-
marginBottom: 20,
|
|
889
|
-
fontSize: 12,
|
|
890
|
-
color: "#555"
|
|
891
|
-
},
|
|
892
|
-
children: [
|
|
893
|
-
/* @__PURE__ */ jsx5("p", { style: { marginBottom: 6 }, children: "Use at least 8 characters, including letters, numbers, and symbols." }),
|
|
894
|
-
password && /* @__PURE__ */ jsxs3(
|
|
895
|
-
"p",
|
|
896
|
-
{
|
|
897
|
-
style: {
|
|
898
|
-
fontWeight: 600,
|
|
899
|
-
color: getPasswordStrength(password).color
|
|
900
|
-
},
|
|
901
|
-
children: [
|
|
902
|
-
"Password strength: ",
|
|
903
|
-
getPasswordStrength(password).label
|
|
904
|
-
]
|
|
905
|
-
}
|
|
906
|
-
)
|
|
907
|
-
]
|
|
908
|
-
}
|
|
909
|
-
),
|
|
910
|
-
/* @__PURE__ */ jsx5(
|
|
911
|
-
"p",
|
|
912
|
-
{
|
|
913
|
-
style: {
|
|
914
|
-
textAlign: "center",
|
|
915
|
-
fontSize: 13,
|
|
916
|
-
color: "#4b4bff",
|
|
917
|
-
cursor: "pointer",
|
|
918
|
-
marginBottom: 24
|
|
919
|
-
},
|
|
920
|
-
onClick: () => {
|
|
921
|
-
window.dispatchEvent(new CustomEvent("auth-flow-kit:navigate-to-login"));
|
|
922
|
-
},
|
|
923
|
-
children: "Already have an account? Sign in"
|
|
924
|
-
}
|
|
925
|
-
),
|
|
926
731
|
/* @__PURE__ */ jsx5(
|
|
927
732
|
"button",
|
|
928
733
|
{
|
|
@@ -948,8 +753,6 @@ function SignupScreen() {
|
|
|
948
753
|
error && /* @__PURE__ */ jsx5(
|
|
949
754
|
"p",
|
|
950
755
|
{
|
|
951
|
-
role: "alert",
|
|
952
|
-
"aria-live": "polite",
|
|
953
756
|
style: {
|
|
954
757
|
marginTop: 18,
|
|
955
758
|
color: "crimson",
|