@authon/js 0.6.0 → 0.7.0

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 CHANGED
@@ -837,6 +837,53 @@ var ModalRenderer = class {
837
837
  if (!this.shadowRoot) return;
838
838
  this.shadowRoot.getElementById("authon-error-msg")?.remove();
839
839
  }
840
+ showVerificationInput(email, onVerify, onResend) {
841
+ if (!this.shadowRoot) return;
842
+ const inner = this.shadowRoot.querySelector(".modal-inner");
843
+ if (!inner) return;
844
+ inner.innerHTML = `
845
+ <div style="text-align:center;padding:8px 0">
846
+ <div style="width:48px;height:48px;border-radius:12px;background:color-mix(in srgb, var(--authon-primary-start) 15%, transparent);display:flex;align-items:center;justify-content:center;margin:0 auto 16px">
847
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--authon-primary-start)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
848
+ </div>
849
+ <h2 class="title" style="font-size:20px;margin-bottom:4px">${this.t.welcomeBack.includes("Welcome") ? "Check your email" : this.t.welcomeBack}</h2>
850
+ <p style="font-size:13px;color:var(--authon-muted);margin-bottom:20px">${email}</p>
851
+ </div>
852
+ <div class="email-form" id="verify-form">
853
+ <input type="text" id="verify-code" class="input" placeholder="000000" maxlength="6" inputmode="numeric" autocomplete="one-time-code" style="text-align:center;font-size:20px;letter-spacing:0.2em;font-family:ui-monospace,monospace" />
854
+ <button type="button" id="verify-submit" class="submit-btn">${this.t.signIn}</button>
855
+ </div>
856
+ <p style="text-align:center;margin-top:12px;font-size:12px;color:var(--authon-dim)">
857
+ <a href="#" id="resend-link" style="color:var(--authon-primary-start);text-decoration:none;font-weight:500">${this.t.backToSignIn.includes("Back") ? "Resend code" : this.t.backToSignIn}</a>
858
+ </p>
859
+ `;
860
+ const codeInput = this.shadowRoot.getElementById("verify-code");
861
+ const submitBtn = this.shadowRoot.getElementById("verify-submit");
862
+ const resendLink = this.shadowRoot.getElementById("resend-link");
863
+ codeInput?.focus();
864
+ codeInput?.addEventListener("input", () => {
865
+ codeInput.value = codeInput.value.replace(/\D/g, "").slice(0, 6);
866
+ });
867
+ submitBtn?.addEventListener("click", async () => {
868
+ const code = codeInput?.value?.trim();
869
+ if (!code || code.length < 6) return;
870
+ submitBtn.textContent = "...";
871
+ submitBtn.disabled = true;
872
+ await onVerify(code);
873
+ });
874
+ codeInput?.addEventListener("keydown", (e) => {
875
+ if (e.key === "Enter") submitBtn?.click();
876
+ });
877
+ resendLink?.addEventListener("click", async (e) => {
878
+ e.preventDefault();
879
+ resendLink.textContent = "...";
880
+ await onResend();
881
+ resendLink.textContent = "Sent!";
882
+ setTimeout(() => {
883
+ resendLink.textContent = "Resend code";
884
+ }, 2e3);
885
+ });
886
+ }
840
887
  showLoading() {
841
888
  if (!this.shadowRoot) return;
842
889
  this.hideLoading();
@@ -3035,14 +3082,27 @@ var Authon = class {
3035
3082
  return res.user;
3036
3083
  }
3037
3084
  async signUpWithEmail(email, password, meta) {
3038
- const tokens = await this.apiPost("/v1/auth/signup", {
3085
+ const res = await this.apiPost("/v1/auth/signup", {
3039
3086
  email,
3040
3087
  password,
3041
3088
  ...meta
3042
3089
  });
3043
- this.session.setSession(tokens);
3044
- this.emit("signedIn", tokens.user);
3045
- return tokens.user;
3090
+ if (res.needsVerification) {
3091
+ this.emit("verificationRequired", res.email);
3092
+ return { needsVerification: true, email: res.email };
3093
+ }
3094
+ this.session.setSession(res);
3095
+ this.emit("signedIn", res.user);
3096
+ return res.user;
3097
+ }
3098
+ async verifyEmail(email, code) {
3099
+ const res = await this.apiPost("/v1/auth/verify-email", { email, code });
3100
+ this.session.setSession(res);
3101
+ this.emit("signedIn", res.user);
3102
+ return res.user;
3103
+ }
3104
+ async resendVerificationCode(email) {
3105
+ await this.apiPost("/v1/auth/resend-code", { email });
3046
3106
  }
3047
3107
  async signOut() {
3048
3108
  await this.session.signOut();
@@ -3393,13 +3453,37 @@ var Authon = class {
3393
3453
  onEmailSubmit: (email, password, isSignUp) => {
3394
3454
  this.modal?.clearError();
3395
3455
  const turnstileToken = this.modal?.getTurnstileToken?.() || void 0;
3396
- const promise = isSignUp ? this.signUpWithEmail(email, password, { turnstileToken }) : this.signInWithEmail(email, password, turnstileToken);
3397
- promise.then(() => this.modal?.close()).catch((err) => {
3398
- this.modal?.resetTurnstile?.();
3399
- const msg = err instanceof Error ? err.message : String(err);
3400
- this.modal?.showError(msg || "Authentication failed");
3401
- this.emit("error", err instanceof Error ? err : new Error(msg));
3402
- });
3456
+ if (isSignUp) {
3457
+ this.signUpWithEmail(email, password, { turnstileToken }).then((result) => {
3458
+ if ("needsVerification" in result && result.needsVerification) {
3459
+ this.modal?.showVerificationInput(email, async (code) => {
3460
+ try {
3461
+ await this.verifyEmail(email, code);
3462
+ this.modal?.close();
3463
+ } catch (err) {
3464
+ const msg = err instanceof Error ? err.message : String(err);
3465
+ this.modal?.showError(msg || "Verification failed");
3466
+ }
3467
+ }, async () => {
3468
+ await this.resendVerificationCode(email);
3469
+ });
3470
+ } else {
3471
+ this.modal?.close();
3472
+ }
3473
+ }).catch((err) => {
3474
+ this.modal?.resetTurnstile?.();
3475
+ const msg = err instanceof Error ? err.message : String(err);
3476
+ this.modal?.showError(msg || "Authentication failed");
3477
+ this.emit("error", err instanceof Error ? err : new Error(msg));
3478
+ });
3479
+ } else {
3480
+ this.signInWithEmail(email, password, turnstileToken).then(() => this.modal?.close()).catch((err) => {
3481
+ this.modal?.resetTurnstile?.();
3482
+ const msg = err instanceof Error ? err.message : String(err);
3483
+ this.modal?.showError(msg || "Authentication failed");
3484
+ this.emit("error", err instanceof Error ? err : new Error(msg));
3485
+ });
3486
+ }
3403
3487
  },
3404
3488
  onClose: () => this.modal?.close(),
3405
3489
  onWeb3WalletSelect: async (walletId) => {