mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2025-12-19 05:47:46 +00:00
major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
118 lines
4.2 KiB
JavaScript
118 lines
4.2 KiB
JavaScript
const router = require('express').Router();
|
|
const debug = require('debug')('jambonz:api-server');
|
|
const {DbErrorBadRequest} = require('../../utils/errors');
|
|
const {promisePool} = require('../../db');
|
|
const {validateEmail, emailSimpleText} = require('../../utils/email-utils');
|
|
const sysError = require('../error');
|
|
const sqlRetrieveUser = `SELECT * from users user
|
|
LEFT JOIN accounts AS account
|
|
ON user.account_sid = account.account_sid
|
|
WHERE user.user_sid = ?`;
|
|
|
|
const validateRequest = async(req, res) => {
|
|
const payload = req.body || {};
|
|
|
|
/* valid type */
|
|
if (!['email', 'phone'].includes(payload.type)) {
|
|
throw new DbErrorBadRequest(`invalid activation type: ${payload.type}`);
|
|
}
|
|
|
|
/* valid user? */
|
|
const [rows] = await promisePool.query('SELECT * from users WHERE user_sid = ?',
|
|
payload.user_sid);
|
|
if (0 === rows.length) throw new DbErrorBadRequest('invalid user_sid');
|
|
|
|
/* valid email? */
|
|
if (payload.type === 'email' && !validateEmail(payload.value)) throw new DbErrorBadRequest('invalid email');
|
|
|
|
};
|
|
|
|
router.post('/', async(req, res) => {
|
|
const logger = req.app.locals.logger;
|
|
const {user_sid, type, code, value} = req.body;
|
|
|
|
try {
|
|
await validateRequest(req, res);
|
|
|
|
const fields = type === 'email' ?
|
|
['email', 'email_validated', 'email_activation_code'] :
|
|
['phone', 'phone_validated', 'phone_activation_code'];
|
|
const sql =
|
|
`UPDATE users set ${fields[0]} = ?, ${fields[1]} = 0, ${fields[2]} = ? WHERE user_sid = ?`;
|
|
const [r] = await promisePool.execute(sql, [value, code, user_sid]);
|
|
logger.debug({r}, 'Result from adding activation code');
|
|
debug({r}, 'Result from adding activation code');
|
|
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
if (type === 'email') {
|
|
/* send code via email */
|
|
const text = '';
|
|
const subject = '';
|
|
await emailSimpleText(logger, value, subject, text);
|
|
}
|
|
else {
|
|
/* send code via SMS */
|
|
}
|
|
}
|
|
res.sendStatus(204);
|
|
} catch (err) {
|
|
sysError(logger, res, err);
|
|
}
|
|
});
|
|
|
|
router.put('/:code', async(req, res) => {
|
|
const logger = req.app.locals.logger;
|
|
const code = req.params.code;
|
|
const {user_sid, type} = req.body;
|
|
|
|
try {
|
|
let activateAccount = false;
|
|
let deactivateOldUsers = false;
|
|
let account_sid;
|
|
if (type === 'email') {
|
|
/* check whether this is first-time activation of account during sign-up/register */
|
|
const [r] = await promisePool.query({sql: sqlRetrieveUser, nestTables: true}, user_sid);
|
|
logger.debug({r}, 'activationcode - selected user');
|
|
if (r.length) {
|
|
const {user, account} = r[0];
|
|
account_sid = account.account_sid;
|
|
const [otherUsers] = await promisePool.query('SELECT * from users WHERE account_sid = ? AND user_sid <> ?',
|
|
[account_sid, user_sid]);
|
|
logger.debug({otherUsers}, `activationcode - users other than ${user_sid}`);
|
|
if (0 === otherUsers.length && user.provider === 'local' && !user.email_validated) {
|
|
logger.debug('activationcode - activating account');
|
|
activateAccount = true;
|
|
}
|
|
else if (otherUsers.length) {
|
|
logger.debug('activationcode - adding new user for existing account');
|
|
deactivateOldUsers = true;
|
|
}
|
|
}
|
|
}
|
|
const fields = type === 'email' ?
|
|
['email_validated', 'email_activation_code'] :
|
|
['phone_validated', 'phone_activation_code'];
|
|
const sql = `UPDATE users set ${fields[0]} = 1, ${fields[1]} = NULL WHERE ${fields[1]} = ? AND user_sid = ?`;
|
|
const [r] = await promisePool.execute(sql, [code, user_sid]);
|
|
logger.debug({r}, 'Result from validating code');
|
|
debug({r}, 'Result from validating code');
|
|
|
|
if (activateAccount) {
|
|
await promisePool.execute('UPDATE accounts SET is_active=1 WHERE account_sid = ?', [account_sid]);
|
|
}
|
|
else if (deactivateOldUsers) {
|
|
const [r] = await promisePool.execute('DELETE FROM users WHERE account_sid = ? AND user_sid <> ?',
|
|
[account_sid, user_sid]);
|
|
logger.debug({r}, 'Result from deleting old/replaced users');
|
|
}
|
|
|
|
if (1 === r.affectedRows) return res.sendStatus(204);
|
|
throw new DbErrorBadRequest('invalid user or activation code');
|
|
} catch (err) {
|
|
sysError(logger, res, err);
|
|
}
|
|
});
|
|
|
|
|
|
module.exports = router;
|