Wire auth modal to register.telecom.quest API (login + register flow)

This commit is contained in:
ask 2026-05-17 10:18:21 +05:00
parent ccf82b5040
commit 004c8a1920

View File

@ -1414,11 +1414,12 @@ const SCHEDULE = [
}); });
/* ── AUTH ────────────────────────────────────────────── /* ── AUTH ──────────────────────────────────────────────
Single-form login/register: Smart single-form auth backed by register.telecom.quest.
- "Askar Tuleev" → CDN "atuleev" (initial + lastname, lowercase, latin only) - Login first (works for both FIO and CDN inputs).
- "askar" → CDN "askar" (passed through) - On 404 with FIO input → register (creates folder + Gitea repo).
Submit → save to localStorage → redirect to code-server in that folder. - On 404 with CDN input → "not found, type your full name to register".
*/ */
const API_BASE = 'https://register.telecom.quest/api';
const CODE_BASE = 'https://code.telecom.quest/?folder=/Users/telecom/dev/'; const CODE_BASE = 'https://code.telecom.quest/?folder=/Users/telecom/dev/';
const STORAGE_KEY = 'vibe.cdn'; const STORAGE_KEY = 'vibe.cdn';
@ -1472,8 +1473,18 @@ const SCHEDULE = [
} }
} }
function redirectTo(cdn) { function redirectTo(cdn, vscodeUrl) {
window.location.href = CODE_BASE + encodeURIComponent(cdn) + '/'; window.location.href = vscodeUrl || (CODE_BASE + encodeURIComponent(cdn) + '/');
}
async function apiCall(path, body) {
const res = await fetch(API_BASE + path, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const data = await res.json().catch(() => ({}));
return { ok: res.ok, status: res.status, data };
} }
function openModal() { function openModal() {
@ -1511,22 +1522,73 @@ const SCHEDULE = [
submit.disabled = false; submit.disabled = false;
}); });
submit.addEventListener('click', () => { async function handleSubmit() {
const { cdn } = makeCdn(input.value); const { cdn, mode } = makeCdn(input.value);
if (!cdn) return; if (!cdn) return;
localStorage.setItem(STORAGE_KEY, cdn);
refreshHeader(); submit.disabled = true;
redirectTo(cdn); submit.textContent = 'Проверяю...';
}); hint.classList.remove('error');
try {
// Step 1: try login (works for both CDN and FIO inputs)
const login = await apiCall('/login', { value: input.value.trim() });
if (login.ok) {
localStorage.setItem(STORAGE_KEY, login.data.cdn);
refreshHeader();
redirectTo(login.data.cdn, login.data.vscode_url);
return;
}
// Step 2: not found — for FIO mode, offer to register
if (login.status === 404 && mode === 'fio') {
submit.textContent = 'Создаю аккаунт...';
hint.innerHTML = `Аккаунт <code>${cdn}</code> не найден — создаю новый...`;
const reg = await apiCall('/register', { fio: input.value.trim() });
if (reg.ok) {
localStorage.setItem(STORAGE_KEY, reg.data.cdn);
refreshHeader();
redirectTo(reg.data.cdn, reg.data.vscode_url);
return;
}
// registration failed
const msg = reg.data?.detail?.message || reg.data?.detail?.error || `HTTP ${reg.status}`;
hint.textContent = `Не удалось создать: ${msg}`;
hint.classList.add('error');
} else if (login.status === 404) {
// CDN mode, no exact match — prompt full name
hint.innerHTML = `CDN <code>${cdn}</code> не найден. Введи имя и фамилию для регистрации.`;
hint.classList.add('error');
} else {
const msg = login.data?.detail?.message || login.data?.detail?.error || `HTTP ${login.status}`;
hint.textContent = `Ошибка: ${msg}`;
hint.classList.add('error');
}
} catch (err) {
hint.textContent = `Ошибка сети: ${err.message || err}`;
hint.classList.add('error');
} finally {
submit.disabled = false;
submit.textContent = 'Открыть VS Code →';
}
}
submit.addEventListener('click', handleSubmit);
input.addEventListener('keydown', (e) => { input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !submit.disabled) submit.click(); if (e.key === 'Enter' && !submit.disabled) handleSubmit();
if (e.key === 'Escape') closeModal(); if (e.key === 'Escape') closeModal();
}); });
authBtn.addEventListener('click', () => { authBtn.addEventListener('click', () => {
const saved = localStorage.getItem(STORAGE_KEY); const saved = localStorage.getItem(STORAGE_KEY);
if (saved) redirectTo(saved); else openModal(); if (saved) {
// Direct redirect using saved CDN — fast path, no API hit
redirectTo(saved);
} else {
openModal();
}
}); });
cdnChip.addEventListener('click', () => { cdnChip.addEventListener('click', () => {