Files
govoplan-core/webui/conformance/PasswordLifecycleScenario.tsx

68 lines
5.1 KiB
TypeScript

import { useState } from "react";
import "../src/styles/auth-gate.css";
import { useLocation } from "react-router";
import PasswordChangePanel from "../../../govoplan-access/webui/src/features/passwords/PasswordChangePanel";
import PasswordRecoveryPage from "../../../govoplan-access/webui/src/features/passwords/PasswordRecoveryPage";
import PasswordRecoveryIssueDialog from "../../../govoplan-access/webui/src/features/passwords/PasswordRecoveryIssueDialog";
import PasswordLoginHelp from "../../../govoplan-access/webui/src/features/passwords/PasswordLoginHelp";
import SystemUsersPanel from "../../../govoplan-access/webui/src/features/admin/SystemUsersPanel";
import { passwordTranslations } from "../../../govoplan-access/webui/src/i18n/passwordTranslations";
import { generatedTranslations } from "../../../govoplan-access/webui/src/i18n/generatedTranslations";
import AuthActionGate from "../src/features/auth/AuthActionGate";
import LoginModal from "../src/features/auth/LoginModal";
import Button from "../src/components/Button";
import { PlatformModulesProvider } from "../src/platform/ModuleContext";
import { PlatformLanguageProvider } from "../src/i18n/LanguageContext";
import type { ApiSettings, AuthActionUiCapability, AuthInfo, AuthUpdate, PlatformWebModule } from "../src/types";
const settings: ApiSettings = { apiBaseUrl: "", apiKey: "", accessToken: "" };
const capability: AuthActionUiCapability = {
actions: ["change_password"], RequiredAction: PasswordChangePanel, LoginHelp: PasswordLoginHelp
};
const modules: PlatformWebModule[] = [{
id: "access", label: "Access", version: "fixture", uiCapabilities: { "auth.actions": capability },
helpContexts: [
{ id: "access.password.change", topic_id: "access.help.password-change", title: "Change your local password", documentation_types: ["user", "admin"] },
{ id: "access.password.recover", topic_id: "access.help.password-recovery", title: "Recover a local password", documentation_types: ["user", "admin"] },
{ id: "access.password.issue-recovery", topic_id: "access.help.password-issue-recovery", title: "Issue and hand over a recovery code", documentation_types: ["user", "admin"] }
]
}];
export default function PasswordLifecycleScenario() {
const parameters = new URLSearchParams(useLocation().search);
const mode = parameters.get("mode") ?? "required";
const language = parameters.get("language") ?? "en";
const tenant = { id: "tenant-1", slug: "fixture", name: "Fixture" };
const owner = parameters.get("owner") !== "false";
const [auth, setAuth] = useState<AuthInfo>({
user: { id: "membership-1", account_id: "account-1", email: "person@example.test", local_password: parameters.get("external") !== "true", required_auth_action: mode === "required" || mode === "missing" ? "change_password" : null },
tenant, active_tenant: tenant, scopes: mode === "required" || mode === "missing" ? [] : owner ? ["system:*"] : ["system:accounts:update"], roles: [], groups: [],
principal: { account_id: "account-1", membership_id: "membership-1", auth_method: parameters.get("api-key") ? "api_key" : "session", scopes: [], group_ids: [], session_id: "old-session" },
profile_loaded: true, roles_loaded: true, groups_loaded: true
});
const [updated, setUpdated] = useState("");
const [open, setOpen] = useState(true);
function update(next: AuthUpdate | null, token?: string) {
setUpdated(JSON.stringify({ action: next?.user?.required_auth_action ?? null, token, session: next?.principal?.session_id }));
if (next?.user) setAuth((current) => ({ ...current, ...next, user: { ...current.user, ...next.user }, tenant: current.tenant, active_tenant: current.active_tenant, tenants: current.tenants }));
}
return <PlatformLanguageProvider preferredLanguageCode={language} moduleTranslations={[generatedTranslations, passwordTranslations]}>
<PlatformModulesProvider modules={mode === "missing" ? [] : modules}>
<div data-testid="password-scenario">
{mode === "required" || mode === "missing"
? auth.user.required_auth_action
? <AuthActionGate settings={settings} auth={auth} capability={mode === "missing" ? null : capability} onAuthChange={update} onSignOut={() => setOpen(false)} />
: <h1>Workspace available</h1>
: mode === "recover" ? <PasswordRecoveryPage settings={settings} />
: mode === "issue" ? open
? <PasswordRecoveryIssueDialog settings={settings} account={{ account_id: "target-1", email: "target@example.test" }} onClose={() => setOpen(false)} />
: <Button onClick={() => setOpen(true)}>Reopen recovery</Button>
: mode === "admin" ? <SystemUsersPanel settings={settings} auth={auth} canCreate={false} canUpdate canSuspend={false} canAssignRoles={false} canManageMemberships={false} onAuthRefresh={async () => {}} />
: mode === "login" ? open && <LoginModal settings={settings} onClose={() => setOpen(false)} onLogin={() => {}} />
: <PasswordChangePanel settings={settings} auth={auth} onAuthChange={update} />}
<output data-testid="auth-update">{updated}</output>
</div>
</PlatformModulesProvider>
</PlatformLanguageProvider>;
}