mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-08-22 07:26:39 +00:00
Add API token roles to enhance access control
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/262170ae-5240-4866-86d5-1e4164217124.jpg
This commit is contained in:
@@ -61,6 +61,13 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select";
|
||||||
import { Loader2, Key, MoreVertical, Calendar, Copy, Info } from "lucide-react";
|
import { Loader2, Key, MoreVertical, Calendar, Copy, Info } from "lucide-react";
|
||||||
import { formatDistanceToNow, format } from "date-fns";
|
import { formatDistanceToNow, format } from "date-fns";
|
||||||
|
|
||||||
@@ -105,8 +112,9 @@ export default function ApiTokensPage() {
|
|||||||
mutationFn: async (data: z.infer<typeof tokenFormSchema>) => {
|
mutationFn: async (data: z.infer<typeof tokenFormSchema>) => {
|
||||||
const tokenData: Partial<InsertApiToken> = {
|
const tokenData: Partial<InsertApiToken> = {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
organizationId: currentOrganization?.id || 0,
|
organizationId: currentOrganization?.id || "",
|
||||||
permissions: data.permissions,
|
permissions: data.permissions,
|
||||||
|
role: data.role,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -226,6 +234,7 @@ export default function ApiTokensPage() {
|
|||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Name</TableHead>
|
<TableHead>Name</TableHead>
|
||||||
<TableHead>Token</TableHead>
|
<TableHead>Token</TableHead>
|
||||||
|
<TableHead>Role</TableHead>
|
||||||
<TableHead>Permissions</TableHead>
|
<TableHead>Permissions</TableHead>
|
||||||
<TableHead>Expires</TableHead>
|
<TableHead>Expires</TableHead>
|
||||||
<TableHead>Status</TableHead>
|
<TableHead>Status</TableHead>
|
||||||
@@ -239,9 +248,14 @@ export default function ApiTokensPage() {
|
|||||||
<TableCell className="font-mono text-xs">
|
<TableCell className="font-mono text-xs">
|
||||||
{token.token.substring(0, 8)}...
|
{token.token.substring(0, 8)}...
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Badge variant="outline" className="text-xs capitalize">
|
||||||
|
{token.role || "readonly"}
|
||||||
|
</Badge>
|
||||||
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div className="flex flex-wrap gap-1">
|
<div className="flex flex-wrap gap-1">
|
||||||
{token.permissions.map((permission) => (
|
{token.permissions?.map((permission) => (
|
||||||
<Badge key={permission} variant="outline" className="text-xs">
|
<Badge key={permission} variant="outline" className="text-xs">
|
||||||
{permission}
|
{permission}
|
||||||
</Badge>
|
</Badge>
|
||||||
@@ -328,6 +342,40 @@ export default function ApiTokensPage() {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="role"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Role</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
defaultValue={field.value}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a role" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{systemRoles.map((role) => (
|
||||||
|
<SelectItem key={role} value={role}>
|
||||||
|
{role === "admin" && "Administrator"}
|
||||||
|
{role === "manager" && "Manager"}
|
||||||
|
{role === "user" && "User"}
|
||||||
|
{role === "readonly" && "Read-only"}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormDescription>
|
||||||
|
Determines the level of access for this token
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="permissions"
|
name="permissions"
|
||||||
@@ -336,7 +384,7 @@ export default function ApiTokensPage() {
|
|||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<FormLabel className="text-base">Permissions</FormLabel>
|
<FormLabel className="text-base">Permissions</FormLabel>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
Select the permissions for this token
|
Select specific permissions for this token
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
</div>
|
</div>
|
||||||
{systemRoles.map((role) => (
|
{systemRoles.map((role) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user