Files
shopify-ai-backup/chat/public/admin-login.js

89 lines
3.1 KiB
JavaScript

(() => {
const form = document.getElementById('admin-login-form');
const statusEl = document.getElementById('admin-login-status');
const userEl = document.getElementById('admin-username');
const passEl = document.getElementById('admin-password');
function setStatus(msg, isError = false) {
if (!statusEl) return;
statusEl.textContent = msg || '';
statusEl.style.color = isError ? 'var(--danger)' : 'inherit';
}
async function ensureSession() {
try {
// Include credentials explicitly so cookies are reliably sent/received across browsers
const res = await fetch('/api/admin/me', { credentials: 'same-origin' });
if (!res.ok) return;
const data = await res.json();
if (data && data.ok) {
const params = new URLSearchParams(window.location.search);
const next = params.get('next');
// Only redirect if we have a next parameter and we're not already on that page
if (next && typeof next === 'string' && next.startsWith('/') && window.location.pathname !== next) {
window.location.href = next;
} else if (!next) {
// If no next parameter, go to admin dashboard
window.location.href = '/admin';
}
}
} catch (_) {
/* ignore */
}
}
form.addEventListener('submit', async (e) => {
e.preventDefault();
setStatus('Signing in...');
try {
const payload = {
username: userEl.value.trim(),
password: passEl.value.trim(),
};
// Ensure credentials are included so Set-Cookie is accepted and future requests send cookies
const res = await fetch('/api/admin/login', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data.error || 'Login failed');
setStatus('Success, redirecting...');
// Respect optional `next` parameter (e.g. /admin/login?next=/test-checkout)
const params = new URLSearchParams(window.location.search);
const next = params.get('next');
// Poll /api/admin/me to ensure the session cookie is active before redirecting.
// This avoids a race where the next page immediately checks /api/admin/me and gets 401.
let sessionActive = false;
for (let i = 0; i < 6; i++) {
try {
const meRes = await fetch('/api/admin/me', { credentials: 'same-origin' });
if (meRes.ok) {
sessionActive = true;
break;
}
} catch (_) {
// ignore
}
// small backoff
await new Promise((r) => setTimeout(r, 150 * (i + 1)));
}
// Redirect regardless (session will usually be active) but polling reduces redirect loops
if (next && typeof next === 'string' && next.startsWith('/')) {
window.location.href = next;
} else {
window.location.href = '/admin';
}
} catch (err) {
setStatus(err.message, true);
}
});
ensureSession();
})();