Feat: password settings for account (#65)

* feat: password settings for account

* feat: password settings for account

* fix: review comments

* fix: review comments

* fix: review comments

* return empty json

* fix: after review
This commit is contained in:
xquanluu
2022-10-04 15:13:57 +07:00
committed by GitHub
parent c04cf65f17
commit b46604fc0d
6 changed files with 186 additions and 1 deletions

View File

@@ -0,0 +1,70 @@
const {promisePool} = require('../db');
class PasswordSettings {
/**
* Retrieve object from database
*/
static async retrieve() {
const [r] = await promisePool.execute(`SELECT * FROM ${this.table}`);
return r;
}
/**
* Update object into the database
*/
static async update(obj) {
let sql = `UPDATE ${this.table} SET `;
const values = [];
const keys = Object.keys(obj);
this.fields.forEach(({name}) => {
if (keys.includes(name)) {
sql = sql + `${name} = ?,`;
values.push(obj[name]);
}
});
if (values.length) {
sql = sql.slice(0, -1);
await promisePool.execute(sql, values);
}
}
/**
* insert object into the database
*/
static async make(obj) {
let params = '', marks = '';
const values = [];
const keys = Object.keys(obj);
this.fields.forEach(({name}) => {
if (keys.includes(name)) {
params = params + `${name},`;
marks = marks + '?,';
values.push(obj[name]);
}
});
if (values.length) {
params = `(${params.slice(0, -1)})`;
marks = `values(${marks.slice(0, -1)})`;
return await promisePool.execute(`INSERT into ${this.table} ${params} ${marks}`, values);
}
}
}
PasswordSettings.table = 'password_settings';
PasswordSettings.fields = [
{
name: 'min_password_length',
type: 'number'
},
{
name: 'require_digit',
type: 'number'
},
{
name: 'require_special_character',
type: 'number'
}
];
module.exports = PasswordSettings;

View File

@@ -44,6 +44,7 @@ api.use('/Subscriptions', require('./subscriptions'));
api.use('/Invoices', require('./invoices'));
api.use('/InviteCodes', require('./invite-codes'));
api.use('/PredefinedCarriers', require('./predefined-carriers'));
api.use('/PasswordSettings', isAdminScope, require('./password-settings'));
// messaging
api.use('/Smpps', require('./smpps')); // our smpp server info

View File

@@ -0,0 +1,42 @@
const router = require('express').Router();
const sysError = require('../error');
const PasswordSettings = require('../../models/password-settings');
const { DbErrorBadRequest } = require('../../utils/errors');
const validate = (obj) => {
if (obj.min_password_length && (
obj.min_password_length < 8 ||
obj.min_password_length > 20
)) {
throw new DbErrorBadRequest('invalid min_password_length property: should be between 8-20');
}
};
router.post('/', async(req, res) => {
const logger = req.app.locals.logger;
try {
validate(req.body);
const [existing] = (await PasswordSettings.retrieve() || []);
if (existing) {
await PasswordSettings.update(req.body);
} else {
await PasswordSettings.make(req.body);
}
res.status(201).json({});
}
catch (err) {
sysError(logger, res, err);
}
});
router.get('/', async(req, res) => {
const logger = req.app.locals.logger;
try {
const [results] = (await PasswordSettings.retrieve() || []);
return res.status(200).json(results || {min_password_length: 8});
}
catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;

View File

@@ -232,7 +232,7 @@ test('account tests', async(t) => {
auth: authAdmin,
json: true,
});
//console.log(result);
// console.log(result);
t.ok(result.length === 1 && result[0].quantity === 205, 'successfully queried account limits by category');
/* delete call session limits for a service provider */

View File

@@ -15,4 +15,5 @@ require('./recent-calls');
require('./webapp_tests');
// require('./homer');
require('./call-test');
require('./password-settings');
require('./docker_stop');

71
test/password-settings.js Normal file
View File

@@ -0,0 +1,71 @@
const test = require('tape') ;
const ADMIN_TOKEN = '38700987-c7a4-4685-a5bb-af378f9734de';
const authAdmin = {bearer: ADMIN_TOKEN};
const request = require('request-promise-native').defaults({
baseUrl: 'http://127.0.0.1:3000/v1'
});
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
test('password settings tests', async(t) => {
/* Check Default Password Settings */
result = await request.get('/PasswordSettings', {
auth: authAdmin,
json: true,
});
t.ok(result.min_password_length == 8 &&
!result.require_digit &&
!result.require_special_character, "default password settings is correct!")
/* Post New Password settings*/
result = await request.post('/PasswordSettings', {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
body: {
min_password_length: 15,
require_digit: 1,
require_special_character: 1
}
});
t.ok(result.statusCode === 201, 'successfully added a password settings');
/* Check Password Settings*/
result = await request.get('/PasswordSettings', {
auth: authAdmin,
json: true,
});
t.ok(result.min_password_length === 15 &&
result.require_digit === 1 &&
result.require_special_character === 1, 'successfully queried password settings');
/* Update Password settings*/
result = await request.post('/PasswordSettings', {
auth: authAdmin,
json: true,
resolveWithFullResponse: true,
body: {
min_password_length: 10,
require_special_character: 0
}
});
t.ok(result.statusCode === 201, 'successfully updated a password settings');
/* Check Password Settings After update*/
result = await request.get('/PasswordSettings', {
auth: authAdmin,
json: true,
});
t.ok(result.min_password_length === 10 &&
result.require_digit === 1 &&
result.require_special_character === 0, 'successfully queried password settings after updated');
});