Add session-bound personal profile editing
verify / verify (push) Successful in 4m35s

This commit is contained in:
2026-09-05 02:37:38 -04:00
parent 7c68a3499a
commit a16283efd7
12 changed files with 499 additions and 8 deletions
+23
View File
@@ -21,3 +21,26 @@ template. Its private evidence, persistent bans, account data, route policy,
operator exclusions, synchronization, and publishing workflow remain
application-owned. Useful pressure from that migration may improve a general
interface, but it may not smuggle EQL-specific policy into this module.
## Optional personal-profile editing
`auth.OwnProfileRepository` supports a narrow self-service boundary independently
of instance-directory authorization. Load the profile using the current session
digest; derive the target from that result. Normalize one username or display
name using `auth.NormalizeProfileValue`. Never decode an HTTP body directly into
`auth.ProfileEdit`, which carries trusted identity and credential-check state.
Require CSRF/origin validation for browser writes and rate-limit credential work.
For username changes, verify the current password (supply its hash as
`ExpectedPasswordHash`) or consume an exact operation-bound passkey approval;
enforce any additional authentication policy your application requires. Include
the session, user, value and expected profile revision in the passkey binding.
The SQLite transaction rechecks session/account/revision and any verified hash,
updates one field, revokes other sessions for username edits, and appends audit.
Do not log the command or include secret material in its audit.
Schema 11 adds `profile_revision` without changing stable identity keys. Run an
explicit migration before starting an adopter with automatic migration disabled.
Keep the pre-migration backup; adjacent older binaries are not approved writers
for the migrated schema. Email-change enrollment/confirmation is not implemented
by this interface and must not be simulated with an unverified direct update.
+14 -2
View File
@@ -8,6 +8,18 @@ application concern belongs in the shared module.
## Gamertan accounts and commerce
- Personal identity editing is not instance administration. `OwnProfileRepository`
derives self-access from the active session; `ProfileEdit` is a trusted internal
command, never a browser request model. SQLite schema 11 adds a monotonic
revision because timestamps alone cannot distinguish two edits in one second.
Session/account/revision checks, mutation and audit share one write transaction.
Username edits invalidate other sessions without changing immutable IDs,
memberships, credentials, orders or provider billing identities. A password
proof binds the verified hash into that transaction; passkey proofs must bind
the exact user/session/field/value/revision before calling it. The application
chooses account-specific reauthentication and owns its credential-work limits.
Email requires a separate verified change protocol, not another accepted field.
- Instance operators need all-user/all-organization directories, not a staff
roster or implicit membership in every business. Optional bounded readers now
expose identity/profile records without credentials, independent of membership.
@@ -47,8 +59,8 @@ application concern belongs in the shared module.
policy; there is no new database schema or commerce dependency in Foundations.
- The account email remains required and unique. Gamertan uses normalized
email as the canonical login identifier and keeps username as a stable public
identity. Until a mail package exists, the application must not describe an
email as the canonical login identifier; the immutable user ID, not the editable
username, owns account relationships. Until a mail package exists, it must not describe an
address as verified merely because it was entered during registration.
- Password authentication is sufficient for an ordinary customer base
session. Privileged application actions use an exact operation binding with
+1 -1
View File
@@ -26,7 +26,7 @@ The packages are ordinary Go imports. Pin the current preview and verify its
module checksum:
```bash
go get gamertan.com/web/requestmeta@v0.1.0-preview.25
go get gamertan.com/web/requestmeta@v0.1.0-preview.26
go mod verify
```