PronounsPage/server/cleanupAccounts.js
Adaline Simonian 23a3862ca0
test: introduce snapshot-based smoke tests
- Adds a new test suite with Docker-based smoke tests for all locales.
  Can be run using the ./smoketest.sh script.
- Replaces all calls to Math.random() with a new helper that returns 0.5
  in snapshot testing mode, ensuring deterministic snapshots.
- Similarly replaces all calls to new Date() and Date.now() with new
  helpers that return a fixed date in snapshot testing mode.
- Replaces checks against NODE_ENV with APP_ENV, to ensure that the
  bundles can be built with Nuxt for testing without losing code that
  would otherwise be stripped out by production optimizations.
- Adds a database init script that can be used to initialize the
  database with a single admin user and a long-lived JWT token for use
  in automation tests.
- Adds a JWT decoding/encoding CLI tool for debugging JWTs.

Note: Snapshots are not checked in, and must be generated manually. See
test/__snapshots__/.gitignore for more information.
2025-02-02 23:11:19 -08:00

104 lines
2.8 KiB
JavaScript

import './setup.ts';
import * as Sentry from '@sentry/node';
import { newDate } from '../src/helpers.ts';
import dbConnection from './db.ts';
import mailer from './mailer.ts';
const execute = process.env.EXECUTE === '1';
console.log(execute ? 'WILL EXECUTE!' : 'Dry run');
const now = +newDate();
const month = 30 * 24 * 60 * 60 * 1000;
const week = 7 * 24 * 60 * 60 * 1000;
const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
async function warnInactive(db) {
console.log('--- Fetching ids to warn ---');
const users = await db.all(`
SELECT u.id, u.username, u.email, u.bannedReason
FROM users u
WHERE
inactiveWarning IS NULL
AND (
(
u.id NOT IN (SELECT DISTINCT p.userId FROM profiles p)
AND lastActive < ${now - month}
)
OR bannedReason IS NOT NULL
)
`);
console.log(users.length);
for (const user of users) {
console.log('warn', user);
if (!execute) {
continue;
}
try {
const userRefreshed = await db.get(`SELECT u.id, u.username, u.email, u.bannedReason, u.inactiveWarning FROM users u WHERE u.id = '${user.id}'`);
if (userRefreshed.inactiveWarning !== null) {
continue;
}
if (userRefreshed.email.endsWith('.oauth')) {
await db.get(`UPDATE users SET inactiveWarning = ${now - week - 1000} WHERE id = '${userRefreshed.id}'`);
continue;
}
await db.get(`UPDATE users SET inactiveWarning = ${now} WHERE id = '${userRefreshed.id}'`);
if (userRefreshed.bannedReason !== null) {
continue;
}
mailer(userRefreshed.email, 'inactivityWarning', { username: userRefreshed.username });
} catch (error) {
Sentry.captureException(error);
}
await sleep(3000);
}
}
async function removeWarned(db) {
console.log('--- Fetching ids to remove ---');
const users = await db.all(`
SELECT u.id, u.username, u.email
FROM users u
WHERE (
u.id NOT IN (
SELECT DISTINCT p.userId
FROM profiles p
)
OR bannedReason IS NOT NULL
)
AND inactiveWarning IS NOT NULL
AND inactiveWarning < ${now - week}
`);
console.log(users.length);
for (const user of users) {
console.log('remove', user);
if (!execute) {
continue;
}
await db.get(`DELETE FROM users WHERE id = '${user.id}'`);
}
}
async function cleanup() {
const db = await dbConnection();
await db.get('PRAGMA foreign_keys = ON');
await warnInactive(db);
await removeWarned(db);
}
cleanup();