Fix login and panel visibility for user and reseller portals

- initUser/initReseller: show main-layout and hide auth-check on
  successful auth (was never shown, causing blank page after login)
- Fix login form IDs in user/index.php and reseller/index.php:
  changed l-user/l-pass/login-err to li-user/li-pass/li-err to
  match what doLogin() reads; add onsubmit handler so form works
  immediately without waiting for JS to replace it
- Wire logout button in both boot sequences
- Fix data.accounts → data in reseller.js (same paginate() bug as admin)
- Reset myron user password to Joker1974!!!

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 22:50:28 +00:00
parent eccbfbfeea
commit f75f124725
3 changed files with 23 additions and 15 deletions
+13 -5
View File
@@ -13,6 +13,8 @@ async function initReseller() {
}
_rUser = res.data;
document.getElementById('user-name').textContent = _rUser.username || 'Reseller';
document.getElementById('auth-check').style.display = 'none';
document.getElementById('main-layout').style.display = '';
return true;
}
@@ -56,10 +58,10 @@ async function rDashboard(el) {
</div>`;
const res = await Nova.api('accounts', 'list', { params:{ limit:5 }});
const accts = res?.data?.accounts || [];
const accts = res?.data || [];
document.getElementById('r-stats').innerHTML = [
{ label: 'Total Accounts', val: res?.data?.total || 0, icon: 'ni-accounts' },
{ label: 'Total Accounts', val: res?.meta?.total || accts.length, icon: 'ni-accounts' },
{ label: 'Active', val: accts.filter(a=>a.status==='active').length, icon: 'ni-stats' },
{ label: 'Suspended', val: accts.filter(a=>a.status==='suspended').length, icon: 'ni-suspend' },
].map(s => `<div class="stat-card" style="display:flex;align-items:center;gap:1rem">
@@ -95,9 +97,10 @@ async function loadRAccounts(search = '') {
const el = document.getElementById('r-accounts-list');
if (!el) return;
const res = await Nova.api('accounts', 'list', { params: search ? { search } : {}});
if (!res?.success || !res.data.accounts.length) { el.innerHTML = '<div class="empty">No accounts found.</div>'; return; }
const acctRows = res?.data || [];
if (!res?.success || !acctRows.length) { el.innerHTML = '<div class="empty">No accounts found.</div>'; return; }
el.innerHTML = `<table class="table"><thead><tr><th>Username</th><th>Domain</th><th>Package</th><th>Disk</th><th>Status</th><th>Actions</th></tr></thead><tbody>
${res.data.accounts.map(a => `<tr>
${acctRows.map(a => `<tr>
<td><strong>${a.username}</strong></td>
<td>${a.domain}</td>
<td>${a.package_name || '—'}</td>
@@ -326,6 +329,11 @@ window.resellerNav = (page) => {
document.addEventListener('DOMContentLoaded', async () => {
const ok = await initReseller();
if (!ok) return;
document.getElementById('logout-btn')?.addEventListener('click', async e => {
e.preventDefault();
await Nova.api('auth', 'logout', { method: 'POST' });
location.href = '/';
});
renderRNav();
window.resellerNav('dashboard');
});
@@ -338,7 +346,7 @@ async function rDocker(el) {
Nova.api('accounts', 'list', { params: { limit: 200 } }),
]);
const stacks = stRes?.data?.stacks || [];
const accts = acctRes?.data?.accounts || [];
const accts = acctRes?.data || [];
el.innerHTML = `
<div class="page-header"><h2 class="page-title">Docker</h2></div>
+5 -5
View File
@@ -61,11 +61,11 @@ $_pname = novacpx_panel_name('NovaCPX');
</div>
<div class="card">
<div class="card-body">
<div id="login-err" class="alert alert-error" style="display:none"></div>
<form id="login-form">
<div class="form-group"><label>Username or Email</label><input type="text" id="l-user" autofocus required></div>
<div class="form-group"><label>Password</label><input type="password" id="l-pass" required></div>
<button type="submit" class="btn btn-primary btn-full" id="l-btn">Sign In to Reseller Panel</button>
<div id="li-err" class="alert alert-error" style="display:none"></div>
<form id="login-form" onsubmit="event.preventDefault();doLogin()">
<div class="form-group"><label>Username or Email</label><input type="text" id="li-user" autofocus autocomplete="username"></div>
<div class="form-group"><label>Password</label><input type="password" id="li-pass" autocomplete="current-password"></div>
<button type="submit" class="btn btn-primary btn-full">Sign In to Reseller Panel</button>
</form>
</div>
</div>
+5 -5
View File
@@ -188,11 +188,11 @@ svg.ring circle { transition: stroke-dashoffset .5s; }
</div>
<div class="card">
<div class="card-body">
<div id="login-err" class="alert alert-error" style="display:none"></div>
<form id="login-form">
<div class="form-group"><label>Username or Email</label><input type="text" id="l-user" autofocus required></div>
<div class="form-group"><label>Password</label><input type="password" id="l-pass" required></div>
<button type="submit" class="btn btn-primary btn-full" id="l-btn">Sign In</button>
<div id="li-err" class="alert alert-error" style="display:none"></div>
<form id="login-form" onsubmit="event.preventDefault();doLogin()">
<div class="form-group"><label>Username or Email</label><input type="text" id="li-user" autofocus autocomplete="username"></div>
<div class="form-group"><label>Password</label><input type="password" id="li-pass" autocomplete="current-password"></div>
<button type="submit" class="btn btn-primary btn-full">Sign In</button>
</form>
</div>
</div>