TypeScript 97.5%
SQL 1.4%
Python 0.8%
1import { KeyRound, LogIn, ShieldAlert } from "lucide-react";2import { getWorkspace } from "@/lib/session";3import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";4import { Badge } from "@/components/ui/badge";5import { Switch } from "@/components/ui/switch";6import { ChangePasswordForm } from "@/components/dashboard/settings/change-password-form";7import { ActiveSessions } from "@/components/dashboard/settings/active-sessions";89export const dynamic = "force-dynamic";1011export default async function SecurityPage() {12 await getWorkspace();13 return (14 <div className="grid gap-6">15 <Card>16 <CardHeader>17 <CardTitle>Change password</CardTitle>18 <CardDescription>Use at least 10 characters with mixed case and a number or symbol. Changing it is recorded in your audit log.</CardDescription>19 </CardHeader>20 <CardContent>21 <ChangePasswordForm />22 </CardContent>23 </Card>2425 <Card>26 <CardHeader>27 <CardTitle>Active sessions</CardTitle>28 <CardDescription>Everywhere you are signed in. Revoke anything you do not recognise — API keys are separate and unaffected.</CardDescription>29 </CardHeader>30 <CardContent>31 <ActiveSessions />32 </CardContent>33 </Card>3435 <div className="grid gap-6 md:grid-cols-2">36 <Card>37 <CardHeader>38 <div className="flex items-center justify-between gap-3">39 <CardTitle>Two-factor authentication</CardTitle>40 <Badge variant="outline">Coming soon</Badge>41 </div>42 <CardDescription>Authenticator app (TOTP) codes are planned first; passkeys will follow. Not available during the public preview.</CardDescription>43 </CardHeader>44 <CardContent>45 <label className="flex items-center justify-between gap-3 rounded-md border border-border px-3 py-2.5 text-[13px] opacity-70">46 <span className="flex items-center gap-2">47 <KeyRound className="size-4 text-fg-subtle" aria-hidden /> Require a second factor at sign-in48 </span>49 <Switch disabled aria-label="Two-factor authentication (coming soon)" />50 </label>51 </CardContent>52 </Card>5354 <Card>55 <CardHeader>56 <CardTitle>Security notifications</CardTitle>57 <CardDescription>Emails we always send to your verified address. They cannot be turned off.</CardDescription>58 </CardHeader>59 <CardContent>60 <ul className="grid gap-2.5 text-[13px]">61 <li className="flex gap-2.5">62 <KeyRound className="mt-0.5 size-4 shrink-0 text-fg-subtle" aria-hidden />63 <span>64 <span className="font-medium">API key created or revoked</span>65 <span className="block text-fg-muted">Includes the key name and prefix, never the secret.</span>66 </span>67 </li>68 <li className="flex gap-2.5">69 <LogIn className="mt-0.5 size-4 shrink-0 text-fg-subtle" aria-hidden />70 <span>71 <span className="font-medium">Password, email or account changes</span>72 <span className="block text-fg-muted">Password resets, email change approvals and account deletion confirmations.</span>73 </span>74 </li>75 <li className="flex gap-2.5">76 <ShieldAlert className="mt-0.5 size-4 shrink-0 text-fg-subtle" aria-hidden />77 <span>78 <span className="font-medium">Spending limits</span>79 <span className="block text-fg-muted">When a soft limit is crossed or a hard limit stops requests.</span>80 </span>81 </li>82 </ul>83 </CardContent>84 </Card>85 </div>86 </div>87 );88}89