fix(core): preserve data integrity and bound shared UI and response work
Module Package Release / publish-packages (push) Successful in 13s
Module Package Release / publish-packages (push) Successful in 13s
Release v0.1.46. Coordinated integrity review: GovOPlaN/govoplan-core#298.
This commit is contained in:
@@ -44,3 +44,60 @@ test("lightweight session changes trigger full auth refresh for required actions
|
||||
assert.equal(sessionMatchesAuth({ ...session, user: { ...session.user, local_password: false } }, auth), false);
|
||||
assert.equal(sessionMatchesAuth({ ...session, session_id: "rotated-session" }, auth), false);
|
||||
});
|
||||
|
||||
const authorityContext = vm.createContext({ module: { exports: {} } });
|
||||
authorityContext.exports = authorityContext.module.exports;
|
||||
vm.runInContext(transformSync(readFileSync(new URL("../src/api/authAuthority.ts", import.meta.url), "utf8"), { loader: "ts", format: "cjs" }).code, authorityContext);
|
||||
const { authAuthorityKey } = authorityContext.module.exports;
|
||||
const settings = { apiBaseUrl: "https://fixture.invalid", apiKey: "fixture-key", accessToken: "fixture-token" };
|
||||
|
||||
test("authority fences ignore fresh object identity and cosmetic profile changes", () => {
|
||||
const auth = normalizeAuthInfo(base);
|
||||
const key = authAuthorityKey(auth, settings);
|
||||
const refreshed = structuredClone(auth);
|
||||
refreshed.user.display_name = "Changed display name";
|
||||
refreshed.user.preferred_language = "de";
|
||||
refreshed.user.ui_preferences = { compact_tables: true };
|
||||
refreshed.tenant.name = "Changed tenant name";
|
||||
refreshed.profile_loaded = true;
|
||||
assert.equal(authAuthorityKey(refreshed, { ...settings }), key);
|
||||
});
|
||||
|
||||
test("authority fences include principal, tenant, credential, scope, acting and required-action changes", () => {
|
||||
const auth = normalizeAuthInfo(base);
|
||||
const key = authAuthorityKey(auth, settings);
|
||||
for (const mutate of [
|
||||
(value) => { value.user.account_id = "different-account"; },
|
||||
(value) => { value.user.email = "different@example.test"; },
|
||||
(value) => { value.user.is_tenant_admin = true; },
|
||||
(value) => { value.user.required_auth_action = "change_password"; },
|
||||
(value) => { value.user.local_password = !value.user.local_password; },
|
||||
(value) => { value.tenant.id = "different-tenant"; },
|
||||
(value) => { value.active_tenant = { ...value.tenant, id: "active-tenant" }; },
|
||||
(value) => { value.tenant.is_active = false; },
|
||||
(value) => { value.scopes = ["new:permission"]; },
|
||||
(value) => { value.roles = [{ id: "role", slug: "role", permissions: ["new:permission"] }]; },
|
||||
(value) => { value.groups = [{ id: "group" }]; },
|
||||
(value) => { value.principal.session_id = "rotated-session"; },
|
||||
(value) => { value.principal.acting_assignment_id = "assignment"; },
|
||||
(value) => { value.principal.acting_for_account_id = "actor"; },
|
||||
(value) => { value.principal.delegation_ids = ["delegation"]; }
|
||||
]) {
|
||||
const changed = structuredClone(auth);
|
||||
mutate(changed);
|
||||
assert.notEqual(authAuthorityKey(changed, settings), key);
|
||||
}
|
||||
for (const field of ["apiBaseUrl", "apiKey", "accessToken"]) {
|
||||
assert.notEqual(authAuthorityKey(auth, { ...settings, [field]: "changed" }), key);
|
||||
}
|
||||
});
|
||||
|
||||
test("authority set ordering and duplicate entries do not invent a context change", () => {
|
||||
const auth = normalizeAuthInfo(base);
|
||||
auth.scopes = ["b", "a", "b"];
|
||||
auth.principal.group_ids = ["g2", "g1"];
|
||||
const reordered = structuredClone(auth);
|
||||
reordered.scopes = ["a", "b"];
|
||||
reordered.principal.group_ids = ["g1", "g2", "g1"];
|
||||
assert.equal(authAuthorityKey(auth, settings), authAuthorityKey(reordered, settings));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user