@kendevelops/auth-flow-kit 1.5.0 → 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.js CHANGED
@@ -9,9 +9,7 @@ import {
9
9
 
10
10
  // src/http.ts
11
11
  function makeURL(baseURL, path) {
12
- const base = baseURL.replace(/\/$/, "");
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
- localStorage.setItem("afk_access_token", token);
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 storedToken = getStoredAccessToken();
39
- if (storedToken) {
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 body = await res.json();
56
- if (body?.message) {
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
  }
@@ -150,22 +138,17 @@ function AuthProvider({
150
138
  }
151
139
 
152
140
  // src/Protected.tsx
141
+ import { useEffect as useEffect2 } from "react";
153
142
  import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
154
- function Protected({
155
- children,
156
- redirectTo,
157
- fallback = /* @__PURE__ */ jsx2("div", { children: "Loading..." })
158
- }) {
143
+ function Protected({ children, redirectTo }) {
159
144
  const { user, loading } = useAuth();
160
- if (loading) {
161
- return /* @__PURE__ */ jsx2(Fragment, { children: fallback });
162
- }
163
- if (!user) {
164
- if (redirectTo && typeof window !== "undefined") {
165
- window.location.replace(redirectTo);
145
+ useEffect2(() => {
146
+ if (!loading && !user && redirectTo) {
147
+ window.location.href = redirectTo;
166
148
  }
167
- return null;
168
- }
149
+ }, [loading, user, redirectTo]);
150
+ if (loading) return /* @__PURE__ */ jsx2("div", { children: "Loading..." });
151
+ if (!user) return null;
169
152
  return /* @__PURE__ */ jsx2(Fragment, { children });
170
153
  }
171
154
 
@@ -180,29 +163,18 @@ function PasswordResetScreen() {
180
163
  const [email, setEmail] = useState2("");
181
164
  const [sent, setSent] = useState2(false);
182
165
  const [error, setError] = useState2(null);
183
- const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
184
166
  const requestReset = async (e) => {
185
167
  e.preventDefault();
186
168
  setError(null);
187
- const trimmedEmail = email.trim();
188
- if (!trimmedEmail) {
189
- setError("Email is required.");
190
- return;
191
- }
192
- if (!isValidEmail(trimmedEmail)) {
193
- setError("Enter a valid email address.");
194
- return;
195
- }
196
169
  try {
197
170
  const url = makeURL(config.baseURL, config.endpoints.forgot);
198
171
  await httpJSON(url, {
199
172
  method: "POST",
200
- body: JSON.stringify({ email: trimmedEmail })
173
+ body: JSON.stringify({ email })
201
174
  });
202
175
  setSent(true);
203
176
  } catch (err) {
204
- const message = err instanceof Error ? err.message : "Failed to request reset";
205
- setError(message);
177
+ setError(err?.message || "Failed to request reset");
206
178
  }
207
179
  };
208
180
  return /* @__PURE__ */ jsxs(
@@ -242,7 +214,6 @@ function PasswordResetScreen() {
242
214
  /* @__PURE__ */ jsx3(
243
215
  "label",
244
216
  {
245
- htmlFor: "afk-reset-email",
246
217
  style: {
247
218
  position: "absolute",
248
219
  top: sent ? "-18px" : "-10px",
@@ -259,7 +230,6 @@ function PasswordResetScreen() {
259
230
  /* @__PURE__ */ jsx3(
260
231
  "input",
261
232
  {
262
- id: "afk-reset-email",
263
233
  value: email,
264
234
  onChange: (e) => setEmail(e.target.value),
265
235
  type: "email",
@@ -322,8 +292,6 @@ function PasswordResetScreen() {
322
292
  error && /* @__PURE__ */ jsx3(
323
293
  "p",
324
294
  {
325
- role: "alert",
326
- "aria-live": "polite",
327
295
  style: {
328
296
  marginTop: 20,
329
297
  color: "crimson",
@@ -374,26 +342,15 @@ function LoginScreen() {
374
342
  setError(null);
375
343
  const trimmedEmail = email.trim();
376
344
  const trimmedPassword = password.trim();
377
- if (!trimmedEmail) {
378
- setError("Email is required.");
379
- setSubmitting(false);
380
- return;
381
- }
382
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmedEmail)) {
383
- setError("Enter a valid email address.");
384
- setSubmitting(false);
385
- return;
386
- }
387
- if (!trimmedPassword) {
388
- setError("Password is required.");
345
+ if (!trimmedEmail || !trimmedPassword) {
346
+ setError("Email and password cannot be empty.");
389
347
  setSubmitting(false);
390
348
  return;
391
349
  }
392
350
  try {
393
351
  await login(trimmedEmail, trimmedPassword);
394
352
  } catch (err) {
395
- const message = err instanceof Error ? err.message : "Login failed";
396
- setError(message);
353
+ setError(err?.message || "Login failed");
397
354
  } finally {
398
355
  setSubmitting(false);
399
356
  }
@@ -434,7 +391,6 @@ function LoginScreen() {
434
391
  /* @__PURE__ */ jsx4(
435
392
  "label",
436
393
  {
437
- htmlFor: "afk-login-email",
438
394
  style: {
439
395
  position: "absolute",
440
396
  top: "-10px",
@@ -451,7 +407,6 @@ function LoginScreen() {
451
407
  /* @__PURE__ */ jsx4(
452
408
  "input",
453
409
  {
454
- id: "afk-login-email",
455
410
  value: email,
456
411
  onChange: (e) => setEmail(e.target.value),
457
412
  type: "email",
@@ -481,7 +436,6 @@ function LoginScreen() {
481
436
  /* @__PURE__ */ jsx4(
482
437
  "label",
483
438
  {
484
- htmlFor: "afk-login-password",
485
439
  style: {
486
440
  position: "absolute",
487
441
  top: "-10px",
@@ -498,7 +452,6 @@ function LoginScreen() {
498
452
  /* @__PURE__ */ jsx4(
499
453
  "input",
500
454
  {
501
- id: "afk-login-password",
502
455
  value: password,
503
456
  onChange: (e) => setPassword(e.target.value),
504
457
  type: "password",
@@ -525,28 +478,17 @@ function LoginScreen() {
525
478
  )
526
479
  ] }),
527
480
  /* @__PURE__ */ jsx4(
528
- "div",
481
+ "p",
529
482
  {
483
+ onClick: () => setShowReset(true),
530
484
  style: {
531
- textAlign: "right"
485
+ textAlign: "right",
486
+ fontSize: 13,
487
+ color: "#4b4bff",
488
+ cursor: "pointer",
489
+ marginBottom: 24
532
490
  },
533
- children: /* @__PURE__ */ jsx4(
534
- "button",
535
- {
536
- onClick: () => setShowReset(true),
537
- style: {
538
- textAlign: "right",
539
- fontSize: 13,
540
- color: "#4b4bff",
541
- cursor: "pointer",
542
- marginBottom: 24,
543
- width: "fit-content",
544
- border: "none",
545
- background: "none"
546
- },
547
- children: "Forgot password?"
548
- }
549
- )
491
+ children: "Forgot password?"
550
492
  }
551
493
  ),
552
494
  /* @__PURE__ */ jsx4(
@@ -574,8 +516,6 @@ function LoginScreen() {
574
516
  error && /* @__PURE__ */ jsx4(
575
517
  "p",
576
518
  {
577
- role: "alert",
578
- "aria-live": "polite",
579
519
  style: {
580
520
  marginTop: 18,
581
521
  color: "crimson",
@@ -599,21 +539,8 @@ function SignupScreen() {
599
539
  const [name, setName] = useState4("");
600
540
  const [email, setEmail] = useState4("");
601
541
  const [password, setPassword] = useState4("");
602
- const [confirmPassword, setConfirmPassword] = useState4("");
603
542
  const [submitting, setSubmitting] = useState4(false);
604
543
  const [error, setError] = useState4(null);
605
- const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
606
- const getPasswordStrength = (value) => {
607
- let score = 0;
608
- if (value.length >= 8) score++;
609
- if (/[A-Z]/.test(value)) score++;
610
- if (/[0-9]/.test(value)) score++;
611
- if (/[^A-Za-z0-9]/.test(value)) score++;
612
- if (!value) return { label: "", color: "" };
613
- if (score <= 1) return { label: "Weak", color: "crimson" };
614
- if (score === 2) return { label: "Medium", color: "#f39c12" };
615
- return { label: "Strong", color: "#2ecc71" };
616
- };
617
544
  const onSubmit = async (e) => {
618
545
  e.preventDefault();
619
546
  setSubmitting(true);
@@ -621,47 +548,15 @@ function SignupScreen() {
621
548
  const trimmedEmail = email.trim();
622
549
  const trimmedPassword = password.trim();
623
550
  const trimmedName = name.trim();
624
- const trimmedConfirm = confirmPassword.trim();
625
- if (!trimmedName) {
626
- setError("Name is required.");
627
- setSubmitting(false);
628
- return;
629
- }
630
- if (!trimmedEmail) {
631
- setError("Email is required.");
632
- setSubmitting(false);
633
- return;
634
- }
635
- if (!isValidEmail(trimmedEmail)) {
636
- setError("Enter a valid email address.");
637
- setSubmitting(false);
638
- return;
639
- }
640
- if (!trimmedPassword) {
641
- setError("Password is required.");
642
- setSubmitting(false);
643
- return;
644
- }
645
- if (trimmedPassword.length < 8) {
646
- setError("Password must be at least 8 characters long.");
647
- setSubmitting(false);
648
- return;
649
- }
650
- if (!trimmedConfirm) {
651
- setError("Please confirm your password.");
652
- setSubmitting(false);
653
- return;
654
- }
655
- if (trimmedPassword !== trimmedConfirm) {
656
- setError("Passwords do not match.");
551
+ if (!trimmedEmail || !trimmedPassword || !trimmedName) {
552
+ setError("Email and password cannot be empty.");
657
553
  setSubmitting(false);
658
554
  return;
659
555
  }
660
556
  try {
661
- await signup({ name: trimmedName, email: trimmedEmail, password: trimmedPassword });
557
+ await signup({ name, email, password });
662
558
  } catch (err) {
663
- const message = err instanceof Error ? err.message : "Signup failed";
664
- setError(message);
559
+ setError(err?.message || "Signup failed");
665
560
  } finally {
666
561
  setSubmitting(false);
667
562
  }
@@ -703,7 +598,6 @@ function SignupScreen() {
703
598
  /* @__PURE__ */ jsx5(
704
599
  "label",
705
600
  {
706
- htmlFor: "afk-signup-name",
707
601
  style: {
708
602
  position: "absolute",
709
603
  top: "-10px",
@@ -720,7 +614,6 @@ function SignupScreen() {
720
614
  /* @__PURE__ */ jsx5(
721
615
  "input",
722
616
  {
723
- id: "afk-signup-name",
724
617
  value: name,
725
618
  onChange: (e) => setName(e.target.value),
726
619
  placeholder: "Your name",
@@ -749,7 +642,6 @@ function SignupScreen() {
749
642
  /* @__PURE__ */ jsx5(
750
643
  "label",
751
644
  {
752
- htmlFor: "afk-signup-email",
753
645
  style: {
754
646
  position: "absolute",
755
647
  top: "-10px",
@@ -766,7 +658,6 @@ function SignupScreen() {
766
658
  /* @__PURE__ */ jsx5(
767
659
  "input",
768
660
  {
769
- id: "afk-signup-email",
770
661
  value: email,
771
662
  onChange: (e) => setEmail(e.target.value),
772
663
  type: "email",
@@ -796,7 +687,6 @@ function SignupScreen() {
796
687
  /* @__PURE__ */ jsx5(
797
688
  "label",
798
689
  {
799
- htmlFor: "afk-signup-password",
800
690
  style: {
801
691
  position: "absolute",
802
692
  top: "-10px",
@@ -813,7 +703,6 @@ function SignupScreen() {
813
703
  /* @__PURE__ */ jsx5(
814
704
  "input",
815
705
  {
816
- id: "afk-signup-password",
817
706
  value: password,
818
707
  onChange: (e) => setPassword(e.target.value),
819
708
  type: "password",
@@ -839,95 +728,6 @@ function SignupScreen() {
839
728
  }
840
729
  )
841
730
  ] }),
842
- /* @__PURE__ */ jsxs3("div", { style: { position: "relative", marginBottom: 18 }, children: [
843
- /* @__PURE__ */ jsx5(
844
- "label",
845
- {
846
- htmlFor: "afk-signup-confirm-password",
847
- style: {
848
- position: "absolute",
849
- top: "-10px",
850
- left: "14px",
851
- background: "rgba(255,255,255,0.85)",
852
- padding: "0 6px",
853
- fontSize: 13,
854
- color: "#444",
855
- borderRadius: 6
856
- },
857
- children: "Confirm password"
858
- }
859
- ),
860
- /* @__PURE__ */ jsx5(
861
- "input",
862
- {
863
- id: "afk-signup-confirm-password",
864
- value: confirmPassword,
865
- onChange: (e) => setConfirmPassword(e.target.value),
866
- type: "password",
867
- placeholder: "Repeat your password",
868
- style: {
869
- width: "80%",
870
- padding: "14px 16px",
871
- borderRadius: 12,
872
- border: "1px solid #d2d2d2",
873
- fontSize: 15,
874
- outline: "none",
875
- transition: "0.25s",
876
- background: "rgba(255,255,255,0.85)"
877
- },
878
- onFocus: (e) => {
879
- e.currentTarget.style.border = "1px solid #4b4bff";
880
- e.currentTarget.style.boxShadow = "0 0 0 3px rgba(75,75,255,0.25)";
881
- },
882
- onBlur: (e) => {
883
- e.currentTarget.style.border = "1px solid #d2d2d2";
884
- e.currentTarget.style.boxShadow = "0 0 0 transparent";
885
- }
886
- }
887
- )
888
- ] }),
889
- /* @__PURE__ */ jsxs3(
890
- "div",
891
- {
892
- style: {
893
- marginBottom: 20,
894
- fontSize: 12,
895
- color: "#555"
896
- },
897
- children: [
898
- /* @__PURE__ */ jsx5("p", { style: { marginBottom: 6 }, children: "Use at least 8 characters, including letters, numbers, and symbols." }),
899
- password && /* @__PURE__ */ jsxs3(
900
- "p",
901
- {
902
- style: {
903
- fontWeight: 600,
904
- color: getPasswordStrength(password).color
905
- },
906
- children: [
907
- "Password strength: ",
908
- getPasswordStrength(password).label
909
- ]
910
- }
911
- )
912
- ]
913
- }
914
- ),
915
- /* @__PURE__ */ jsx5(
916
- "p",
917
- {
918
- style: {
919
- textAlign: "center",
920
- fontSize: 13,
921
- color: "#4b4bff",
922
- cursor: "pointer",
923
- marginBottom: 24
924
- },
925
- onClick: () => {
926
- window.dispatchEvent(new CustomEvent("auth-flow-kit:navigate-to-login"));
927
- },
928
- children: "Already have an account? Sign in"
929
- }
930
- ),
931
731
  /* @__PURE__ */ jsx5(
932
732
  "button",
933
733
  {
@@ -953,8 +753,6 @@ function SignupScreen() {
953
753
  error && /* @__PURE__ */ jsx5(
954
754
  "p",
955
755
  {
956
- role: "alert",
957
- "aria-live": "polite",
958
756
  style: {
959
757
  marginTop: 18,
960
758
  color: "crimson",