The swarm UI's user menu moves to @hive/shared and takes the whoami URL and authelia's URL as props; the swarm UI keeps a thin wrapper, and the hive dashboard and the per-agent page mount the same component. The dashboard's nginx vhost proxies /api/whoami to authelia (the agent page is served from the same vhost), and hive-c0re's state carries authelia_public_url, set from services.hyperhive.swarm.authelia.url. The agent page shows the menu only behind the gateway.
67 lines
2.4 KiB
JavaScript
67 lines
2.4 KiB
JavaScript
// What the profile menu shows of the signed-in user, shared by the swarm UI,
|
|
// the hive dashboard and the per-agent page. Run by `npm test`.
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import {
|
|
accountLinks,
|
|
initialOf,
|
|
labelOf,
|
|
parseWhoAmI,
|
|
pickAccent,
|
|
} from "../../shared/src/user-menu/identity.ts";
|
|
|
|
test("authelia's user info is read from its {status, data} envelope or bare", () => {
|
|
const data = { display_name: "Mara", emails: ["mara@example.org"] };
|
|
assert.deepEqual(parseWhoAmI({ status: "OK", data }), {
|
|
displayName: "Mara",
|
|
email: "mara@example.org",
|
|
});
|
|
assert.deepEqual(parseWhoAmI(data), {
|
|
displayName: "Mara",
|
|
email: "mara@example.org",
|
|
});
|
|
});
|
|
|
|
test("a shape that is not recognised gives no name instead of an error", () => {
|
|
const none = { displayName: null, email: null };
|
|
assert.deepEqual(parseWhoAmI(null), none);
|
|
assert.deepEqual(parseWhoAmI("nope"), none);
|
|
assert.deepEqual(
|
|
parseWhoAmI({ data: { display_name: 3, emails: "x" } }),
|
|
none,
|
|
);
|
|
assert.deepEqual(parseWhoAmI({ data: { emails: [7] } }), none);
|
|
});
|
|
|
|
test("the label is the display name, else the e-mail, else none", () => {
|
|
assert.equal(labelOf({ displayName: "Mara", email: "m@x" }), "Mara");
|
|
assert.equal(labelOf({ displayName: "", email: "m@x" }), "m@x");
|
|
assert.equal(labelOf({ displayName: null, email: null }), null);
|
|
assert.equal(labelOf(null), null);
|
|
});
|
|
|
|
test("the avatar letter is the label's first, capitalised, or a question mark", () => {
|
|
assert.equal(initialOf(" mara"), "M");
|
|
assert.equal(initialOf(null), "?");
|
|
assert.equal(initialOf(""), "?");
|
|
});
|
|
|
|
test("a name always gets the same colour, one of the theme's", () => {
|
|
assert.equal(pickAccent("Mara"), pickAccent("Mara"));
|
|
assert.match(pickAccent("Mara"), /^var\(--[a-z]+\)$/);
|
|
const seen = new Set(
|
|
["a", "b", "c", "d", "e", "f", "g", "h", "i"].map(pickAccent),
|
|
);
|
|
assert.ok(seen.size > 1, "different names do not all collapse to one colour");
|
|
});
|
|
|
|
test("the account links sit under authelia's URL whether or not it ends in a slash", () => {
|
|
const want = {
|
|
settings: "https://auth.example.org/settings",
|
|
logout: "https://auth.example.org/logout",
|
|
};
|
|
assert.deepEqual(accountLinks("https://auth.example.org/"), want);
|
|
assert.deepEqual(accountLinks("https://auth.example.org"), want);
|
|
assert.equal(accountLinks(null), null);
|
|
assert.equal(accountLinks(""), null);
|
|
});
|