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
+17
-1
@@ -20,6 +20,10 @@ import crypto from "node:crypto";
|
||||
import http from "node:http";
|
||||
|
||||
const b64url = (buf) => Buffer.from(buf).toString("base64url");
|
||||
const ONE_PIXEL_PNG = Buffer.from(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
|
||||
"base64"
|
||||
);
|
||||
const json = (res, body, status = 200) => {
|
||||
res.writeHead(status, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify(body));
|
||||
@@ -76,7 +80,12 @@ export async function startFakeIdp({ port = 3011, issuer, clientId, clientSecret
|
||||
|
||||
/* Who the next sign-in is, and what the provider should do wrong this time.
|
||||
Set by the suite through POST /who before each attempt. */
|
||||
let identity = { sub: "subject-1", preferred_username: "someone", name: "Some One" };
|
||||
let identity = {
|
||||
sub: "subject-1",
|
||||
preferred_username: "someone",
|
||||
name: "Some One",
|
||||
picture: `${issuer}/picture.png`,
|
||||
};
|
||||
let misbehave = { wrongKey: false, wrongAudience: false };
|
||||
const codes = new Map(); // code -> { challenge, nonce, identity }
|
||||
|
||||
@@ -113,6 +122,13 @@ export async function startFakeIdp({ port = 3011, issuer, clientId, clientSecret
|
||||
});
|
||||
}
|
||||
|
||||
/* A picture to be somebody's face — one green pixel, blown up by the
|
||||
browser. The point is the journey, not the portrait. */
|
||||
if (url.pathname === "/picture.png") {
|
||||
res.writeHead(200, { "Content-Type": "image/png" });
|
||||
return res.end(ONE_PIXEL_PNG);
|
||||
}
|
||||
|
||||
if (url.pathname === "/jwks") {
|
||||
const jwk = real.publicKey.export({ format: "jwk" });
|
||||
return json(res, { keys: [{ ...jwk, kid, use: "sig", alg: "RS256" }] });
|
||||
|
||||
Reference in new issue
Block a user