@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
52 lines (51 loc) • 2.58 kB
JavaScript
;
/*
* This file is part of CoCalc: Copyright © 2021 Sagemath, Inc.
* License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
Enforce limits on the number of that a user can cause to be sent.
For now starting with a simple limit: at most XXX messages per day.
*/
const DAILY_LIMIT = 1000;
const pii_1 = require("@cocalc/database/postgres/pii");
const pool_1 = __importDefault(require("@cocalc/database/pool"));
const settings_1 = require("@cocalc/server/settings");
// Call this function whenever an email will be sent on behalf of the given account.
// It will increment a counter for each day, and if it goes too high it throws
// an exceptions, which prevents further emais from being sent for that user.
async function sendEmailThrottle(id // account_id or project_id or organization_id...
) {
if (!id)
return; // not associated to a particular user
const day = startOfToday();
// get current count
const pool = (0, pool_1.default)("short"); // a few seconds old is ok...
const { rows } = await pool.query("SELECT count FROM email_counter WHERE time=$1 AND id=$2", [day, id]);
if (rows.length > 0 && rows[0].count > DAILY_LIMIT) {
throw Error(`You may send at most ${DAILY_LIMIT} emails per day, and you have reached that limit.`);
}
// Increment the counter.
if (rows.length > 0) {
// This will always work with no race conditions, since the given entry exists.
await pool.query("UPDATE email_counter SET count = count + 1 WHERE id=$1 AND time=$2", [id, day]);
}
else {
const settings = await (0, settings_1.getServerSettings)();
const expire = (0, pii_1.pii_retention_to_future)(settings.pii_retention ?? false);
// It's possible another server created email_counter in the meantime,
// hence the "ON CONFLICT".
await pool.query("INSERT INTO email_counter (id,time,count,expire) VALUES($1,$2,1,$3) ON CONFLICT (id, time) DO UPDATE SET count = excluded.count + 1", [id, day, expire]);
}
}
exports.default = sendEmailThrottle;
function startOfToday() {
// https://stackoverflow.com/questions/7195513/how-do-you-get-the-unix-timestamp-for-the-start-of-today-in-javascript
const now = new Date();
return new Date(now.getFullYear(), now.getMonth(), now.getDate());
}
//# sourceMappingURL=throttle.js.map