allow admins to delete approvals and activity entries
This commit is contained in:
@@ -1137,6 +1137,80 @@ test("approvals list exposes account status and supports repeated decisions", as
|
||||
}
|
||||
});
|
||||
|
||||
test("admin can delete individual approval and activity entries", async (t) => {
|
||||
const rootDir = path.resolve(__dirname, "..");
|
||||
const dataDir = await fs.mkdtemp(path.join(os.tmpdir(), "rms-delete-entries-test-"));
|
||||
const port = randomPort();
|
||||
const baseUrl = `http://127.0.0.1:${port}`;
|
||||
|
||||
const server = spawn(process.execPath, ["server/index.js"], {
|
||||
cwd: rootDir,
|
||||
env: {
|
||||
...process.env,
|
||||
PORT: String(port),
|
||||
DATA_DIR: dataDir,
|
||||
ADMIN_EMAILS: "admin@arcg.at",
|
||||
PRIMARY_EMAIL_DOMAIN: "arcg.at",
|
||||
PUBLIC_BASE_URL: baseUrl
|
||||
},
|
||||
stdio: ["ignore", "pipe", "pipe"]
|
||||
});
|
||||
|
||||
let serverStdErr = "";
|
||||
server.stderr.on("data", (chunk) => {
|
||||
serverStdErr += String(chunk);
|
||||
});
|
||||
|
||||
t.after(async () => {
|
||||
if (!server.killed) {
|
||||
server.kill("SIGTERM");
|
||||
}
|
||||
await fs.rm(dataDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
await waitForServer(baseUrl);
|
||||
|
||||
const adminVerify = await requestAccessAndVerify(baseUrl, dataDir, "admin@arcg.at");
|
||||
const adminHeaders = { Authorization: `Bearer ${adminVerify.accessToken}` };
|
||||
|
||||
const externalEmail = "deleteme@oevsv.at";
|
||||
const verify = await requestAccessAndVerify(baseUrl, dataDir, externalEmail);
|
||||
assert.equal(verify.approved, false);
|
||||
|
||||
const approvalsBefore = await requestJson(baseUrl, "/v1/approvals", { headers: adminHeaders });
|
||||
const pending = (approvalsBefore.approvals || []).find((entry) => entry.email === externalEmail);
|
||||
assert.ok(pending, "approval entry should exist before delete");
|
||||
|
||||
const deleteApproval = await requestJson(baseUrl, `/v1/approvals/${encodeURIComponent(pending.id)}`, {
|
||||
method: "DELETE",
|
||||
headers: adminHeaders
|
||||
});
|
||||
assert.equal(deleteApproval.ok, true);
|
||||
assert.equal(deleteApproval.deletedId, pending.id);
|
||||
|
||||
const approvalsAfter = await requestJson(baseUrl, "/v1/approvals", { headers: adminHeaders });
|
||||
assert.equal((approvalsAfter.approvals || []).some((entry) => entry.id === pending.id), false);
|
||||
|
||||
const activityBefore = await requestJson(baseUrl, "/v1/activity-log?limit=300", { headers: adminHeaders });
|
||||
assert.ok(Array.isArray(activityBefore.entries));
|
||||
const targetActivity = activityBefore.entries.find((entry) => entry && entry.id && entry.action === "auth.request_access");
|
||||
assert.ok(targetActivity, "activity entry with id should exist before delete");
|
||||
|
||||
const deleteActivity = await requestJson(baseUrl, `/v1/activity-log/${encodeURIComponent(targetActivity.id)}`, {
|
||||
method: "DELETE",
|
||||
headers: adminHeaders
|
||||
});
|
||||
assert.equal(deleteActivity.ok, true);
|
||||
assert.equal(deleteActivity.deletedId, targetActivity.id);
|
||||
|
||||
const activityAfter = await requestJson(baseUrl, "/v1/activity-log?limit=300", { headers: adminHeaders });
|
||||
assert.equal((activityAfter.entries || []).some((entry) => entry.id === targetActivity.id), false);
|
||||
|
||||
if (server.exitCode !== null && server.exitCode !== 0) {
|
||||
throw new Error(`Server exited unexpectedly: ${server.exitCode}\n${serverStdErr}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("station usage is auto-ended after configured max usage time", async (t) => {
|
||||
const rootDir = path.resolve(__dirname, "..");
|
||||
const dataDir = await fs.mkdtemp(path.join(os.tmpdir(), "rms-station-timeout-test-"));
|
||||
|
||||
Reference in New Issue
Block a user