mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-07-05 03:31:56 +00:00
ed51d8b13f
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;
|