mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-15 23:03:14 -06:00
SSO settings: show a verification outcome once, not twice
First real-browser pass over this feature. Chrome via puppeteer-core, driving the
actual settings page: login, the SSO card, and a real click on Verify.
The click path works — the loadSso fix holds, no ReferenceError, and a failure shows
the specific DNS answer ("no _screentinker-verify record found ... DNS can take a few
minutes") rather than the generic catch-all. But the outcome was rendered TWICE: the
server persists last_error on the row and the template drew it, while the click handler
wrote the same sentence into a second element underneath. Anyone retrying a failed
verification saw the identical line twice, in two different colours.
One element now owns the outcome, and the handler replaces its text. Also colours the
in-flight "Checking DNS…" as muted rather than leaving it red.
Found by looking at a screenshot. Parsing, VM rendering and mutation testing all passed
over it — none of them draws anything.
18/18 browser checks, 1598 unit tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bvjey4FNam49MN7ybjcq6A
This commit is contained in:
parent
c91b96ab91
commit
481a44c15a
|
|
@ -743,8 +743,12 @@ export async function render(container) {
|
||||||
${d.verified ? '' : `
|
${d.verified ? '' : `
|
||||||
<div style="margin-top:6px;color:var(--text-muted)">${esc(t('sso.dns_instructions'))}</div>
|
<div style="margin-top:6px;color:var(--text-muted)">${esc(t('sso.dns_instructions'))}</div>
|
||||||
<code style="display:block;word-break:break-all;padding:6px;background:var(--bg-secondary);border-radius:4px;margin-top:4px">${esc(d.record_name)} TXT ${esc(d.txt_value)}</code>
|
<code style="display:block;word-break:break-all;padding:6px;background:var(--bg-secondary);border-radius:4px;margin-top:4px">${esc(d.record_name)} TXT ${esc(d.txt_value)}</code>
|
||||||
${d.last_error ? `<div style="margin-top:4px;color:var(--danger,#b91c1c)">${esc(d.last_error)}</div>` : ''}`}
|
`}
|
||||||
<div id="ssoVerify-${esc(p.id)}-${di}" style="margin-top:4px"></div>
|
<!-- ONE place for the outcome. The last failure is persisted server-side and was
|
||||||
|
rendered here, while the click handler wrote the live result into a second
|
||||||
|
element below it — so retrying showed the identical sentence twice, in two
|
||||||
|
different colours. The handler replaces this element's text instead. -->
|
||||||
|
<div id="ssoVerify-${esc(p.id)}-${di}" style="margin-top:4px;color:var(--danger,#b91c1c)">${d.verified ? '' : esc(d.last_error || '')}</div>
|
||||||
</div>`).join('')}
|
</div>`).join('')}
|
||||||
</div>` : ''}
|
</div>` : ''}
|
||||||
|
|
||||||
|
|
@ -797,7 +801,7 @@ export async function render(container) {
|
||||||
// `a-b-test`, and getElementById would put one domain's answer in the other's box.
|
// `a-b-test`, and getElementById would put one domain's answer in the other's box.
|
||||||
const out = document.getElementById(`ssoVerify-${id}-${btn.dataset.di}`);
|
const out = document.getElementById(`ssoVerify-${id}-${btn.dataset.di}`);
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
if (out) out.textContent = t('sso.verifying');
|
if (out) { out.style.color = 'var(--text-muted)'; out.textContent = t('sso.verifying'); }
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/organizations/${orgId}/sso/${id}/domains/${encodeURIComponent(domain)}/verify`, {
|
const res = await fetch(`/api/organizations/${orgId}/sso/${id}/domains/${encodeURIComponent(domain)}/verify`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -816,9 +820,9 @@ export async function render(container) {
|
||||||
await loadSso();
|
await loadSso();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (out) out.textContent = body.error || t('sso.verify_failed');
|
if (out) { out.style.color = 'var(--danger,#b91c1c)'; out.textContent = body.error || t('sso.verify_failed'); }
|
||||||
} catch {
|
} catch {
|
||||||
if (out) out.textContent = t('sso.verify_failed');
|
if (out) { out.style.color = 'var(--danger,#b91c1c)'; out.textContent = t('sso.verify_failed'); }
|
||||||
} finally {
|
} finally {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue