added passreset and mail helper
This commit is contained in:
parent
1a3fdc567d
commit
4e68267bfd
@ -141,14 +141,17 @@ Email:
|
||||
email:
|
||||
type: string
|
||||
example: john.doe@bosch.com
|
||||
User:
|
||||
allOf:
|
||||
- $ref: 'oas.yaml#/components/schemas/_Id'
|
||||
- $ref: 'oas.yaml#/components/schemas/Email'
|
||||
UserName:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: johndoe
|
||||
User:
|
||||
allOf:
|
||||
- $ref: 'oas.yaml#/components/schemas/_Id'
|
||||
- $ref: 'oas.yaml#/components/schemas/UserName'
|
||||
- $ref: 'oas.yaml#/components/schemas/Email'
|
||||
properties:
|
||||
pass:
|
||||
type: string
|
||||
writeOnly: true
|
||||
|
@ -171,11 +171,13 @@
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: 'oas.yaml#/components/schemas/Email'
|
||||
allOf:
|
||||
- $ref: 'oas.yaml#/components/schemas/UserName'
|
||||
- $ref: 'oas.yaml#/components/schemas/Email'
|
||||
responses:
|
||||
200:
|
||||
$ref: 'oas.yaml#/components/responses/Ok'
|
||||
401:
|
||||
$ref: 'oas.yaml#/components/responses/401'
|
||||
404:
|
||||
$ref: 'oas.yaml#/components/responses/404'
|
||||
500:
|
||||
$ref: 'oas.yaml#/components/responses/500'
|
26
package-lock.json
generated
26
package-lock.json
generated
@ -203,6 +203,14 @@
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
@ -848,6 +856,24 @@
|
||||
"is-buffer": "~2.0.3"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||
|
@ -17,6 +17,7 @@
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^13.1.6",
|
||||
"axios": "^0.19.2",
|
||||
"basic-auth": "^2.0.1",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"body-parser": "^1.19.0",
|
||||
|
@ -51,6 +51,7 @@ export default class db {
|
||||
});
|
||||
});
|
||||
mongoose.connection.once('open', () => {
|
||||
mongoose.set('useFindAndModify', false);
|
||||
console.log(process.env.NODE_ENV === 'test' ? '' : `Connected to ${connectionString}`);
|
||||
this.state.db = mongoose.connection;
|
||||
done();
|
||||
|
64
src/helpers/mail.ts
Normal file
64
src/helpers/mail.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import axios from 'axios';
|
||||
|
||||
// sends an email
|
||||
|
||||
export default (mailAddress, subject, content, f) => { // callback, executed empty or with error
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const mailService = JSON.parse(process.env.VCAP_SERVICES).Mail[0];
|
||||
axios({
|
||||
method: 'post',
|
||||
url: mailService.credentials.uri + '/email',
|
||||
auth: {username: mailService.credentials.username, password: mailService.credentials.password},
|
||||
data: {
|
||||
recipients: [{to: mailAddress}],
|
||||
subject: {content: subject},
|
||||
body: {
|
||||
content: content,
|
||||
contentType: "text/html"
|
||||
},
|
||||
from: {
|
||||
eMail: "dfop@bosch-iot.com",
|
||||
password: "PlasticsOfFingerprintDigital"
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
f();
|
||||
})
|
||||
.catch((err) => {
|
||||
f(err);
|
||||
});
|
||||
}
|
||||
else if (process.env.NODE_ENV === 'test') {
|
||||
console.log('Sending mail to ' + mailAddress + ': -- ' + subject + ' -- ' + content);
|
||||
f();
|
||||
}
|
||||
else { // dev
|
||||
axios({
|
||||
method: 'get',
|
||||
url: 'https://digital-fingerprint-of-plastics-mail-test.apps.de1.bosch-iot-cloud.com/api',
|
||||
data: {
|
||||
method: 'post',
|
||||
url: '/email',
|
||||
data: {
|
||||
recipients: [{to: mailAddress}],
|
||||
subject: {content: subject},
|
||||
body: {
|
||||
content: content,
|
||||
contentType: "text/html"
|
||||
},
|
||||
from: {
|
||||
eMail: "dfop-test@bosch-iot.com",
|
||||
password: "PlasticsOfFingerprintDigital"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
f();
|
||||
})
|
||||
.catch((err) => {
|
||||
f(err);
|
||||
});
|
||||
}
|
||||
}
|
@ -105,4 +105,96 @@ describe('/user/new', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
describe('/user/passreset', () => {
|
||||
let server;
|
||||
|
||||
before(done => {
|
||||
process.env.port = '2999';
|
||||
process.env.NODE_ENV = 'test';
|
||||
db.connect('test', done);
|
||||
});
|
||||
beforeEach(done => {
|
||||
delete require.cache[require.resolve('../index')]; // prevent loading from cache
|
||||
server = require('../index');
|
||||
db.drop(err => { // reset database
|
||||
if (err) return done(err);
|
||||
db.loadJson(require('../test/db.json'), done);
|
||||
});
|
||||
});
|
||||
afterEach(done => {
|
||||
server.close(done);
|
||||
});
|
||||
it('returns the ok response', done => {
|
||||
supertest(server)
|
||||
.post('/user/passreset')
|
||||
.send({
|
||||
email: 'jane.doe@bosch.com',
|
||||
name: 'janedoe'
|
||||
})
|
||||
.expect('Content-type', /json/)
|
||||
.expect(200)
|
||||
.end((err, res) => {
|
||||
if (err) done(err);
|
||||
should(res.body).be.eql({status: 'OK'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('returns 404 for wrong username/email combo', done => {
|
||||
supertest(server)
|
||||
.post('/user/passreset')
|
||||
.send({
|
||||
email: 'jane.doe@bosch.com',
|
||||
name: 'admin'
|
||||
})
|
||||
.expect('Content-type', /json/)
|
||||
.expect(404)
|
||||
.end((err, res) => {
|
||||
if (err) done(err);
|
||||
should(res.body).be.eql({status: 'Not found'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('returns 404 for unknown username', done => {
|
||||
supertest(server)
|
||||
.post('/user/passreset')
|
||||
.send({
|
||||
email: 'jane.doe@bosch.com',
|
||||
name: 'admin'
|
||||
})
|
||||
.expect('Content-type', /json/)
|
||||
.expect(404)
|
||||
.end((err, res) => {
|
||||
if (err) done(err);
|
||||
should(res.body).be.eql({status: 'Not found'});
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('changes the user password', done => {
|
||||
UserModel.find({name: 'janedoe'}).lean().exec( 'find', (err, data) => {
|
||||
if (err) return done(err);
|
||||
const oldpass = data[0].pass;
|
||||
supertest(server)
|
||||
.post('/user/passreset')
|
||||
.send({
|
||||
email: 'jane.doe@bosch.com',
|
||||
name: 'janedoe'
|
||||
})
|
||||
.expect('Content-type', /json/)
|
||||
.expect(200)
|
||||
.end((err, res) => {
|
||||
if (err) done(err);
|
||||
should(res.body).be.eql({status: 'OK'});
|
||||
UserModel.find({name: 'janedoe'}).lean().exec( 'find', (err, data) => {
|
||||
if (err) return done(err);
|
||||
should(data[0].pass).not.eql(oldpass);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -3,6 +3,7 @@ import mongoose from 'mongoose';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import UserValidate from './validate/user';
|
||||
import UserModel from '../models/user';
|
||||
import mail from '../helpers/mail';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@ -11,7 +12,6 @@ router.get('/users', (req, res) => {
|
||||
});
|
||||
|
||||
router.post('/user/new', (req, res, next) => {
|
||||
console.log(req.authDetails);
|
||||
if (!req.auth(res, ['admin'], 'basic')) return;
|
||||
|
||||
// validate input
|
||||
@ -40,4 +40,27 @@ router.post('/user/new', (req, res, next) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/user/passreset', (req, res, next) => {
|
||||
// check if user/email combo exists
|
||||
UserModel.find({name: req.body.name, email: req.body.email}).lean().exec( 'find', (err, data) => {
|
||||
if (err) next(err);
|
||||
if (data.length === 1) { // it exists
|
||||
const newPass = Math.random().toString(36).substring(2);
|
||||
bcrypt.hash(newPass, 10, (err, hash) => { // password hashing
|
||||
if (err) next(err);
|
||||
UserModel.findOneAndUpdate({name: req.body.name, email: req.body.email}, {pass: hash}, err => {
|
||||
if (err) next(err);
|
||||
mail(data[0].email, 'Your new password for the DFOP database', 'Hi, <br><br> You requested to reset your password.<br>Your new password is:<br><br>' + newPass + '<br><br>If you did not request a password reset, talk to the sysadmin quickly!<br><br>Have a nice day.<br><br>The DFOP team', err => {
|
||||
if (err) next(err);
|
||||
res.json({status: 'OK'});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
res.status(404).json({status: 'Not found'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
Reference in New Issue
Block a user