UNPKG

@cocalc/server

Version:

CoCalc server functionality: functions used by either the hub and the next.js server

52 lines (51 loc) 2.58 kB
"use strict"; /* * 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