@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
103 lines (100 loc) • 5.13 kB
JavaScript
;
/*
Set email address of an account.
The password must also be provided. If the email address is already set in the
database, then password has to be the current correct password. If the email
address is NOT set, then a new email address and password are set.
Also, if user changes email address to one that has some pending actions, carry
those actions out. (TODO: should probably only do these after email address
is verified.)
Throws an exception if something is wrong.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const password_hash_1 = __importStar(require("@cocalc/backend/auth/password-hash"));
const pool_1 = __importDefault(require("@cocalc/database/pool"));
const check_required_sso_1 = require("@cocalc/server/auth/sso/check-required-sso");
const get_strategies_1 = __importDefault(require("@cocalc/server/auth/sso/get-strategies"));
const misc_1 = require("@cocalc/util/misc");
const account_creation_actions_1 = __importStar(require("./account-creation-actions"));
async function setEmailAddress(account_id, email_address, password) {
if (!(0, misc_1.isValidUUID)(account_id)) {
throw Error("account_id is not valid");
}
if (!(0, misc_1.is_valid_email_address)(email_address)) {
throw Error("email address is not valid");
}
email_address = email_address.toLowerCase();
if (!password || password.length < 6) {
throw Error("password must be at least 6 characters");
}
const pool = (0, pool_1.default)();
const { rows } = await pool.query("SELECT email_address, password_hash FROM accounts WHERE account_id=$1", [account_id]);
if (rows.length == 0) {
throw Error("no such account");
}
const { password_hash, email_address: old_email_address } = rows[0];
// if you have an email address that's controlled by an "exclusive" SSO strategy
// you're not allowed to change your email address
const strategies = await (0, get_strategies_1.default)();
const strategy = (0, check_required_sso_1.checkRequiredSSO)({ strategies, email: old_email_address });
if (strategy != null) {
// user has no password set, so we can set it – but not the email address
if (!password_hash) {
await pool.query("UPDATE accounts SET password_hash=$1, WHERE account_id=$2", [(0, password_hash_1.default)(password), account_id]);
}
throw new Error(`You are not allowed to change your email address`);
}
// you're also not allowed to change your email address to one that's covered by an exclusive strategy
if ((0, check_required_sso_1.checkRequiredSSO)({ strategies, email: email_address }) != null) {
throw new Error(`You are not allowed to change your email address to this one`);
}
if (!password_hash) {
// setting both the email_address *and* password at once.
await pool.query("UPDATE accounts SET password_hash=$1, email_address=$2 WHERE account_id=$3", [(0, password_hash_1.default)(password), email_address, account_id]);
return;
}
// Verify that existing password is correct.
if (!(0, password_hash_1.verifyPassword)(password, password_hash)) {
throw Error("password is incorrect");
}
// Is the email address available?
if ((await pool.query("SELECT COUNT(*)::INT FROM accounts WHERE email_address=$1", [email_address])).rows[0].count > 0) {
throw Error(`email address "${email_address}" is already in use by another account`);
}
// Set the email address:
await pool.query("UPDATE accounts SET email_address=$1 WHERE account_id=$2", [
email_address,
account_id,
]);
// Do any pending account creation actions for this email.
await (0, account_creation_actions_1.default)(email_address, account_id);
await (0, account_creation_actions_1.creationActionsDone)(account_id);
}
exports.default = setEmailAddress;
//# sourceMappingURL=set-email-address.js.map