The face from the provider, and whose business a password is
The password tab was hidden for accounts with no password, which is not the same as accounts that sign in through the provider — an account linked to one kept its password and therefore kept the tab. That is precisely the account the person setting this up is using. It goes by "signs in over there" now; the password it kept is the emergency door, set by an administrator. And the picture. The provider sends one, the server fetches it at each sign-in and stores it encrypted in a table beside the users rather than in them, and serves it back through the API — so the page never talks to the provider, no third-party cookie is needed for a face to appear, and it survives the provider being down like everything else here. Fetched once per account into an object URL, since an img tag cannot carry a bearer token. The suite's provider now serves a picture too, and the check asks the browser whether it actually decoded rather than whether the element exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
40bdf81aa2
commit
a2b3f91e00
12 files changed
+325
-22
No files matched your search
@@ -310,11 +310,29 @@ administrator — PocketID, Authentik, Keycloak as they are normally run — tha
|
||||
exactly the intent. Do not point this at one where people choose their own name
|
||||
freely.
|
||||
|
||||
**Both doors stay open.** An account created by the provider has no password here
|
||||
at all: the interface stops offering to change one, and the login route refuses
|
||||
it exactly as it refuses a wrong password, at the same speed. An administrator
|
||||
can still *set* one for such an account, and that is deliberate — it is the way
|
||||
back in on the day the provider is unreachable.
|
||||
**Both doors stay open, and passwords become an administrator's business.** An
|
||||
account created by the provider has no password here at all: the login route
|
||||
refuses one exactly as it refuses a wrong password, at the same speed. An
|
||||
administrator can still *set* one — deliberately, since that is the way back in
|
||||
on the day the provider is unreachable — and the button in the list says "Give a
|
||||
password" rather than offering to reset something that does not exist.
|
||||
|
||||
An account that signs in through the provider is offered no password tab of its
|
||||
own, and that includes one which had a password before it was linked. The
|
||||
password it kept is the emergency door, not a second thing for its owner to
|
||||
maintain; the account panel says so, and names the provider it signs in through.
|
||||
The administration list marks every linked account, and says which of them have
|
||||
no password here.
|
||||
|
||||
**The picture comes along.** If the provider sends a `picture` claim — PocketID
|
||||
does — the server fetches it at each sign-in and stores it, encrypted, in a table
|
||||
of its own. It is served back through the API, so nothing on the page talks to
|
||||
the provider, no third-party cookie is needed for it to appear, and it keeps
|
||||
working when the provider does not. The bytes are fetched once per account and
|
||||
turned into an object URL, since an `<img src>` cannot carry a bearer token; the
|
||||
picture then shows in the sidebar, in the account panel and beside the name in
|
||||
the administration list. It arrives with the *next* sign-in: that is the one
|
||||
moment this app talks to the provider at all.
|
||||
|
||||
**The refresh token is deliberately unused.** The provider is asked once, at
|
||||
sign-in; InkNote's own token carries the session from then on, and nothing here
|
||||
@@ -566,7 +584,7 @@ docker compose -f docker-compose.dev.yml up -d --build # must be running
|
||||
| Suite | Checks | What it holds down |
|
||||
| --- | --- | --- |
|
||||
| `admin` | 15 | no sign-up anywhere; `/api/admin/*` refused for non-admins even when called directly |
|
||||
| `oidc` | 26 | the whole redirect journey against a provider that signs real tokens — and the four ways it must fail: a refusal, a replayed ticket, a token signed with an unpublished key, a token addressed to another client |
|
||||
| `oidc` | 39 | the whole redirect journey against a provider that signs real tokens — and the four ways it must fail: a refusal, a replayed ticket, a token signed with an unpublished key, a token addressed to another client |
|
||||
| `editor` | 40 | tables and their right-click menu, task lists, note links, backlinks — and that each survives a reload |
|
||||
| `search-attachments` | 12 | body-only matches, ranking, umlauts; images as blob URLs, not inline bytes |
|
||||
| `history` | 10 | a large deletion is snapshotted, restoring works, restoring is itself undoable |
|
||||
|
||||
Reference in new issue
Block a user