Fix GDPR export, delete-account cascade, errors.js boot crash
- Add GET /auth/export-data endpoint (GDPR data download) - Fix delete-account: comprehensive cascade delete + /delete-account alias - Remove non-existent sessions table reference that caused 500 errors - Fix errors.js: add missing CREATE TABLE statement (was causing SyntaxError on boot) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,16 +101,36 @@ async function authRoutes(app) {
|
|||||||
return { status: 'not_implemented', message: 'WebAuthn biometric auth coming soon.' };
|
return { status: 'not_implemented', message: 'WebAuthn biometric auth coming soon.' };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete account
|
// Delete account (GDPR + Google Play requirement)
|
||||||
app.delete('/auth/account', { preHandler: [async (req) => { await req.jwtVerify(); }] }, async (req, reply) => {
|
app.delete("/auth/account", { preHandler: [async (req) => { await req.jwtVerify(); }] }, async (req, reply) => {
|
||||||
const uid = req.user.id;
|
const uid = req.user.id;
|
||||||
await app.db.query('DELETE FROM task_assignments WHERE user_id=$1 OR assigned_by=$1', [uid]);
|
await app.db.query("DELETE FROM task_comments WHERE user_id=$1", [uid]);
|
||||||
await app.db.query('DELETE FROM tasks WHERE user_id=$1', [uid]);
|
await app.db.query("DELETE FROM subtasks WHERE assigned_to=$1", [uid]);
|
||||||
await app.db.query('DELETE FROM task_groups WHERE user_id=$1', [uid]);
|
await app.db.query("DELETE FROM task_collaboration WHERE from_user_id=$1 OR to_user_id=$1", [uid]);
|
||||||
await app.db.query('DELETE FROM goals WHERE user_id=$1', [uid]);
|
await app.db.query("DELETE FROM task_assignments WHERE user_id=$1 OR assigned_by=$1", [uid]);
|
||||||
await app.db.query('DELETE FROM sessions WHERE user_id=$1', [uid]);
|
await app.db.query("DELETE FROM push_subscriptions WHERE user_id=$1", [uid]);
|
||||||
await app.db.query('DELETE FROM users WHERE id=$1', [uid]);
|
await app.db.query("DELETE FROM goals WHERE user_id=$1", [uid]);
|
||||||
return reply.send({ data: { deleted: true } });
|
await app.db.query("DELETE FROM connectors WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM tasks WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM task_groups WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM users WHERE id=$1", [uid]);
|
||||||
|
return reply.send({ data: { deleted: true, message: "Account and all data permanently deleted" } });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alias: /auth/delete-account (backward compat)
|
||||||
|
app.delete("/auth/delete-account", { preHandler: [async (req) => { await req.jwtVerify(); }] }, async (req, reply) => {
|
||||||
|
const uid = req.user.id;
|
||||||
|
await app.db.query("DELETE FROM task_comments WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM subtasks WHERE assigned_to=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM task_collaboration WHERE from_user_id=$1 OR to_user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM task_assignments WHERE user_id=$1 OR assigned_by=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM push_subscriptions WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM goals WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM connectors WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM tasks WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM task_groups WHERE user_id=$1", [uid]);
|
||||||
|
await app.db.query("DELETE FROM users WHERE id=$1", [uid]);
|
||||||
|
return reply.send({ data: { deleted: true, message: "Account and all data permanently deleted" } });
|
||||||
});
|
});
|
||||||
|
|
||||||
// OAuth initiate routes moved to ./oauth.js
|
// OAuth initiate routes moved to ./oauth.js
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
// Task Team — Error Tracking — 2026-03-29
|
// Task Team — Error Tracking — 2026-03-29
|
||||||
|
|
||||||
async function errorRoutes(app) {
|
async function errorRoutes(app) {
|
||||||
|
await app.db.query(`
|
||||||
|
CREATE TABLE IF NOT EXISTS error_logs (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
level VARCHAR(20) DEFAULT 'error',
|
||||||
|
message TEXT,
|
||||||
|
stack TEXT,
|
||||||
|
url TEXT,
|
||||||
|
method VARCHAR(10),
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
created_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_errors_created ON error_logs(created_at DESC);
|
CREATE INDEX IF NOT EXISTS idx_errors_created ON error_logs(created_at DESC);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user