owltide/server/api/admin/database-import.post.ts
Hornwitser e5e923bc8d Implement database administration
Add routes and admin panel elements for creating a database backup,
restoring from a backup, deleting the existing schedule, and replacing
the database with the demo schedule.  These server as crude ways to
manage the data stored in the system.
2025-06-28 01:30:39 +02:00

44 lines
1.8 KiB
TypeScript

import { readNextSessionId, readNextUserId, readSessions, type ServerSession, type ServerUser, writeNextSessionId, writeNextUserId, writeSchedule, writeSessions, writeSubscriptions, writeUsers } from "~/server/database";
import type { ApiSchedule, ApiSubscription } from "~/shared/types/api";
export default defineEventHandler(async (event) => {
await requireServerSessionWithAdmin(event);
const formData = await readMultipartFormData(event);
let snapshot: undefined | {
nextUserId: number,
users: ServerUser[],
nextSessionId: number,
sessions: ServerSession[],
subscriptions: ApiSubscription[],
schedule: ApiSchedule,
};
for (const part of formData ?? []) {
if (part.name === "snapshot") {
snapshot = JSON.parse(part.data.toString("utf-8"));
}
}
if (!snapshot) {
throw createError({
statusCode: 400,
statusMessage: "Bad Request",
message: "snapshot missing."
});
}
const currentNextUserId = await readNextUserId();
await writeNextUserId(Math.max(currentNextUserId, snapshot.nextUserId));
await writeUsers(snapshot.users);
const currentNextSessionId = await readNextSessionId();
await writeNextSessionId(Math.max(currentNextSessionId, snapshot.nextSessionId));
const currentSessions = new Map((await readSessions()).map(session => [session.id, session]));
await writeSessions(snapshot.sessions.filter(session => {
const current = currentSessions.get(session.id);
// Only keep sessions that match the account id in both sets to avoid
// resurrecting deleted sessions. This will still cause session cross
// pollution if a snapshot from another instance is loaded here.
return current && current.account.id === session.account.id;
}));
await writeSubscriptions(snapshot.subscriptions);
await writeSchedule(snapshot.schedule);
await sendRedirect(event, "/");
})