UNPKG

smc-hub

Version:

CoCalc: Backend webserver component

160 lines (148 loc) 4.76 kB
// Generated by CoffeeScript 2.5.1 (function() { //######################################################################## // This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. // License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details //######################################################################## /* Temporary authentication token for user. */ var BAN_TIME_MS, async, auth, ban, defaults, misc, random_key, required, types; async = require('async'); random_key = require("random-key"); misc = require('smc-util/misc'); ({defaults, types, required} = misc); auth = require('./auth'); // map {account_id:{user_account_id:timestamp}} ban = {}; BAN_TIME_MS = 1000 * 60; exports.get_user_auth_token = function(opts) { var auth_token, b, is_admin, is_lti, ref; opts = defaults(opts, { // temporary until types is more than just a WARNING database: required, account_id: required, user_account_id: required, password: required, // admin can get token by using password = ''. lti: false, // LTI auth mode cb: required }); types(opts, { database: types.object.isRequired, account_id: types.string.isRequired, user_account_id: types.string.isRequired, password: types.string.isRequired, lti: types.bool, // LTI auth mode cb: types.func.isRequired // cb(err, auth_token) }); auth_token = void 0; b = (ref = ban[opts.account_id]) != null ? ref[opts.user_account_id] : void 0; if ((b != null) && (new Date() - b < BAN_TIME_MS)) { opts.cb(`banned -- please wait at least ${BAN_TIME_MS / 1000}s before trying again`); return; } is_admin = false; is_lti = false; return async.series([ function(cb) { if (opts.password !== '') { is_admin = false; cb(); return; } if (!opts.lti) { // must be an admin or NOPE. return opts.database.is_admin({ account_id: opts.account_id, cb: (err, _is_admin) => { is_admin = _is_admin; return cb(err); } }); } else { // must have an lti_id return opts.database.get_account({ account_id: opts.account_id, columns: ["lti_id"], cb: (err, lti_id) => { is_lti = !!lti_id; return cb(err); } }); } }, function(cb) { if ((is_admin || is_lti) && opts.password === '') { // no need to do anything further cb(); return; } // confirm auth return auth.is_password_correct({ database: opts.database, account_id: opts.user_account_id, password: opts.password, allow_empty_password: false, // user must have a password cb: function(err, is_correct) { var name; if (err) { return cb(err); } else if (!is_correct) { // ban opts.account_id from attempting again for 1 minute (say) b = ban[name = opts.account_id] != null ? ban[name] : ban[name] = {}; b[opts.user_account_id] = new Date(); return cb("incorrect password"); } else { return cb(); } } }); }, function(cb) { // generate token auth_token = random_key.generate(24); // save in db return opts.database.save_auth_token({ account_id: opts.user_account_id, auth_token: auth_token, ttl: 12 * 3600, // ttl in seconds (12 hours) cb: cb }); }, function(cb) { // log that we created an auth_token for an account... // just in case (this is entirely a security thing) return opts.database.log({ event: 'get_user_auth_token', value: { account_id: opts.account_id, user_account_id: opts.user_account_id, is_admin: is_admin }, cb: cb }); } ], function(err) { return opts.cb(err, auth_token); }); }; exports.revoke_user_auth_token = function(opts) { opts = defaults(opts, { database: required, auth_token: required, cb: required }); types(opts, { database: types.object.isRequired, auth_token: types.string.isRequired, cb: types.func.isRequired // cb(err, auth_token) }); return opts.database.delete_auth_token({ auth_token: opts.auth_token, cb: cb }); }; }).call(this); //# sourceMappingURL=auth-token.js.map