Add stale invite expiry action
All checks were successful
Template Compliance / compliance (push) Successful in 5s
All checks were successful
Template Compliance / compliance (push) Successful in 5s
This commit is contained in:
@@ -12,7 +12,7 @@ import { requireInitialSetup } from "@/lib/setup";
|
|||||||
import { DataTable, EmptyState, MetricTile, PageHeader, Panel, StatusDot, Tabs } from "@/components/ui";
|
import { DataTable, EmptyState, MetricTile, PageHeader, Panel, StatusDot, Tabs } from "@/components/ui";
|
||||||
import { getAppSettings, type AppSettings } from "@/lib/settings";
|
import { getAppSettings, type AppSettings } from "@/lib/settings";
|
||||||
import { updateInstanceSettings, updateSecuritySettings } from "@/lib/settings-actions";
|
import { updateInstanceSettings, updateSecuritySettings } from "@/lib/settings-actions";
|
||||||
import { banUser, createInstanceInvite, disableUser, enableUser, grantAdminRole, removeUserFriendships, revokeAdminRole, revokeInvite } from "@/lib/admin-actions";
|
import { banUser, createInstanceInvite, disableUser, enableUser, expireStaleInvites, grantAdminRole, removeUserFriendships, revokeAdminRole, revokeInvite } from "@/lib/admin-actions";
|
||||||
import { deleteRoom } from "@/lib/room-actions";
|
import { deleteRoom } from "@/lib/room-actions";
|
||||||
import { isInviteExpired } from "@/lib/invites";
|
import { isInviteExpired } from "@/lib/invites";
|
||||||
|
|
||||||
@@ -340,6 +340,8 @@ function InvitesPanel({
|
|||||||
}>;
|
}>;
|
||||||
rooms: Array<{ id: string; name: string; slug: string }>;
|
rooms: Array<{ id: string; name: string; slug: string }>;
|
||||||
}) {
|
}) {
|
||||||
|
const expiredInviteCount = invites.filter((invite) => invite.status === "ACTIVE" && isInviteExpired(invite.expiresAt)).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="split-grid">
|
<div className="split-grid">
|
||||||
<Panel title="Create Invite" eyebrow="Access">
|
<Panel title="Create Invite" eyebrow="Access">
|
||||||
@@ -361,6 +363,11 @@ function InvitesPanel({
|
|||||||
</form>
|
</form>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Panel title="Invites" eyebrow={`${invites.length} recent`}>
|
<Panel title="Invites" eyebrow={`${invites.length} recent`}>
|
||||||
|
{expiredInviteCount > 0 ? (
|
||||||
|
<form action={expireStaleInvites} className="inline-form">
|
||||||
|
<button className="button compact-button" type="submit">Mark {expiredInviteCount} expired</button>
|
||||||
|
</form>
|
||||||
|
) : null}
|
||||||
{invites.length === 0 ? (
|
{invites.length === 0 ? (
|
||||||
<EmptyState title="No invites yet" description="Create an invite to allow registration or room access workflows." />
|
<EmptyState title="No invites yet" description="Create an invite to allow registration or room access workflows." />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -125,6 +125,19 @@ export async function revokeInvite(formData: FormData) {
|
|||||||
revalidateAdmin();
|
revalidateAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function expireStaleInvites() {
|
||||||
|
const admin = await requireAdmin();
|
||||||
|
const result = await prisma.invite.updateMany({
|
||||||
|
where: {
|
||||||
|
status: "ACTIVE",
|
||||||
|
expiresAt: { lt: new Date() }
|
||||||
|
},
|
||||||
|
data: { status: "EXPIRED" }
|
||||||
|
});
|
||||||
|
await audit(admin.id, "admin.invites.expire", { expiredInvites: result.count });
|
||||||
|
revalidateAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
async function audit(actorId: string, action: string, metadata: Prisma.InputJsonObject) {
|
async function audit(actorId: string, action: string, metadata: Prisma.InputJsonObject) {
|
||||||
await prisma.auditEvent.create({ data: { actorId, action, metadata } });
|
await prisma.auditEvent.create({ data: { actorId, action, metadata } });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user