feat: email verification for free tier signup
- Signup now requires email verification before API key is revealed - Verification token sent via email (Resend) with console fallback - GET /verify?token=xxx shows API key in styled HTML page - Handles expired (24h), invalid, and already-verified tokens - Frontend modal shows 'check your email' instead of key - Keeps existing rate limiting
This commit is contained in:
parent
890b82e5ec
commit
1b20665b0d
7 changed files with 252 additions and 29 deletions
|
|
@ -9,6 +9,7 @@ function openSignup() {
|
|||
document.getElementById('signupModal').classList.add('active');
|
||||
showState('signupInitial');
|
||||
document.getElementById('signupError').style.display = 'none';
|
||||
document.getElementById('signupEmail').value = '';
|
||||
}
|
||||
|
||||
function closeSignup() {
|
||||
|
|
@ -18,6 +19,15 @@ function closeSignup() {
|
|||
async function submitSignup() {
|
||||
var errEl = document.getElementById('signupError');
|
||||
var btn = document.getElementById('signupBtn');
|
||||
var emailInput = document.getElementById('signupEmail');
|
||||
var email = emailInput.value.trim();
|
||||
|
||||
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||
errEl.textContent = 'Please enter a valid email address.';
|
||||
errEl.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
errEl.style.display = 'none';
|
||||
btn.disabled = true;
|
||||
showState('signupLoading');
|
||||
|
|
@ -26,7 +36,7 @@ async function submitSignup() {
|
|||
var res = await fetch('/v1/signup/free', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
body: JSON.stringify({ email: email })
|
||||
});
|
||||
var data = await res.json();
|
||||
|
||||
|
|
@ -38,7 +48,7 @@ async function submitSignup() {
|
|||
return;
|
||||
}
|
||||
|
||||
document.getElementById('apiKeyText').textContent = data.apiKey;
|
||||
// Show "check your email" message
|
||||
showState('signupResult');
|
||||
} catch (err) {
|
||||
showState('signupInitial');
|
||||
|
|
@ -86,11 +96,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
document.getElementById('btn-checkout').addEventListener('click', checkout);
|
||||
document.getElementById('btn-close-signup').addEventListener('click', closeSignup);
|
||||
document.getElementById('signupBtn').addEventListener('click', submitSignup);
|
||||
document.getElementById('copyBtn').addEventListener('click', copyKey);
|
||||
document.getElementById('signupModal').addEventListener('click', function(e) {
|
||||
if (e.target === this) closeSignup();
|
||||
});
|
||||
// Smooth scroll for nav links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(function(a) {
|
||||
a.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -357,14 +357,11 @@ html, body {
|
|||
</div>
|
||||
|
||||
<div id="signupResult">
|
||||
<h2>🚀 You're in!</h2>
|
||||
<h2>📧 Check your email!</h2>
|
||||
<p style="color:var(--fg);line-height:1.7;">We've sent a verification link to your email address. Click the link to get your API key.</p>
|
||||
<div class="warning-box">
|
||||
<span class="icon">⚠️</span>
|
||||
<span>Save your API key now — we can't recover it later.</span>
|
||||
</div>
|
||||
<div class="key-box" id="apiKeyDisplay">
|
||||
<span class="key-text" id="apiKeyText"></span>
|
||||
<button class="copy-btn" id="copyBtn">Copy</button>
|
||||
<span class="icon">💡</span>
|
||||
<span>The link expires in 24 hours. Check your spam folder if you don't see it.</span>
|
||||
</div>
|
||||
<p style="margin-top:20px;color:var(--muted);font-size:0.9rem;">100 free PDFs/month • <a href="/docs">Read the docs →</a></p>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue