/**
* portal/auth/pages.mjs — 인증·계정 화면 HTML(서버 렌더). 데이터·동작은 /ui/auth/auth.js 가 /api/auth·/api/account 를 불러 처리한다.
* 로그인 전 화면(로그인·가입·확인·재설정)은 공통 틀의 비로그인 모드로, 로그인 뒤 화면(내 계정·보안·기기)은 왼쪽 메뉴가 있는 모드로 그린다.
*/
import { esc } from '../../lib/http.mjs';
import { t } from '../../lib/i18n.mjs';
const box = (title, inner, foot = '') => `
${esc(title)} ${inner}${foot ? `
${foot}
` : ''}
`;
const f = (id, label, type = 'text', extra = '', hint = '') => `${esc(label)} ${hint ? `${esc(hint)} ` : ''}
`;
export function loginPage(shell, { next = '/', notice = '' } = {}) {
return shell({ title: t('auth.login.title'), nav: null, scripts: ['/ui/auth/auth.js'], body: box(t('auth.login.title'), `
${notice ? `${esc(notice)}
` : ''}
`,
`${esc(t('auth.login.noAccount'))} ${esc(t('auth.signup.title'))} · ${esc(t('auth.login.forgot'))} ${esc(t('auth.login.operatorNote'))} `) });
}
export function signupPage(shell) {
return shell({ title: t('auth.signup.title'), nav: null, scripts: ['/ui/auth/auth.js'], body: box(t('auth.signup.title'), `
`, `${esc(t('auth.login.title')) } `) });
}
export function verifyPage(shell, { state, user }) {
const msg = { ok: t('auth.verify.ok'), invalid: t('auth.verify.invalid'), used: t('auth.verify.used') }[state] || t('auth.verify.invalid');
return shell({ title: t('auth.verify.title'), nav: null, user, scripts: ['/ui/auth/auth.js'], body: box(t('auth.verify.title'), `${esc(msg)}
${state === 'ok' ? `${esc(t('nav.dashboard'))} ` : `${esc(t('auth.verify.resend'))} ${esc(t('auth.login.title'))} `}`) });
}
export function resetRequestPage(shell) {
return shell({ title: t('auth.reset.title'), nav: null, scripts: ['/ui/auth/auth.js'], body: box(t('auth.reset.title'), `
`, `${esc(t('auth.login.title'))} `) });
}
export function resetFormPage(shell, { token, state }) {
const body = state === 'valid' ? `
`
: `${esc(t('auth.reset.state'))}: ${esc(state === 'used' ? t('auth.reset.used') : t('auth.reset.expired'))}
${esc(t('auth.reset.request'))} `;
return shell({ title: t('auth.reset.title'), nav: null, scripts: ['/ui/auth/auth.js'], body: box(t('auth.reset.title'), body) });
}
/** 내 계정(프로필·비밀번호·이메일 확인 상태) */
export function accountPage(shell, o) {
const u = o.user;
return shell({ ...o, title: t('auth.account.title'), nav: null, crumbs: [{ label: t('auth.account.title') }], scripts: ['/ui/auth/auth.js'], body: `
${!u.email_verified_at ? `${esc(t('auth.verify.banner'))} ${esc(t('auth.verify.resend'))}
` : ''}
${esc(t('auth.account.profile'))} ${esc(t('auth.login.email'))} ${esc(u.email)} ${u.email_verified_at ? '✔ 확인됨 ' : '! 확인 전 '}
${esc(t('auth.account.changePassword'))} 비밀번호를 바꾸면 다른 기기의 로그인이 모두 종료됩니다.
` });
}
export function securityPage(shell, o) {
const mfaOn = !!o.mfaEnabled;
return shell({ ...o, title: t('auth.mfa.title'), nav: null, crumbs: [{ label: t('auth.account.title'), href: '/account' }, { label: t('auth.account.security') }], scripts: ['/ui/auth/auth.js'], body: `
${esc(t('auth.mfa.title'))} ${esc(t('auth.mfa.level'))} ${mfaOn ? `✔ ${esc(t('auth.mfa.levelMfa'))} ` : `! ${esc(t('auth.mfa.levelPw'))} `} ${esc(t('auth.mfa.title'))} ${esc(mfaOn ? t('auth.mfa.enabled') : t('auth.mfa.disabled'))}${o.mfaEnabledAt ? ` (${esc(o.mfaEnabledAt)}) ` : ''} ${mfaOn ? `${esc(t('auth.mfa.recovery'))} 남은 복구 코드 ${o.recoveryLeft}개 ` : ''}
${mfaOn ? `
`
: `
${esc(t('auth.mfa.setup'))}
`}
` });
}
export function sessionsPage(shell, o) {
return shell({ ...o, title: t('auth.sessions.title'), nav: null, crumbs: [{ label: t('auth.account.title'), href: '/account' }, { label: t('auth.sessions.title') }], scripts: ['/ui/auth/auth.js'], body: `
${esc(t('auth.sessions.title'))} ${esc(t('auth.sessions.revokeOthers'))} ${o.statePanel('loading')}
` });
}