메일 서비스(사이트 대표·독립)·메일함·사용량·보안·전환·보존과 AriMail 도입 수정(KST 월 경계, 발신 키 오류, 도메인별 보장량, 100% 제한, 발송 큐·속도, 운영 상태, SSO) (§15~§18·§0.4)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
zzabisagent-lab
2026-10-26 11:47:45 +00:00
co-authored by Claude Fable 5.1
parent a014e3cd05
commit a1cde81332
26 changed files with 1610 additions and 37 deletions
+1 -1
View File
@@ -99,7 +99,7 @@ function domainsCard() {
const cur = d.domain === DOMAIN;
const btns = [`<button type="button" class="small ${cur ? '' : 'primary'}" data-domain-select="${esc(d.domain)}" ${cur ? 'disabled' : ''}>${cur ? '보는 중' : '선택'}</button>`, `<button type="button" class="small" data-domain-edit="${esc(d.domain)}">수정</button>`];
if (!d.primary) btns.push(`<button type="button" class="small" data-domain-toggle="${esc(d.domain)}" data-enabled="${d.enabled ? '1' : '0'}">${d.enabled ? '중지' : '사용'}</button>`, `<button type="button" class="small ghost" data-domain-remove="${esc(d.domain)}">삭제</button>`);
return `<tr class="${cur ? 'current' : ''} ${d.enabled ? '' : 'off'}"><td><code>${esc(d.domain)}</code>${d.primary ? ' <span class="tag">기본</span>' : ''}${d.note ? `<div class="meta muted">${esc(d.note)}</div>` : ''}</td><td class="mono">${d.hosts.map(esc).join('<br>')}</td><td>${d.enabled ? tag(true, '사용', '') : tag(false, '', '중지')}</td><td>${esc(AUTH_LABEL[d.auth.mode] || d.auth.mode)}${d.auth.mode === 'www' ? `<div class="meta muted">${esc(d.auth.wwwDbFile)}</div>` : ''}${d.auth.mode === 'webmaker' ? `<div class="meta muted">${esc(d.auth.webmakerDir)}${d.auth.webmakerUser ? ` (sudo -u ${esc(d.auth.webmakerUser)})` : ''}</div>${d.external && d.external.error ? `<div class="meta warn">읽기 실패: ${esc(d.external.error)}</div>` : ''}` : ''}</td><td>${esc(MODES.inbound[d.inbound] ? MODES.inbound[d.inbound][0] : d.inbound)} / ${esc(MODES.outbound[d.outbound] ? MODES.outbound[d.outbound][0] : d.outbound)}</td><td>${d.accounts}명${d.external && !d.external.error ? ` + 웹메이커 ${d.external.count}명` : ''} · ${d.messages}통${d.initialPassword ? `<div class="meta warn">초기 관리자 ${esc(d.mailbox.split('@')[0])} / ${esc(d.initialPassword)}</div>` : ''}</td><td class="actions-cell">${btns.join('')}</td></tr>`;
return `<tr class="${cur ? 'current' : ''} ${d.enabled ? '' : 'off'}"><td><code>${esc(d.domain)}</code>${d.primary ? ' <span class="tag">기본</span>' : ''}${d.note ? `<div class="meta muted">${esc(d.note)}</div>` : ''}</td><td class="mono">${d.hosts.map(esc).join('<br>')}</td><td>${d.enabled ? tag(true, '사용', '') : tag(false, '', '중지')}${d.operating && d.operating !== 'active' ? `<div class="meta warn">운영 상태: ${esc({ migrating_out: '이전 중(보내는 쪽)', migrating_in: '이전 중(받는 쪽)', frozen: '동결' }[d.operating] || d.operating)}</div>` : ''}${d.ariweb ? `<div class="meta muted">Ariweb: ${esc(d.ariweb.kind === 'site_bound' ? '사이트 대표 메일' : '독립 메일 서비스')}${d.ariweb.siteId ? ' · 사이트 ' + esc(d.ariweb.siteId) : ''}</div>` : ''}</td><td>${esc(AUTH_LABEL[d.auth.mode] || d.auth.mode)}${d.auth.mode === 'www' ? `<div class="meta muted">${esc(d.auth.wwwDbFile)}</div>` : ''}${d.auth.mode === 'webmaker' ? `<div class="meta muted">${esc(d.auth.webmakerDir)}${d.auth.webmakerUser ? ` (sudo -u ${esc(d.auth.webmakerUser)})` : ''}</div>${d.external && d.external.error ? `<div class="meta warn">읽기 실패: ${esc(d.external.error)}</div>` : ''}` : ''}</td><td>${esc(MODES.inbound[d.inbound] ? MODES.inbound[d.inbound][0] : d.inbound)} / ${esc(MODES.outbound[d.outbound] ? MODES.outbound[d.outbound][0] : d.outbound)}</td><td>${d.accounts}명${d.external && !d.external.error ? ` + 웹메이커 ${d.external.count}명` : ''} · ${d.messages}통${d.initialPassword ? `<div class="meta warn">초기 관리자 ${esc(d.mailbox.split('@')[0])} / ${esc(d.initialPassword)}</div>` : ''}</td><td class="actions-cell">${btns.join('')}</td></tr>`;
}).join('');
const e = EDIT, editing = !!e, isPrimaryEdit = editing && e.primary;
const form = `<form id="f-domain" class="domain-form ${editing ? 'editing' : ''}"><h3>${editing ? `도메인 수정 — ${esc(e.domain)}` : '도메인 추가'}</h3><div class="grid">