2026-10-01 23:15:57 +02:00
<!doctype html>
< html lang = "en" data-theme = "tokyo" data-mode = "dark" >
< head > < meta charset = "utf-8" > < meta name = "viewport" content = "width=device-width,initial-scale=1" > < title > Install Go Loose< / title > < link rel = "stylesheet" href = "/assets/style.css" > < / head >
< body class = "login-page" >
< div class = "login-glow" > < / div >
< main class = "terminal installer" >
< div class = "terminal-bar" > < span > < / span > < span > < / span > < span > < / span > < strong > goloose@installer:~< / strong > < / div >
< div class = "terminal-body" >
< p class = "eyebrow" > FIRST-RUN INSTALLER< / p >
< h1 > Initialize< br > < span > Go Loose.< / span > < / h1 >
feat: account menu, database roles, and single logout
Bundles the console work from the current branch: the header account
control, database-backed roles and permissions, and signing out across
the applications that share this sign-in.
The account control replaces a separate identity chip and a separate
sign-out button, which meant the header carried two controls describing
one fact. web/account.js is mounted into every page by a placeholder and
owns the keyboard handling, the outside-click behaviour and the sign-out
form once. It also fills the trigger's name, which the previous markup
left empty.
Signing out revokes the hosted-login bearer sessions this installation
issued, then redirects to the provider's end_session_endpoint when the
discovery document advertises one. Applications that authenticate
against this installation therefore lose their session too; one pointed
straight at an identity provider is out of its reach and is unchanged.
Roles and permissions become rows rather than a closed enum, so a tenant
can extend the catalog without a migration, and a role can no longer be
granted a capability that is not in it. requireSameOrigin now compares
against the origin the request arrived on instead of the configured base
URL, which defaulted to http://localhost:8080 and so rejected every
write in a deployment that never set it.
Two bugs found while verifying in a browser:
- A profile picture never rendered. avatarURL built an absolute URL
from the configured base URL, and the page's own img-src 'self'
blocked it. The console's own pages now take a root-relative path;
only /connect/userinfo, read from another origin, needs an absolute
one, and it follows the request.
- absoluteURL preferred the configuration over the request while its
comment claimed the opposite, which also misdirected the logout
redirect.
Card layout: the footer was one two-column row shared between a label
and a forty-character identifier, so the identifier took the width and
crushed its label into three stacked words. Each pair is a line now, the
value truncates with the full text in the title, and cards align their
footers across a row.
2026-10-05 19:18:07 +02:00
< p class = "muted" > Configure OIDC identity provider and optionally create the Guess demonstration tenants. The client secret is encrypted before it reaches PostgreSQL.< / p >
2026-10-01 23:15:57 +02:00
< form action = "/install" method = "post" class = "installer-form" >
< input type = "hidden" name = "csrf_token" value = "{{CSRF_TOKEN}}" >
feat: account menu, database roles, and single logout
Bundles the console work from the current branch: the header account
control, database-backed roles and permissions, and signing out across
the applications that share this sign-in.
The account control replaces a separate identity chip and a separate
sign-out button, which meant the header carried two controls describing
one fact. web/account.js is mounted into every page by a placeholder and
owns the keyboard handling, the outside-click behaviour and the sign-out
form once. It also fills the trigger's name, which the previous markup
left empty.
Signing out revokes the hosted-login bearer sessions this installation
issued, then redirects to the provider's end_session_endpoint when the
discovery document advertises one. Applications that authenticate
against this installation therefore lose their session too; one pointed
straight at an identity provider is out of its reach and is unchanged.
Roles and permissions become rows rather than a closed enum, so a tenant
can extend the catalog without a migration, and a role can no longer be
granted a capability that is not in it. requireSameOrigin now compares
against the origin the request arrived on instead of the configured base
URL, which defaulted to http://localhost:8080 and so rejected every
write in a deployment that never set it.
Two bugs found while verifying in a browser:
- A profile picture never rendered. avatarURL built an absolute URL
from the configured base URL, and the page's own img-src 'self'
blocked it. The console's own pages now take a root-relative path;
only /connect/userinfo, read from another origin, needs an absolute
one, and it follows the request.
- absoluteURL preferred the configuration over the request while its
comment claimed the opposite, which also misdirected the logout
redirect.
Card layout: the footer was one two-column row shared between a label
and a forty-character identifier, so the identifier took the width and
crushed its label into three stacked words. Each pair is a line now, the
value truncates with the full text in the title, and cards align their
footers across a row.
2026-10-05 19:18:07 +02:00
< label > OIDC Issuer< input name = "field1" value = "https://accounts.google.com" required placeholder = "https://accounts.google.com" > < / label >
< label > Client ID< input name = "field2" autocomplete = "new-password" required > < / label >
< label > Client Secret< input type = "password" name = "field3" autocomplete = "new-password" required > < / label >
< label > Redirect URL< input name = "field4" value = "{{CALLBACK_URL}}" required > < / label >
2026-10-01 23:15:57 +02:00
< label class = "seed-option" > < input type = "checkbox" name = "seed_demo" checked > < span > Seed NMBS and YPTO Guess demo data< / span > < / label >
< button type = "submit" > INSTALL GO LOOSE< / button >
< / form >
feat: account menu, database roles, and single logout
Bundles the console work from the current branch: the header account
control, database-backed roles and permissions, and signing out across
the applications that share this sign-in.
The account control replaces a separate identity chip and a separate
sign-out button, which meant the header carried two controls describing
one fact. web/account.js is mounted into every page by a placeholder and
owns the keyboard handling, the outside-click behaviour and the sign-out
form once. It also fills the trigger's name, which the previous markup
left empty.
Signing out revokes the hosted-login bearer sessions this installation
issued, then redirects to the provider's end_session_endpoint when the
discovery document advertises one. Applications that authenticate
against this installation therefore lose their session too; one pointed
straight at an identity provider is out of its reach and is unchanged.
Roles and permissions become rows rather than a closed enum, so a tenant
can extend the catalog without a migration, and a role can no longer be
granted a capability that is not in it. requireSameOrigin now compares
against the origin the request arrived on instead of the configured base
URL, which defaulted to http://localhost:8080 and so rejected every
write in a deployment that never set it.
Two bugs found while verifying in a browser:
- A profile picture never rendered. avatarURL built an absolute URL
from the configured base URL, and the page's own img-src 'self'
blocked it. The console's own pages now take a root-relative path;
only /connect/userinfo, read from another origin, needs an absolute
one, and it follows the request.
- absoluteURL preferred the configuration over the request while its
comment claimed the opposite, which also misdirected the logout
redirect.
Card layout: the footer was one two-column row shared between a label
and a forty-character identifier, so the identifier took the width and
crushed its label into three stacked words. Each pair is a line now, the
value truncates with the full text in the title, and cards align their
footers across a row.
2026-10-05 19:18:07 +02:00
< p class = "muted" > In your identity provider console, add the redirect URL above under Authorized redirect URIs. After installation you will continue to the provider, then return to Go Loose with a secure signed session.< / p >
2026-10-01 23:15:57 +02:00
< / div >
< / main >
< script > const t = localStorage . getItem ( 'gl-theme' ) || 'tokyo' , m = localStorage . getItem ( 'gl-mode' ) || 'dark' ; document . documentElement . dataset . theme = t ; document . documentElement . dataset . mode = m < / script >
< / body >
< / html >