Skip to content

Commit

Permalink
feat: delete account
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixNgFender committed Mar 18, 2024
1 parent 59945d7 commit 0a225e4
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 1 deletion.
35 changes: 35 additions & 0 deletions src/app/settings/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use server';

import { env } from '@/config/env';
import { siteConfig } from '@/config/site';
import { fileStorage } from '@/infra';
import { auth } from '@/lib/auth';
import { authAction } from '@/lib/safe-action';
import { findManyByUserId as findManyAssetsByUserId } from '@/models/asset';
import { deleteOne as deleteOneUser } from '@/models/user';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { z } from 'zod';

const schema = z.object({});

export const deleteAccount = authAction(schema, async ({}, { user }) => {
// Don't need to invalidate the session, since the session table has a
// cascade delete on the user id. This will automatically delete the
// session when the user is deleted.
const sessionCookie = auth.createBlankSessionCookie();
cookies().set(
sessionCookie.name,
sessionCookie.value,
sessionCookie.attributes,
);
const assets = await findManyAssetsByUserId(user.id);
await Promise.all([
fileStorage.removeObjects(
env.S3_BUCKET_NAME,
assets.map((asset) => asset.name),
),
deleteOneUser(user.id),
]);
return redirect(siteConfig.paths.auth.signIn);
});
54 changes: 54 additions & 0 deletions src/app/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,26 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { DialogFooter, DialogHeader } from '@/components/ui/dialog';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { siteConfig } from '@/config/site';
import { umami } from '@/lib/analytics';
import { getUserSession } from '@/models/user';
import { Trash2, X } from 'lucide-react';
import Link from 'next/link';
import { redirect } from 'next/navigation';

import { deleteAccount } from './actions';

const ProfilePage = async () => {
const { user } = await getUserSession();

Expand All @@ -39,6 +52,47 @@ const ProfilePage = async () => {
</div>
</CardContent>
<CardFooter className="flex justify-between">
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">
Delete account
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>
Confirm account deletion
</DialogTitle>
<DialogDescription>
This irreversible action will delete your
account and all associated data.
</DialogDescription>
</DialogHeader>
<DialogFooter className="space-y-2">
<DialogClose asChild>
<Button
type="button"
variant="secondary"
className="mt-2"
>
<X className="mr-2 h-4 w-4" />
Close
</Button>
</DialogClose>
<form action={deleteAccount}>
<Button
variant="destructive"
data-umami-event={
umami.deleteAccount.name
}
>
<Trash2 className="mr-2 h-4 w-4" />
Delete account
</Button>
</form>
</DialogFooter>
</DialogContent>
</Dialog>
<Button asChild variant="secondary">
<Link href={siteConfig.paths.auth.passwordReset}>
Change Password
Expand Down
3 changes: 3 additions & 0 deletions src/lib/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export const umami = {
deleteTrack: {
name: 'delete-track',
},
deleteAccount: {
name: 'delete-account',
},
generation: {
init: {
name: 'process-track-generation-init',
Expand Down
11 changes: 10 additions & 1 deletion src/models/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,13 @@ const findManyByTrackId = async (trackId: string) => {
});
};

export { createOne, findManyByTrackId };
const findManyByUserId = async (userId: string) => {
return await db.query.assetTable.findMany({
where: eq(assetTable.userId, userId),
columns: {
name: true,
},
});
};

export { createOne, findManyByTrackId, findManyByUserId };
5 changes: 5 additions & 0 deletions src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ const updateOne = async (id: string, user: Partial<NewUser>) => {
.where(eq(userTable.id, id));
};

const deleteOne = async (id: string) => {
await db.delete(userTable).where(eq(userTable.id, id));
};

export type { DatabaseUser };

export {
Expand All @@ -121,4 +125,5 @@ export {
findOne,
findOneByEmail,
updateOne,
deleteOne,
};

0 comments on commit 0a225e4

Please sign in to comment.