create endpoint for deleting account with all associated data

This commit is contained in:
Michi 2025-10-31 16:45:31 +01:00
parent 279845628c
commit 65f34d4d45
3 changed files with 54 additions and 8 deletions

View file

@ -6,24 +6,24 @@ export const attraction = sqliteTable('attraction', {
id: integer().primaryKey({ autoIncrement: true }),
name: text().notNull(),
apiCode: text('api_code').notNull().unique(),
themeparkId: integer('themepark_id').notNull().references(() => themepark.id)
themeparkId: integer('themepark_id').notNull().references(() => themepark.id, {onDelete: 'cascade'})
}, (t) => [
unique().on(t.apiCode, t.themeparkId)
])
export const attractionNotification = sqliteTable('attraction_notification', {
id: integer().primaryKey({ autoIncrement: true}),
userId: integer('user_id').notNull().references(() => user.id),
attractionId: integer('attraction_id').notNull().references(() => attraction.id),
notificationMethodId: integer('notification_method_id').notNull().references(() => notificationMethod.id)
userId: integer('user_id').notNull().references(() => user.id, {onDelete: 'cascade'}),
attractionId: integer('attraction_id').notNull().references(() => attraction.id, {onDelete: 'cascade'}),
notificationMethodId: integer('notification_method_id').notNull().references(() => notificationMethod.id, {onDelete: 'cascade'})
}, (t) => [
unique().on(t.userId, t.attractionId, t.notificationMethodId)
])
export const logbook = sqliteTable('logbook', {
id: integer().primaryKey({ autoIncrement: true }),
userId: integer('user_id').notNull().references(() => user.id),
attractionId: integer('attraction_id').notNull().references(() => attraction.id),
userId: integer('user_id').notNull().references(() => user.id, {onDelete: 'cascade'}),
attractionId: integer('attraction_id').notNull().references(() => attraction.id, {onDelete: 'cascade'}),
timestamp: integer().notNull(), // unix timecode
expectedWaittime: integer(),
realWaittime: integer()
@ -35,8 +35,8 @@ export const notificationMethod = sqliteTable('notification_method', {
id: integer().primaryKey({ autoIncrement: true }),
webhookUrl: text('webhook_url').notNull(),
shownName: text().notNull(),
userId: integer('user_id').notNull().references(() => user.id),
notificationProviderId: integer('notification_provider_id').notNull().references(() => notificationProvider.id),
userId: integer('user_id').notNull().references(() => user.id, {onDelete: 'cascade'}),
notificationProviderId: integer('notification_provider_id').notNull().references(() => notificationProvider.id, {onDelete: 'cascade'}),
}, (t) => [
unique().on(t.webhookUrl, t.userId, t.notificationProviderId)
])

View file

@ -6,6 +6,7 @@ import attraction from './routes/attraction'
import notification from './routes/notification-method'
import logbook from './routes/logbook'
import themepark from './routes/themepark'
import user from './routes/user'
import cronRouter from './jobs/cron'
// create app
@ -37,6 +38,7 @@ app.route('/attraction', attraction)
app.route('/notification-method', notification)
app.route('/logbook', logbook)
app.route('/themepark', themepark)
app.route('/user', user)
export default {
fetch: app.fetch,
scheduled: cronRouter,

44
api/src/routes/user.ts Normal file
View file

@ -0,0 +1,44 @@
import { Hono } from 'hono'
import { DatabaseError } from '../errors'
import { getDbContext } from '../db/client'
import { getUser } from '../lib/user-auth'
import { user } from '../db/schema'
import { eq } from 'drizzle-orm'
import { Message } from '../types/response'
import * as z from 'zod'
import httpZValidator from '../lib/http-z-validator'
const app = new Hono()
/**
* Deletes user account with all associated data (requires parameter 'confirm' to be true)
* Be careful when using (once your data is delete it cannot be restored)
*/
app.delete('delete-account', httpZValidator('query', z.strictObject({
confirm: z.literal('true') // to prevent unwanted account deletion when hitting the endpoint unintentionally
})),
async (c) => {
const db = getDbContext(c);
const currentUser = await getUser(c);
const params = c.req.valid('query');
try{
const res = await db.delete(user).where(
eq(user.id, currentUser.id)
).returning();
const deletedUser = res[0];
const message = res.length > 0
? `User account ${deletedUser.mail} with all associated data deleted.`
: 'User account does not exist. No changes made.';
return c.json(new Message(message));
}
catch(e){
console.error(e);
throw new DatabaseError();
}
})
export default app