feat(auth): add generic OIDC login with mandatory groups

This commit is contained in:
2026-08-17 05:44:10 +02:00
parent 202822f3ba
commit 4fe51cbeb1
20 changed files with 1144 additions and 40 deletions
@@ -92,3 +92,37 @@ test("a delayed gate response from user A cannot clear user B's pending gate", a
expect(useSessionStore.getState().pendingWidget?.id).toBe("gate-b");
expect(useSessionStore.getState().lastUserEntry).toBeNull();
});
test("a held s1 gate response cannot clear the pending s2 gate", async () => {
let release!: () => void;
let started!: () => void;
let settled!: () => void;
const held = new Promise<void>((resolve) => { release = resolve; });
const requestStarted = new Promise<void>((resolve) => { started = resolve; });
const requestSettled = new Promise<void>((resolve) => { settled = resolve; });
server.use(http.post("/api/sessions/s1/response", async () => {
started();
try {
await held;
return new HttpResponse(null, { status: 204 });
} finally {
settled();
}
}));
useSessionStore.setState({
pendingWidget: { id: "gate-s1", widget: "select", options: [{ id: "s1", label: "Answer s1" }] },
});
const view = render(<WidgetHost sessionId="s1" />);
await userEvent.click(screen.getByRole("button", { name: "Answer s1" }));
await requestStarted;
view.rerender(<WidgetHost sessionId="s2" />);
act(() => useSessionStore.setState({
pendingWidget: { id: "gate-s2", widget: "select", options: [{ id: "s2", label: "Answer s2" }] },
}));
release();
await act(async () => { await requestSettled; });
expect(useSessionStore.getState().pendingWidget?.id).toBe("gate-s2");
expect(useSessionStore.getState().lastUserEntry).toBeNull();
});