allow deleting aliases
This commit is contained in:
parent
e10dbc9a62
commit
f7eb59e89e
|
@ -1,12 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { aliasAvailable, changeOwnPassword, createAliasSelf, fetchOwnAliases } from "@/lib/actions";
|
import { aliasAvailable, changeOwnPassword, createAliasSelf, deleteAlias, fetchOwnAliases } from "@/lib/actions";
|
||||||
import GhostMessage from "@/lib/components/ui/GhostMessage";
|
import GhostMessage from "@/lib/components/ui/GhostMessage";
|
||||||
import LoadingSpinner from "@/lib/components/ui/LoadingSpinner";
|
import LoadingSpinner from "@/lib/components/ui/LoadingSpinner";
|
||||||
import { AliasEntry } from "@/lib/db";
|
import { AliasEntry } from "@/lib/db";
|
||||||
import useWindowDimensions from "@/lib/hooks/useWindowDimensions";
|
import useWindowDimensions from "@/lib/hooks/useWindowDimensions";
|
||||||
import { aliasesNeedApproval } from "@/lib/util";
|
import { aliasesNeedApproval } from "@/lib/util";
|
||||||
import { Card, Text, Heading, Flex, TextField, Button, IconButton, Popover, Link, Tabs, Box, Grid, Dialog, Callout, Tooltip, Table, ScrollArea, DropdownMenu } from "@radix-ui/themes";
|
import { Card, Text, Heading, Flex, TextField, Button, IconButton, Popover, Link, Tabs, Box, Grid, Dialog, Callout, Tooltip, Table, ScrollArea, DropdownMenu, Code } from "@radix-ui/themes";
|
||||||
import { AlertCircleIcon, CheckIcon, ChevronDownIcon, CopyIcon, ExternalLinkIcon, InfoIcon, LockIcon, UserIcon, UsersRound } from "lucide-react";
|
import { AlertCircleIcon, CheckIcon, ChevronDownIcon, CopyIcon, ExternalLinkIcon, InfoIcon, LockIcon, UserIcon, UsersRound } from "lucide-react";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
@ -303,6 +303,7 @@ export default function SelfService() {
|
||||||
const alias = await createAliasSelf(`${newAliasUsername}@${newAliasDomain}`);
|
const alias = await createAliasSelf(`${newAliasUsername}@${newAliasDomain}`);
|
||||||
setAliases([...(aliases ?? []), alias]);
|
setAliases([...(aliases ?? []), alias]);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
}}>Change</Button>
|
}}>Change</Button>
|
||||||
|
@ -332,7 +333,41 @@ export default function SelfService() {
|
||||||
<Table.Cell justify='start'>{alias.alias}</Table.Cell>
|
<Table.Cell justify='start'>{alias.alias}</Table.Cell>
|
||||||
<Table.Cell justify='end'>{alias.pending ? "Pending" : "Active"}</Table.Cell>
|
<Table.Cell justify='end'>{alias.pending ? "Pending" : "Active"}</Table.Cell>
|
||||||
<Table.Cell justify='end'>
|
<Table.Cell justify='end'>
|
||||||
<Button variant="solid" size="1" mr="2">Delete</Button>
|
<Dialog.Root>
|
||||||
|
<Dialog.Trigger>
|
||||||
|
<Button variant="solid" size="1" mr="2">Delete</Button>
|
||||||
|
</Dialog.Trigger>
|
||||||
|
|
||||||
|
<Dialog.Content>
|
||||||
|
<Dialog.Title>Delete alias</Dialog.Title>
|
||||||
|
<Dialog.Description>
|
||||||
|
Are you sure you want to delete the alias <Code>{alias.alias}</Code>?
|
||||||
|
It will become available for other users to claim immediately.
|
||||||
|
</Dialog.Description>
|
||||||
|
|
||||||
|
<Flex gap="3" mt="4" justify="end">
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button variant="outline">Cancel</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
<Dialog.Close>
|
||||||
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
await deleteAlias(alias.alias);
|
||||||
|
setAliases(aliases.filter((a) => a.id != alias.id));
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(e);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</Dialog.Close>
|
||||||
|
</Flex>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog.Root>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>))
|
</Table.Row>))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { getServerSession } from "next-auth";
|
import { getServerSession } from "next-auth";
|
||||||
import { AliasEntry, createAlias, database, getUserAliases, setUserPassword } from "./db";
|
import { AliasEntry, createAlias, database, deleteAliasEntry, getAlias, getUserAliases, setUserPassword } from "./db";
|
||||||
import { aliasesNeedApproval, isAdmin } from "./util";
|
import { aliasesNeedApproval, isAdmin } from "./util";
|
||||||
|
|
||||||
export async function fetchAllUsers(): Promise<string[]> {
|
export async function fetchAllUsers(): Promise<string[]> {
|
||||||
|
@ -66,3 +66,14 @@ export async function createAliasSelf(alias: string): Promise<AliasEntry> {
|
||||||
pending: pending
|
pending: pending
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteAlias(alias: string) {
|
||||||
|
const session = await getServerSession();
|
||||||
|
if (!session?.user?.email) throw new Error("Unauthenticated");
|
||||||
|
|
||||||
|
if (!isAdmin(session) && (await getAlias(alias))?.address != session.user.email) {
|
||||||
|
throw new Error("Unauthorized");
|
||||||
|
}
|
||||||
|
|
||||||
|
await deleteAliasEntry(alias);
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,22 @@ export function getUserAliases(email: string) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAlias(alias: string) {
|
||||||
|
return new Promise<AliasEntry | undefined>(async (resolve, reject) => {
|
||||||
|
const db = database('aliases');
|
||||||
|
|
||||||
|
db.get("SELECT id, address, alias, pending FROM aliases WHERE address = ?", alias, (err, res: AliasEntry) => {
|
||||||
|
db.close();
|
||||||
|
if (err) return reject(err);
|
||||||
|
if (!res) return resolve(undefined);
|
||||||
|
resolve({
|
||||||
|
...res,
|
||||||
|
pending: !!res.pending,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function createAlias(user: string, alias: string, pending: boolean) {
|
export function createAlias(user: string, alias: string, pending: boolean) {
|
||||||
return new Promise<number>(async (resolve, reject) => {
|
return new Promise<number>(async (resolve, reject) => {
|
||||||
const db = database('aliases');
|
const db = database('aliases');
|
||||||
|
@ -95,3 +111,18 @@ export function createAlias(user: string, alias: string, pending: boolean) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function deleteAliasEntry(alias: string) {
|
||||||
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
|
const db = database('aliases');
|
||||||
|
|
||||||
|
db.run(
|
||||||
|
"DELETE FROM aliases WHERE alias = ?",
|
||||||
|
alias,
|
||||||
|
function(err: any) {
|
||||||
|
db.close();
|
||||||
|
if (err) return reject(err);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue