Feat: RBAC, Keys Extension, Invites

feat: org members page — invite users, cancel invites, change roles
feat: show pending invitations banner on profile page
feat: invite accept flow for existing users (no password needed)
feat: departments page updates
feat: SSH keys page — dept cert policy UI (expiry + extensions)
feat: wire up auth pages to real API (register, verify, reset, OIDC)
feat: CLI auth bridge — login page handles CLI token flow
feat: admin users — suspend/unsuspend, role badges, role filter
feat: add admin OAuth providers management page
feat: activity page — org-wide audit log view for admins
feat: add my memberships page
chore: add isOrgAdmin/isOrgMember to AuthContext, restrict sidebar
chore: update app routing and shared layout
This commit is contained in:
2026-03-01 16:50:19 +05:45
parent 62f767474b
commit 4c01fd0107
22 changed files with 2457 additions and 496 deletions
+16 -13
View File
@@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { BannerAlert } from "@/components/auth/BannerAlert";
import { api, ApiError } from "@/lib/api";
type VerificationState = "verifying" | "success" | "error" | "resend";
@@ -22,21 +23,20 @@ export default function VerifyEmailPage() {
if (token && state === "verifying") {
verifyToken(token);
}
}, [token, state]);
}, [token]);
const verifyToken = async (verificationToken: string) => {
// Mock verification - POST /api/auth/verify-email?token=...
setTimeout(() => {
// Simulate different responses
const mockSuccess = Math.random() > 0.3; // 70% success rate for demo
if (mockSuccess) {
setState("success");
try {
await api.auth.verifyEmail(verificationToken);
setState("success");
} catch (err) {
setState("error");
if (err instanceof ApiError) {
setErrorMessage(err.message || "This verification link has expired or is invalid.");
} else {
setState("error");
setErrorMessage("This verification link has expired or is invalid.");
}
}, 1500);
}
};
const handleResendVerification = async (e: React.FormEvent) => {
@@ -44,11 +44,14 @@ export default function VerifyEmailPage() {
setIsResending(true);
setResendSuccess(false);
// Mock resend - POST /api/auth/request-email-verification
setTimeout(() => {
try {
await api.auth.resendVerification(resendEmail);
} catch {
// Always show success to avoid leaking account existence
} finally {
setIsResending(false);
setResendSuccess(true);
}, 1000);
}
};
// Loading / Verifying state