feat: add dedicated Create Account form with field inputs and sub-tabs
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 23s

This commit is contained in:
vickytechkey 2026-09-13 10:18:47 +05:30
parent ea76459d63
commit 4618bb0c6b

View file

@ -900,18 +900,67 @@
<div class="card">
<div class="card-header">
<div class="card-title">
<span>🔐</span> 1. Authentication &amp; Sessions
<span>🔐</span> 1. Authentication &amp; User Accounts
</div>
<span class="card-title-tag">POST /api/auth/*</span>
</div>
<p style="font-size: 0.8rem; color: var(--text-muted);">
Test supplier onboarding, JWT token issuance, simulated OTP verification, and session management.
</p>
<!-- Auth Sub-tabs -->
<div class="pill-btn-group" style="width: 100%; display: flex;">
<button id="tabBtnRegister" class="pill-btn active" style="flex: 1; text-align: center;" onclick="switchAuthSubTab('register')">
📝 Create Account
</button>
<button id="tabBtnLogin" class="pill-btn" style="flex: 1; text-align: center;" onclick="switchAuthSubTab('login')">
🔑 Sign In
</button>
<button id="tabBtnOtp" class="pill-btn" style="flex: 1; text-align: center;" onclick="switchAuthSubTab('otp')">
📱 Verify OTP
</button>
</div>
<!-- Sub-tab 1: Create Account Form -->
<div id="authSubTabRegister">
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.75rem;">
Create a brand new supplier account. Generates JWT tokens and sends mock verification OTPs.
</p>
<div class="form-row">
<div class="form-group">
<label>Username / Email</label>
<label>Username</label>
<input type="text" id="regUsername" value="artisan_seller_01">
</div>
<div class="form-group">
<label>Email Address</label>
<input type="email" id="regEmail" value="artisan01@example.com">
</div>
</div>
<div class="form-row" style="margin-top: 0.5rem;">
<div class="form-group">
<label>Phone Number (10 Digits)</label>
<input type="text" id="regPhone" value="9876543210">
</div>
<div class="form-group">
<label>Password (Min 8 chars)</label>
<input type="password" id="regPassword" value="SecurePassword123!">
</div>
</div>
<div style="display: flex; gap: 0.5rem; margin-top: 0.85rem; flex-wrap: wrap;">
<button class="btn btn-success btn-sm" onclick="runCreateAccount()">
✨ Create Account
</button>
<button class="btn btn-secondary btn-sm" onclick="randomizeRegisterFields()">
🎲 Randomize Fields
</button>
</div>
</div>
<!-- Sub-tab 2: Sign In Form -->
<div id="authSubTabLogin" style="display: none;">
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.75rem;">
Authenticate an existing supplier with username or phone number.
</p>
<div class="form-row">
<div class="form-group">
<label>Username or Phone</label>
<input type="text" id="authUsername" value="demo_seller">
</div>
<div class="form-group">
@ -919,20 +968,24 @@
<input type="password" id="authPassword" value="super_secure_pass_123">
</div>
</div>
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
<div style="display: flex; gap: 0.5rem; margin-top: 0.85rem; flex-wrap: wrap;">
<button class="btn btn-primary btn-sm" onclick="runLogin()">
🔑 Authenticate (Login)
🔑 Sign In
</button>
<button class="btn btn-secondary btn-sm" onclick="runRegister()">
📝 Register New User
<button class="btn btn-secondary btn-sm" onclick="fillDemoSeller()">
⚡ Fill Demo Seller
</button>
<button class="btn btn-secondary btn-sm" onclick="runLogout()">
<button class="btn btn-danger btn-sm" onclick="runLogout()">
🚪 Logout
</button>
</div>
</div>
<div style="border-top: 1px solid var(--border-color); padding-top: 0.75rem; margin-top: 0.25rem;">
<!-- Sub-tab 3: Verify OTP Form -->
<div id="authSubTabOtp" style="display: none;">
<p style="font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.75rem;">
Validate simulated 2FA verification codes (default mock code: <code>123456</code>).
</p>
<div class="form-row">
<div class="form-group">
<label>OTP Verification Type</label>
@ -942,14 +995,25 @@
</select>
</div>
<div class="form-group">
<label>OTP Code (Default: 123456)</label>
<label>OTP Code</label>
<input type="text" id="otpCode" value="123456">
</div>
</div>
<button class="btn btn-secondary btn-sm" style="margin-top: 0.5rem;" onclick="runVerifyOtp()">
<div style="display: flex; gap: 0.5rem; margin-top: 0.85rem;">
<button class="btn btn-primary btn-sm" onclick="runVerifyOtp()">
✅ Verify OTP Code
</button>
</div>
</div>
<!-- Active Session Info Card -->
<div style="border-top: 1px solid var(--border-color); padding-top: 0.65rem; display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem; color: var(--text-muted);">
<span>Active: <strong id="sessionUserLabel" style="color: var(--text-main);">Anonymous / Dummy</strong></span>
<div style="display: flex; gap: 0.4rem;">
<button class="btn btn-secondary btn-sm" style="padding: 2px 7px; font-size: 0.7rem;" onclick="copyToken()">Copy JWT</button>
<button class="btn btn-secondary btn-sm" style="padding: 2px 7px; font-size: 0.7rem;" onclick="runLogout()">Logout</button>
</div>
</div>
<!-- Response Inspector -->
<div class="response-inspector" id="authResponseWrap" style="display: none;">
@ -1332,12 +1396,23 @@
// Update Header Auth UI
function updateAuthUI() {
const authBadge = document.getElementById('headerAuthUser');
const sessionLabel = document.getElementById('sessionUserLabel');
const savedUser = localStorage.getItem('seller_central_active_user') || '';
if (activeToken) {
authBadge.innerText = 'Token Active (Bearer)';
authBadge.innerText = savedUser ? `User: ${savedUser}` : 'Token Active (Bearer)';
authBadge.style.color = '#34d399';
if (sessionLabel) {
sessionLabel.innerText = savedUser ? `${savedUser} (Authenticated)` : 'Logged In (Bearer Token)';
sessionLabel.style.color = '#34d399';
}
} else {
authBadge.innerText = 'Dummy / Anonymous';
authBadge.style.color = '#94a3b8';
if (sessionLabel) {
sessionLabel.innerText = 'Anonymous / Dummy';
sessionLabel.style.color = '#94a3b8';
}
}
}
@ -1582,11 +1657,83 @@
}
// =========================================================================
// API TEST SUITE FUNCTIONS
// AUTHENTICATION & ACCOUNT CREATION LOGIC
// =========================================================================
function switchAuthSubTab(tab) {
document.getElementById('authSubTabRegister').style.display = tab === 'register' ? 'block' : 'none';
document.getElementById('authSubTabLogin').style.display = tab === 'login' ? 'block' : 'none';
document.getElementById('authSubTabOtp').style.display = tab === 'otp' ? 'block' : 'none';
document.getElementById('tabBtnRegister').classList.toggle('active', tab === 'register');
document.getElementById('tabBtnLogin').classList.toggle('active', tab === 'login');
document.getElementById('tabBtnOtp').classList.toggle('active', tab === 'otp');
}
function randomizeRegisterFields() {
const rand = Math.floor(1000 + Math.random() * 9000);
document.getElementById('regUsername').value = `seller_${rand}`;
document.getElementById('regEmail').value = `seller_${rand}@example.com`;
document.getElementById('regPhone').value = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
document.getElementById('regPassword').value = 'SecurePassword123!';
showToast('Generated fresh random credentials!', '🎲');
}
function fillDemoSeller() {
document.getElementById('authUsername').value = 'demo_seller';
document.getElementById('authPassword').value = 'super_secure_pass_123';
showToast('Pre-filled demo seller credentials', '⚡');
}
function copyToken() {
if (!activeToken) {
showToast('No active JWT token found. Please sign in.', '⚠️');
return;
}
navigator.clipboard.writeText(activeToken);
showToast('JWT Access Token copied to clipboard!', '📋');
}
async function runCreateAccount() {
const username = document.getElementById('regUsername').value.trim();
const email = document.getElementById('regEmail').value.trim();
const phone = document.getElementById('regPhone').value.trim();
const password = document.getElementById('regPassword').value;
if (!username || !email || !phone || !password) {
alert('All fields (username, email, phone, password) are required to create an account.');
return;
}
const res = await apiRequest('/api/auth/register/', 'POST', {
username,
email,
phone,
password,
confirm_password: password
});
showInspector('authResponseWrap', 'authStatusCode', 'authResponseBody', res);
if (res.ok && res.data?.access_token) {
activeToken = res.data.access_token;
localStorage.setItem('seller_central_access_token', activeToken);
localStorage.setItem('seller_central_active_user', username);
document.getElementById('authUsername').value = username;
updateAuthUI();
showToast(`Account created for ${username}! Verification OTPs sent.`, '🎉');
// Automatically switch to OTP tab and pre-fill default test OTP
document.getElementById('otpCode').value = '123456';
switchAuthSubTab('otp');
fetchLogs();
} else {
const errMsg = typeof res.data === 'object' ? Object.entries(res.data).map(([k,v]) => `${k}: ${v}`).join(' ') : (res.data || res.statusText);
showToast(`Registration failed: ${errMsg}`, '❌');
}
}
async function runLogin() {
const u = document.getElementById('authUsername').value;
const u = document.getElementById('authUsername').value.trim();
const p = document.getElementById('authPassword').value;
const res = await apiRequest('/api/auth/login/', 'POST', {
@ -1597,33 +1744,11 @@
showInspector('authResponseWrap', 'authStatusCode', 'authResponseBody', res);
if (res.ok && res.data?.access_token) {
activeToken = res.data.access_token;
const loggedUser = res.data?.user?.username || u;
localStorage.setItem('seller_central_access_token', activeToken);
localStorage.setItem('seller_central_active_user', loggedUser);
updateAuthUI();
showToast('Logged in successfully! Token stored.', '🔑');
fetchLogs();
}
}
async function runRegister() {
const rand = Math.floor(1000 + Math.random() * 9000);
const username = `seller_${rand}`;
const email = `seller_${rand}@example.com`;
const phone = `9${Math.floor(100000000 + Math.random() * 900000000)}`;
const res = await apiRequest('/api/auth/register/', 'POST', {
username,
email,
phone,
password: 'Password123!'
});
showInspector('authResponseWrap', 'authStatusCode', 'authResponseBody', res);
if (res.ok && res.data?.access_token) {
activeToken = res.data.access_token;
localStorage.setItem('seller_central_access_token', activeToken);
document.getElementById('authUsername').value = username;
updateAuthUI();
showToast(`Created ${username}! Access token saved.`, '🎉');
showToast(`Logged in successfully as ${loggedUser}!`, '🔑');
fetchLogs();
}
}
@ -1632,6 +1757,7 @@
const res = await apiRequest('/api/auth/logout/', 'POST');
activeToken = '';
localStorage.removeItem('seller_central_access_token');
localStorage.removeItem('seller_central_active_user');
updateAuthUI();
showInspector('authResponseWrap', 'authStatusCode', 'authResponseBody', res);
showToast('Logged out. Cleared local token.', '🚪');