@cocalc/database
Version:
CoCalc: code for working with our PostgreSQL database
79 lines • 3.12 kB
JavaScript
;
/*
* This file is part of CoCalc: Copyright © 2022 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 });
exports.getOauthCache = exports.getPassportCache = void 0;
const pool_1 = __importDefault(require("../pool"));
// this is a general key/value store with expiration.
// each key is prefixed with the passport strategy name.
// this is used by some passport strategies to share data regarding
// a request and a response, or other information. for example,
// if there are 3 hubs and one of them generates an ID that's expected to
// be returned by the SSO server, then the possibly different hub receiving the
// response can only know that ID, if it is somehow stored in this table.
const SAVE_QUERY = `
INSERT INTO passport_store (key, value, expire)
VALUES ($1, $2, NOW() + make_interval(secs => $3))
ON CONFLICT (key)
DO UPDATE SET value = $2, expire = NOW() + make_interval(secs => $3);`;
// ATTN: do not change the method names nilly-willy: https://github.com/node-saml/passport-saml#cache-provider
class PassportCache {
constructor(name, cachedMS) {
if (typeof name !== "string" || name.length === 0) {
throw new Error("name must be a non-empty string");
}
if (typeof cachedMS !== "number" || cachedMS < 0) {
throw new Error("cachedMS must be a positive number");
}
this.name = name;
this.cachedMS = cachedMS;
this.pool = (0, pool_1.default)();
}
getKey(key) {
return `${this.name}::${key}`;
}
// saves the key with the optional value, returns the saved value
async saveAsync(key, value) {
const cacheSecs = Math.floor(this.cachedMS / 1000);
await this.pool.query(SAVE_QUERY, [this.getKey(key), value, cacheSecs]);
}
// returns the value if found, null otherwise
async getAsync(key) {
const { rows } = await this.pool.query(`SELECT value, expire FROM passport_store WHERE key = $1`, [this.getKey(key)]);
if (rows.length === 0) {
return null;
}
const { value, expire } = rows[0];
if (expire < new Date()) {
return null;
}
else {
return value;
}
}
// removes the key from the cache, returns the
// key removed, null if no key is removed
async removeAsync(key) {
await this.pool.query(`DELETE FROM passport_store WHERE key = $1`, [
this.getKey(key),
]);
}
}
const samlCaches = {};
function getPassportCache(name, cachedMS) {
if (!samlCaches[name]) {
samlCaches[name] = new PassportCache(name, cachedMS);
}
return samlCaches[name];
}
exports.getPassportCache = getPassportCache;
function getOauthCache(name) {
return getPassportCache(name, 1000 * 60 * 60);
}
exports.getOauthCache = getOauthCache;
//# sourceMappingURL=passport-store.js.map