diff --git a/app/panel/inspect/account/[id]/page.tsx b/app/panel/inspect/account/[id]/page.tsx
index 3c487c6..732b525 100644
--- a/app/panel/inspect/account/[id]/page.tsx
+++ b/app/panel/inspect/account/[id]/page.tsx
@@ -1,10 +1,30 @@
+import { JsonCard } from "@/components/cards/JsonCard";
import { UserCard } from "@/components/cards/UserCard";
import { EmailClassificationCard } from "@/components/cards/authifier/EmailClassificationCard";
import { NavigationToolbar } from "@/components/common/NavigationToolbar";
import { AccountActions } from "@/components/inspector/AccountActions";
-import { fetchAccountById, fetchUserById } from "@/lib/db";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { Separator } from "@/components/ui/separator";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+import {
+ fetchAccountById,
+ fetchSessionsByAccount,
+ fetchUserById,
+} from "@/lib/db";
+import dayjs from "dayjs";
import { notFound } from "next/navigation";
import { User } from "revolt-api";
+import { decodeTime } from "ulid";
+
+import relativeTime from "dayjs/plugin/relativeTime";
+dayjs.extend(relativeTime);
export default async function User({
params,
@@ -15,6 +35,7 @@ export default async function User({
if (!account) return notFound();
const user = await fetchUserById(params.id);
+ const sessions = await fetchSessionsByAccount(params.id);
return (
@@ -22,6 +43,37 @@ export default async function User({
{user &&
}
+
+
+
+
+ Active Sessions
+
+
+
+
+
+ Name
+ Created
+
+
+
+ {sessions.map((session) => (
+
+ {session.name}
+
+ {dayjs(decodeTime(session._id)).fromNow()}
+
+
+ ))}
+
+
+
+
+
+
+
+
{/*TODO? update password, reset 2FA, disable / undisable (disabled if pending
delete), delete / cancel delete
diff --git a/components/ui/table.tsx b/components/ui/table.tsx
new file mode 100644
index 0000000..bb3a87f
--- /dev/null
+++ b/components/ui/table.tsx
@@ -0,0 +1,114 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+const Table = React.forwardRef<
+ HTMLTableElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+Table.displayName = "Table"
+
+const TableHeader = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableHeader.displayName = "TableHeader"
+
+const TableBody = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableBody.displayName = "TableBody"
+
+const TableFooter = React.forwardRef<
+ HTMLTableSectionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableFooter.displayName = "TableFooter"
+
+const TableRow = React.forwardRef<
+ HTMLTableRowElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableRow.displayName = "TableRow"
+
+const TableHead = React.forwardRef<
+ HTMLTableCellElement,
+ React.ThHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableHead.displayName = "TableHead"
+
+const TableCell = React.forwardRef<
+ HTMLTableCellElement,
+ React.TdHTMLAttributes
+>(({ className, ...props }, ref) => (
+ |
+))
+TableCell.displayName = "TableCell"
+
+const TableCaption = React.forwardRef<
+ HTMLTableCaptionElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+))
+TableCaption.displayName = "TableCaption"
+
+export {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+}
diff --git a/lib/db.ts b/lib/db.ts
index 6d502fe..ce0e80c 100644
--- a/lib/db.ts
+++ b/lib/db.ts
@@ -8,6 +8,7 @@ import type {
Message,
Report,
Server,
+ SessionInfo,
SnapshotContent,
User,
} from "revolt-api";
@@ -89,6 +90,24 @@ export async function fetchAccountById(id: string) {
);
}
+export async function fetchSessionsByAccount(accountId: string) {
+ return await mongo()
+ .db("revolt")
+ .collection("sessions")
+ .find(
+ { user_id: accountId },
+ {
+ projection: {
+ token: 0,
+ },
+ sort: {
+ _id: -1,
+ },
+ }
+ )
+ .toArray();
+}
+
export async function fetchUserById(id: string) {
return await mongo()
.db("revolt")