Entrega read-only de apontamentos DNS (Cloudflare, OpenPanel BIND, público) no Desk e Console /admin/dominio, com spec, scripts de rollback e patches VM112 para painel lateral no passo DNS do onboarding (deploy wizard pendente). Co-authored-by: Cursor <cursoragent@cursor.com>
77 lines
3.1 KiB
Python
77 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Wizard UI — provision-email + painel credenciais proj_*."""
|
|
from pathlib import Path
|
|
import re
|
|
|
|
APP = Path("/opt/ligbox-wizard/frontend/src/App.jsx")
|
|
text = APP.read_text(encoding="utf-8")
|
|
|
|
if "projectCredentials" not in text:
|
|
text = text.replace(
|
|
" const [byoToken, setByoToken] = useState('')",
|
|
" const [byoToken, setByoToken] = useState('')\n"
|
|
" const [projectCredentials, setProjectCredentials] = useState(null)",
|
|
)
|
|
|
|
PROVISION_FN = '''
|
|
async function ensureProjectEmail() {
|
|
if (projectCredentials?.ligbox_project_email) return projectCredentials
|
|
const data = await api('/onboarding/project/provision-email', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ domain, display_name: companyLabelFromDomain(domain) }),
|
|
})
|
|
setProjectCredentials(data)
|
|
return data
|
|
}
|
|
|
|
'''
|
|
|
|
if "ensureProjectEmail" not in text:
|
|
text = text.replace(" async function choosePortalDns() {", PROVISION_FN + " async function choosePortalDns() {")
|
|
|
|
# inject ensureProjectEmail at start of choosePortalDns
|
|
if "await ensureProjectEmail()" not in text:
|
|
text = text.replace(
|
|
" startBusy('dns_zone')\n try {\n const resolved = dnsResolve",
|
|
" startBusy('dns_zone')\n try {\n const proj = await ensureProjectEmail()\n const resolved = dnsResolve",
|
|
)
|
|
|
|
PANEL = '''
|
|
{projectCredentials?.ligbox_project_email && (
|
|
<WizardStatusPanel variant="info" icon={ShieldCheck} title="Credenciais do projeto Ligbox">
|
|
<p>
|
|
E-mail: <strong>{projectCredentials.ligbox_project_email}</strong>
|
|
<br />
|
|
Webmail: <a href="https://mail.ligbox.com.br/" target="_blank" rel="noreferrer">mail.ligbox.com.br</a>
|
|
</p>
|
|
{projectCredentials.password_available && !projectCredentials.password && (
|
|
<ActionDoneButton
|
|
label="Mostrar senha do projeto (uma vez)"
|
|
onClick={async () => {
|
|
try {
|
|
const rev = await api(`/onboarding/project/${domain}/reveal-password`, { method: 'POST' })
|
|
setProjectCredentials((p) => ({ ...p, password: rev.password, password_shown: true }))
|
|
} catch (e) {
|
|
setError(e.message)
|
|
}
|
|
}}
|
|
/>
|
|
)}
|
|
{projectCredentials.password && (
|
|
<p className="sub">
|
|
Senha: <code>{projectCredentials.password}</code> — guarde agora.
|
|
</p>
|
|
)}
|
|
</WizardStatusPanel>
|
|
)}
|
|
|
|
'''
|
|
|
|
if "Credenciais do projeto Ligbox" not in text:
|
|
text = text.replace(
|
|
" {portalDnsApplied && (",
|
|
PANEL + " {portalDnsApplied && (",
|
|
)
|
|
|
|
APP.write_text(text, encoding="utf-8")
|
|
print("App.jsx project panel OK")
|