feat(admin): live redis kill-switch on tunnel actions, sortable columns + CSV export + bulk actions, Node 24 LTS
WS1: pin all Docker stages to node:24.16.0-alpine; add engines node>=20. WS2: lib/redis.ts gains TTL-backed redisSet, redisDel, setTunnelActive (writes tunnel:active:<sub>=1/0 EX 30, TUNNEL_ACTIVE_TTL override, no-op without REDIS_URL); wired into tunnel active/delete/reassign routes. WS3: sortable columns, CSV export routes (token excluded), and bulk actions (self-account guard) across users/tunnels/audit admin tables.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { getUsersList } from '@/lib/admin/list';
|
||||
import { requireAdmin } from '@/lib/auth/admin-guard';
|
||||
import { UsersTable } from './users-table';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
@@ -10,11 +11,18 @@ export default async function AdminUsersPage() {
|
||||
// Initial load runs on the server (the admin session is already validated by
|
||||
// the admin layout's requireAdmin()), so the first paint never races the
|
||||
// client session-cookie refresh.
|
||||
const admin = await requireAdmin();
|
||||
const { users, total } = await getUsersList({
|
||||
page: 1,
|
||||
perPage: PER_PAGE,
|
||||
search: '',
|
||||
});
|
||||
|
||||
return <UsersTable initialUsers={users} initialTotal={total} />;
|
||||
return (
|
||||
<UsersTable
|
||||
initialUsers={users}
|
||||
initialTotal={total}
|
||||
currentUserId={admin.id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user