Style the NetKingdom sign-out confirmation like the account site.
Assistant: grok Assistant-Session: 01a0d25d-d358-7e13-b84a-d007fbb7e34f
This commit is contained in:
parent
36f9677bd1
commit
13afaa916d
2 changed files with 23 additions and 4 deletions
|
|
@ -37,13 +37,25 @@ type AccountLogoutHandler struct {
|
|||
const logoutCSRF = "__Host-keycape-logout"
|
||||
|
||||
var accountLogoutPage = template.Must(template.New("logout").Parse(`<!doctype html>
|
||||
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Sign out of NetKingdom</title><main><h1>Sign out of NetKingdom?</h1>
|
||||
<html lang="en"><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Sign out of NetKingdom · NetKingdom Identity</title><style>
|
||||
:root{--ink:#17201c;--paper:#f5f1e8;--accent:#195b47;--line:#c8c1b3}
|
||||
*{box-sizing:border-box}body{margin:0;background:var(--paper);color:var(--ink);font:18px/1.55 system-ui,sans-serif}
|
||||
header,main{max-width:68rem;margin:auto;padding:1.25rem}header{border-bottom:1px solid var(--line)}
|
||||
h1{font:clamp(2.2rem,7vw,5.5rem)/.98 Georgia,serif;max-width:13ch}a{color:var(--accent)}
|
||||
form{display:grid;gap:.8rem;max-width:42rem}
|
||||
input,button{font:inherit;padding:.65rem}button{background:var(--accent);color:white;border:0;border-radius:.3rem;cursor:pointer}
|
||||
a:focus-visible,button:focus-visible{outline:3px solid #e59f24;outline-offset:3px}
|
||||
@media(max-width:640px){body{font-size:16px}}
|
||||
</style></head><body><header><strong>NetKingdom Identity</strong></header><main>
|
||||
<h1>Sign out of NetKingdom?</h1>
|
||||
<p>This ends your shared sign-in session in this browser so you can use another account.
|
||||
Applications that already have their own sessions may remain signed in.</p>
|
||||
<form method="post" action="/account/logout"><input type="hidden" name="csrf" value="{{.CSRF}}">
|
||||
<button type="submit">Sign out of NetKingdom</button></form>
|
||||
<p><a href="{{.Portal}}">Back to my account</a></p></main></html>`))
|
||||
<p><a href="{{.Portal}}">Back to my account</a></p>
|
||||
</main></body></html>`))
|
||||
|
||||
func (h *AccountLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
|
|
@ -53,7 +65,7 @@ func (h *AccountLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
|||
upstream, _ := url.Parse(h.UpstreamLogoutURL)
|
||||
portal, _ := url.Parse(h.PortalURL)
|
||||
destinations := upstream.Scheme + "://" + upstream.Host + " " + portal.Scheme + "://" + portal.Host
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'none'; form-action 'self' "+destinations+"; frame-ancestors 'none'; base-uri 'none'")
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; form-action 'self' "+destinations+"; frame-ancestors 'none'; base-uri 'none'")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ func TestSharedLogoutRequiresConfirmationAndFixedReturn(t *testing.T) {
|
|||
if w.Code != 200 || w.Header().Get("Location") != "" {
|
||||
t.Fatal("GET must only confirm")
|
||||
}
|
||||
page := w.Body.String()
|
||||
if !strings.Contains(page, "<strong>NetKingdom Identity</strong>") || !strings.Contains(page, "<h1>Sign out of NetKingdom?</h1>") || !strings.Contains(page, "--paper:#f5f1e8") || !strings.Contains(page, "Georgia,serif") {
|
||||
t.Fatal("logout page left the account-site design")
|
||||
}
|
||||
if !strings.Contains(w.Header().Get("Content-Security-Policy"), "style-src 'unsafe-inline'") {
|
||||
t.Fatal("inline account-site style blocked")
|
||||
}
|
||||
if w.Header().Get("Referrer-Policy") != "same-origin" {
|
||||
t.Fatal("browser POST would lose its Origin")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue