2026-10-01 23:15:57 +02:00
|
|
|
SHELL := /bin/sh
|
|
|
|
|
|
|
|
|
|
GO_LOOSE_ADDR ?= :8081
|
2026-10-04 16:57:30 +02:00
|
|
|
GO_LOOSE_PORT ?= 8081
|
2026-10-01 23:15:57 +02:00
|
|
|
GO_LOOSE_BASE_URL ?= http://localhost:$(GO_LOOSE_PORT)
|
|
|
|
|
GO_LOOSE_DATABASE_URL ?= postgres://goloose:goloose@localhost:5433/goloose?sslmode=disable
|
|
|
|
|
GO_LOOSE_SESSION_SECRET ?= local-development-secret-change-me-now
|
|
|
|
|
GO_LOOSE_DEV_LOGIN ?= true
|
|
|
|
|
GO_LOOSE_DEV_USER ?= admin@local.test
|
|
|
|
|
GO_LOOSE_BOOTSTRAP_TENANT ?= nmbs
|
|
|
|
|
GO_LOOSE_BOOTSTRAP_APP ?= guess
|
|
|
|
|
GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS ?= true
|
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
|
|
|
GO_LOOSE_DEV_PORT ?= 8080
|
2026-10-01 23:15:57 +02:00
|
|
|
|
|
|
|
|
export
|
|
|
|
|
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
.PHONY: build test integration-db integration-test behaviour-test run compose-up compose-down compose-dev-up compose-dev-down compose-dev-logs fmt vet
|
2026-10-01 23:15:57 +02:00
|
|
|
|
|
|
|
|
build:
|
|
|
|
|
go build ./...
|
|
|
|
|
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
# The database-backed suites drop every table they touch, so `test` runs without
|
|
|
|
|
# them. Each suite skips itself when its variable is empty, which keeps a
|
|
|
|
|
# developer without PostgreSQL from being blocked; `integration-test` sets them.
|
2026-10-01 23:15:57 +02:00
|
|
|
test:
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
GO_LOOSE_TEST_DATABASE_URL= GO_LOOSE_TEST_SERVER_DATABASE_URL= go test -race ./...
|
2026-10-01 23:15:57 +02:00
|
|
|
|
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
|
|
|
# Integration tests drop every table they touch, so they only run against scratch
|
|
|
|
|
# databases. Both test helpers refuse any database whose name lacks "test", and
|
|
|
|
|
# `make integration-db` creates the two they expect. Override the check with
|
|
|
|
|
# GO_LOOSE_TEST_DATABASE_DESTRUCTIVE=1 only when you mean it.
|
|
|
|
|
#
|
|
|
|
|
# The store-backed tests in internal/server need a database of their own: Go runs
|
|
|
|
|
# package tests in parallel and both packages drop every table, so sharing one
|
|
|
|
|
# database makes them fight over the schema.
|
|
|
|
|
GO_LOOSE_TEST_DATABASE_URL ?= postgres://goloose:goloose@localhost:5433/goloose_test?sslmode=disable
|
|
|
|
|
GO_LOOSE_TEST_SERVER_DATABASE_URL ?= postgres://goloose:goloose@localhost:5433/goloose_server_test?sslmode=disable
|
|
|
|
|
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
# The behaviour suite drives the whole application over HTTP and needs the Google
|
|
|
|
|
# client credentials for the installer. It reads ../google_secrets.json, or the
|
|
|
|
|
# variables below, and skips when neither is present.
|
|
|
|
|
GO_LOOSE_BEHAVIOUR_DATABASE_URL ?= postgres://goloose:goloose@localhost:5433/goloose_behaviour_test?sslmode=disable
|
|
|
|
|
|
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
|
|
|
# createdb is not idempotent, so ignore a database that is already there.
|
|
|
|
|
integration-db:
|
|
|
|
|
-docker compose exec -T postgres createdb -U goloose goloose_test
|
|
|
|
|
-docker compose exec -T postgres createdb -U goloose goloose_server_test
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
-docker compose exec -T postgres createdb -U goloose goloose_behaviour_test
|
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
|
|
|
|
2026-10-04 12:24:13 +02:00
|
|
|
integration-test:
|
|
|
|
|
@test -n "$(GO_LOOSE_TEST_DATABASE_URL)" || { echo "set GO_LOOSE_TEST_DATABASE_URL to a scratch database"; exit 1; }
|
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
|
|
|
go test -race ./internal/store/ ./internal/server/ -count=1
|
2026-10-04 12:24:13 +02:00
|
|
|
|
test: drive the whole application over HTTP, and serialise migrations
The behaviour suite in internal/behaviour installs the application into an
empty database through the web installer, signs in, walks every flow, and then
replaces the process to confirm the state was persisted rather than held in
memory. It found four defects, each fixed here or in the preceding commit:
- Migrate was not safe to run from two instances at once. CREATE TABLE IF NOT
EXISTS is not race free in PostgreSQL and collided on the pg_type unique
index, and two replicas could apply the same file. The run now holds a
session-level advisory lock, so a rolling deployment waits instead of failing.
- Bootstrap refused ownership whenever a tenant held any member, so installing
with the demonstration seed and then setting a local administrator password
produced an account that could never reach the console. It now grants
ownership only while the tenant has no owner, which still never takes a tenant
over from one that does.
Three of the fixes are covered by store-level regression tests in the same
commit: the ownership rule, the duplicate tenant slug conflict, and concurrent
migration runs.
The suite is skipped by go test ./... because it needs a scratch database and
the Google credentials for the installer. Run it with make behaviour-test, which
also resets the database afterwards. make test no longer inherits the database
variables, so unit runs need nothing.
Completes the earlier correction to the docs: the role matrix lives in the
database rather than in internal/role, and a local administrator claims the
system administrator role when no Google account has.
2026-10-05 19:37:09 +02:00
|
|
|
# Installs the application into an empty database, walks every flow, restarts the
|
|
|
|
|
# process, and checks that everything is still there. Leaves the database empty
|
|
|
|
|
# again so the next run starts from nothing.
|
|
|
|
|
behaviour-test:
|
|
|
|
|
GO_LOOSE_BEHAVIOUR=1 go test ./internal/behaviour/ -count=1 -v
|
|
|
|
|
-docker compose exec -T postgres psql -q -U goloose -d goloose_behaviour_test \
|
|
|
|
|
-c 'DROP SCHEMA public CASCADE; CREATE SCHEMA public;' >/dev/null
|
|
|
|
|
|
2026-10-01 23:15:57 +02:00
|
|
|
run:
|
|
|
|
|
go run ./cmd/go-loose
|
|
|
|
|
|
2026-10-04 16:57:30 +02:00
|
|
|
# The variables above are exported for `make run`, but compose reads
|
|
|
|
|
# GO_LOOSE_BASE_URL too and would inherit the local http://localhost:8081 value,
|
|
|
|
|
# which then overrides the https:// defaults in docker-compose.yaml. Clearing it
|
|
|
|
|
# for the compose targets lets compose apply its own defaults.
|
2026-10-01 23:15:57 +02:00
|
|
|
compose-up:
|
2026-10-04 16:57:30 +02:00
|
|
|
GO_LOOSE_BASE_URL= docker compose up --build
|
2026-10-01 23:15:57 +02:00
|
|
|
|
|
|
|
|
compose-down:
|
|
|
|
|
docker compose down
|
|
|
|
|
|
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
|
|
|
# Air rebuilds into ./dist on every change.
|
|
|
|
|
compose-dev-up:
|
|
|
|
|
mkdir -p dist
|
|
|
|
|
docker compose -f docker-compose.dev.yaml up --build
|
|
|
|
|
|
|
|
|
|
compose-dev-down:
|
|
|
|
|
docker compose -f docker-compose.dev.yaml down --remove-orphans
|
|
|
|
|
# Air writes dist/go-loose as root inside the container, so the host user
|
|
|
|
|
# cannot delete it directly. Empty the directory through a container instead.
|
|
|
|
|
-docker run --rm -v "$(CURDIR)/dist:/dist" alpine sh -c 'rm -rf /dist/*' 2>/dev/null || true
|
|
|
|
|
|
|
|
|
|
compose-dev-logs:
|
|
|
|
|
docker compose -f docker-compose.dev.yaml logs -f go-loose
|
|
|
|
|
|
2026-10-01 23:15:57 +02:00
|
|
|
fmt:
|
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
|
|
|
# Prune directories that are not source and may be unreadable: vendored
|
|
|
|
|
# code, build output, the PostgreSQL volume, and anything hidden or
|
|
|
|
|
# underscore prefixed, which is how Go itself skips package trees.
|
|
|
|
|
gofmt -w $$(find . -mindepth 1 -type d \( -name vendor -o -name dist -o -name '.*' -o -name '_*' \) -prune -o -name '*.go' -print)
|
2026-10-01 23:15:57 +02:00
|
|
|
|
|
|
|
|
vet:
|
|
|
|
|
go vet ./...
|