mirror of
https://github.com/Sevichecc/m-oauth.git
synced 2025-04-30 06:59:29 +08:00
feat: useCreateApp hook
This commit is contained in:
parent
1990cdb898
commit
ae0fc58569
10 changed files with 402 additions and 79 deletions
31
app/page.tsx
31
app/page.tsx
|
@ -1,15 +1,40 @@
|
||||||
import InputForm from "@/components/InputForm";
|
import InputForm from "@/components/InputForm";
|
||||||
import ClientOnly from "@/components/ClientOnly";
|
import ClientOnly from "@/components/ClientOnly";
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import DataDisplay from "@/components/DataDisplay";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<h1 className="mb-5 scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
<div className="flex flex-col gap-5">
|
||||||
M-OAuth
|
<Card className="mt-5">
|
||||||
</h1>
|
<CardHeader>
|
||||||
|
<CardTitle>M-OAuth</CardTitle>
|
||||||
|
<CardDescription>Card Description</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardContent>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<InputForm />
|
<InputForm />
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
</CardContent>
|
||||||
|
{/* <CardFooter>
|
||||||
|
<p>Card Footer</p>
|
||||||
|
</CardFooter> */}
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<CardContent>
|
||||||
|
<DataDisplay />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
43
components/DataDisplay.tsx
Normal file
43
components/DataDisplay.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
'use client'
|
||||||
|
|
||||||
|
import useCreateApp from "@/hooks/useCreateApp";
|
||||||
|
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
|
import { AppEntry } from "../lib/types";
|
||||||
|
|
||||||
|
interface DataDisplayProps {
|
||||||
|
appEntry: AppEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderTableRow = (label: string, value: string | undefined) => (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell className="font-medium">{label}</TableCell>
|
||||||
|
<TableCell>{value}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
|
||||||
|
const DataDisplay = () => {
|
||||||
|
const { appEntry } = useCreateApp();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table>
|
||||||
|
<TableCaption>A list of your recent invoices.</TableCaption>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>Data Name</TableHead>
|
||||||
|
<TableHead>Value</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{renderTableRow("ID", appEntry?.id)}
|
||||||
|
{renderTableRow("Name", appEntry?.name)}
|
||||||
|
{renderTableRow("Website", appEntry?.website || '')}
|
||||||
|
{renderTableRow("Redirect URI", appEntry?.redirectUri)}
|
||||||
|
{renderTableRow("Client ID", appEntry?.clientId)}
|
||||||
|
{renderTableRow("Client Secret", appEntry?.clientSecret)}
|
||||||
|
{renderTableRow("Vapid Key", appEntry?.vapidKey)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataDisplay;
|
|
@ -1,10 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as z from "zod";
|
import * as z from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
@ -14,66 +14,10 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import {
|
|
||||||
READ_SCOPES,
|
|
||||||
WRITE_SCOPES,
|
|
||||||
ADMIN_READ_SCOPES,
|
|
||||||
ADMIN_WRITE_SCOPES,
|
|
||||||
} from "@/lib/utils";
|
|
||||||
import ScopeSection from "./ScopeSection";
|
|
||||||
|
|
||||||
export type MethodType =
|
import ScopeSection from "@/components/ScopeSection";
|
||||||
| "read"
|
import { scopesInfo } from "@/lib/utils";
|
||||||
| "write"
|
import useCreateApp from "@/hooks/useCreateApp";
|
||||||
| "follow"
|
|
||||||
| "crypto"
|
|
||||||
| "follow"
|
|
||||||
| "admin"
|
|
||||||
| "push";
|
|
||||||
export interface ScopeInfo {
|
|
||||||
method: MethodType;
|
|
||||||
label: string;
|
|
||||||
scopes?: string[] | string[][];
|
|
||||||
description: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scopesInfo: ScopeInfo[] = [
|
|
||||||
{
|
|
||||||
method: "read",
|
|
||||||
label: "Read",
|
|
||||||
scopes: READ_SCOPES,
|
|
||||||
description: "read account's data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: "write",
|
|
||||||
label: "Write",
|
|
||||||
scopes: WRITE_SCOPES,
|
|
||||||
description: "modify account's data",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: "admin",
|
|
||||||
label: "Admin",
|
|
||||||
scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES],
|
|
||||||
description: "read all data on the server",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: "follow",
|
|
||||||
label: "Follow",
|
|
||||||
description: "modify account relationships,deprecated in 3.5.0 and newer.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: "push",
|
|
||||||
label: "Push",
|
|
||||||
description: "receive push notifications",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
method: "crypto",
|
|
||||||
label: "Crypto",
|
|
||||||
description: "use end-to-end encryption",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
instance: z.string().trim(),
|
instance: z.string().trim(),
|
||||||
|
@ -83,25 +27,23 @@ const formSchema = z.object({
|
||||||
website: z.string().url().trim().optional(),
|
website: z.string().url().trim().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type FormSchema = z.infer<typeof formSchema>;
|
||||||
|
|
||||||
const InputForm = () => {
|
const InputForm = () => {
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
const { createApp } = useCreateApp();
|
||||||
|
const form = useForm<FormSchema>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
instance: "https://",
|
instance: "https://",
|
||||||
clientName: "",
|
clientName: "",
|
||||||
redirectUris: "",
|
redirectUris: "",
|
||||||
scopes: [],
|
scopes: ["read"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
|
||||||
const scopes = values.scopes?.join(" ");
|
|
||||||
console.log(scopes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
<form onSubmit={form.handleSubmit(createApp)} className="space-y-6 flex flex-col">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="instance"
|
name="instance"
|
||||||
|
@ -190,7 +132,7 @@ const InputForm = () => {
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Button type="submit">Submit</Button>
|
<Button type="submit" className="w-ful">Submit</Button>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { MethodType } from "./InputForm";
|
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
|
import { MethodType } from "@/lib/types";
|
||||||
|
|
||||||
interface ScopeCheckboxProps {
|
interface ScopeCheckboxProps {
|
||||||
scope: string;
|
scope: string;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { ChevronsUpDown } from "lucide-react";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
Collapsible,
|
Collapsible,
|
||||||
|
@ -7,10 +8,10 @@ import {
|
||||||
CollapsibleTrigger,
|
CollapsibleTrigger,
|
||||||
} from "@/components/ui/collapsible";
|
} from "@/components/ui/collapsible";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ChevronsUpDown } from "lucide-react";
|
import ScopeItem from "@/components/ScopeItem";
|
||||||
|
|
||||||
|
import { ScopeInfo } from "@/lib/types";
|
||||||
|
|
||||||
import { ScopeInfo } from "./InputForm";
|
|
||||||
import ScopeItem from "./ScopeItem";
|
|
||||||
interface ScopeSectionProps {
|
interface ScopeSectionProps {
|
||||||
info: ScopeInfo;
|
info: ScopeInfo;
|
||||||
field: any;
|
field: any;
|
||||||
|
|
79
components/ui/card.tsx
Normal file
79
components/ui/card.tsx
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Card = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Card.displayName = "Card"
|
||||||
|
|
||||||
|
const CardHeader = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardHeader.displayName = "CardHeader"
|
||||||
|
|
||||||
|
const CardTitle = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLHeadingElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<h3
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-lg font-semibold leading-none tracking-tight",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardTitle.displayName = "CardTitle"
|
||||||
|
|
||||||
|
const CardDescription = React.forwardRef<
|
||||||
|
HTMLParagraphElement,
|
||||||
|
React.HTMLAttributes<HTMLParagraphElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<p
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardDescription.displayName = "CardDescription"
|
||||||
|
|
||||||
|
const CardContent = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
||||||
|
))
|
||||||
|
CardContent.displayName = "CardContent"
|
||||||
|
|
||||||
|
const CardFooter = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
React.HTMLAttributes<HTMLDivElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(" flex items-center p-6 pt-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
CardFooter.displayName = "CardFooter"
|
||||||
|
|
||||||
|
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
114
components/ui/table.tsx
Normal file
114
components/ui/table.tsx
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Table = React.forwardRef<
|
||||||
|
HTMLTableElement,
|
||||||
|
React.HTMLAttributes<HTMLTableElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<div className="w-full overflow-auto">
|
||||||
|
<table
|
||||||
|
ref={ref}
|
||||||
|
className={cn("w-full caption-bottom text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
Table.displayName = "Table"
|
||||||
|
|
||||||
|
const TableHeader = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
|
||||||
|
))
|
||||||
|
TableHeader.displayName = "TableHeader"
|
||||||
|
|
||||||
|
const TableBody = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tbody
|
||||||
|
ref={ref}
|
||||||
|
className={cn("[&_tr:last-child]:border-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableBody.displayName = "TableBody"
|
||||||
|
|
||||||
|
const TableFooter = React.forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tfoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn("bg-primary font-medium text-primary-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableFooter.displayName = "TableFooter"
|
||||||
|
|
||||||
|
const TableRow = React.forwardRef<
|
||||||
|
HTMLTableRowElement,
|
||||||
|
React.HTMLAttributes<HTMLTableRowElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tr
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableRow.displayName = "TableRow"
|
||||||
|
|
||||||
|
const TableHead = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<th
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableHead.displayName = "TableHead"
|
||||||
|
|
||||||
|
const TableCell = React.forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<td
|
||||||
|
ref={ref}
|
||||||
|
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCell.displayName = "TableCell"
|
||||||
|
|
||||||
|
const TableCaption = React.forwardRef<
|
||||||
|
HTMLTableCaptionElement,
|
||||||
|
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<caption
|
||||||
|
ref={ref}
|
||||||
|
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
TableCaption.displayName = "TableCaption"
|
||||||
|
|
||||||
|
export {
|
||||||
|
Table,
|
||||||
|
TableHeader,
|
||||||
|
TableBody,
|
||||||
|
TableFooter,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
TableCell,
|
||||||
|
TableCaption,
|
||||||
|
}
|
54
hooks/useCreateApp.ts
Normal file
54
hooks/useCreateApp.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import { FormSchema } from "@/components/InputForm";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { AppEntry } from "@/lib/types";
|
||||||
|
|
||||||
|
type MError = {
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useCreateApp = () => {
|
||||||
|
const [appEntry, setAppEntry] = useState<AppEntry>();
|
||||||
|
|
||||||
|
const createApp = useCallback(
|
||||||
|
async ({
|
||||||
|
instance,
|
||||||
|
website,
|
||||||
|
clientName,
|
||||||
|
redirectUris,
|
||||||
|
scopes,
|
||||||
|
}: FormSchema) => {
|
||||||
|
const app = {
|
||||||
|
website,
|
||||||
|
client_name: clientName,
|
||||||
|
redirect_uris: redirectUris,
|
||||||
|
scopes: scopes?.join(" "),
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("app,", app);
|
||||||
|
try {
|
||||||
|
let request = await fetch(`${instance}/api/v1/apps`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(app),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!request.ok || request.status === 424) {
|
||||||
|
throw new Error((await request.json()).error);
|
||||||
|
}
|
||||||
|
setAppEntry(await request.json());
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error((error as MError).error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
console.log(appEntry);
|
||||||
|
return {
|
||||||
|
appEntry,
|
||||||
|
createApp,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useCreateApp;
|
27
lib/types.ts
Normal file
27
lib/types.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
export type MethodType =
|
||||||
|
| "read"
|
||||||
|
| "write"
|
||||||
|
| "follow"
|
||||||
|
| "crypto"
|
||||||
|
| "follow"
|
||||||
|
| "admin"
|
||||||
|
| "push";
|
||||||
|
|
||||||
|
export interface ScopeInfo {
|
||||||
|
method: MethodType;
|
||||||
|
label: string;
|
||||||
|
scopes?: string[] | string[][];
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppEntry {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
website: string | null;
|
||||||
|
redirectUri: string;
|
||||||
|
clientId: string;
|
||||||
|
clientSecret: string;
|
||||||
|
vapidKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
38
lib/utils.ts
38
lib/utils.ts
|
@ -1,5 +1,6 @@
|
||||||
import { clsx, type ClassValue } from "clsx";
|
import { clsx, type ClassValue } from "clsx";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import { ScopeInfo } from "./types";
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
|
@ -53,3 +54,40 @@ export const ADMIN_WRITE_SCOPES = [
|
||||||
"admin:write:email_domain_blocks",
|
"admin:write:email_domain_blocks",
|
||||||
"admin:write:canonical_email_blocks",
|
"admin:write:canonical_email_blocks",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const scopesInfo: ScopeInfo[] = [
|
||||||
|
{
|
||||||
|
method: "read",
|
||||||
|
label: "Read",
|
||||||
|
scopes: READ_SCOPES,
|
||||||
|
description: "read account's data",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "write",
|
||||||
|
label: "Write",
|
||||||
|
scopes: WRITE_SCOPES,
|
||||||
|
description: "modify account's data",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "admin",
|
||||||
|
label: "Admin",
|
||||||
|
scopes: [ADMIN_READ_SCOPES, ADMIN_WRITE_SCOPES],
|
||||||
|
description: "read all data on the server",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "follow",
|
||||||
|
label: "Follow",
|
||||||
|
description: "modify account relationships,deprecated in 3.5.0 and newer.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "push",
|
||||||
|
label: "Push",
|
||||||
|
description: "receive push notifications",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
method: "crypto",
|
||||||
|
label: "Crypto",
|
||||||
|
description: "use end-to-end encryption",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
Loading…
Reference in a new issue