add reset password
This commit is contained in:
@@ -1,2 +1,4 @@
|
|||||||
|
NODE_ENV=development
|
||||||
|
PORT=8000
|
||||||
TOKEN_SECRET=cfe41fd581767805dddabab7e1ca15c8
|
TOKEN_SECRET=cfe41fd581767805dddabab7e1ca15c8
|
||||||
TOKEN_EXPIRES=1800s
|
TOKEN_EXPIRES=1800s
|
||||||
Regular → Executable
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"config": path.resolve('./src/server/config', 'config.json'),
|
||||||
|
"models-path": path.resolve('./src/server/models'),
|
||||||
|
"seeders-path": path.resolve('./src/server/seeders'),
|
||||||
|
"migrations-path": path.resolve('./src/server/migrations')
|
||||||
|
};
|
||||||
Regular → Executable
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM node:10.15.0-alpine
|
FROM node:12-alpine
|
||||||
EXPOSE 3000 9229
|
EXPOSE 3000 9229
|
||||||
|
|
||||||
WORKDIR /home/app
|
WORKDIR /home/app
|
||||||
|
|||||||
Executable
Executable
BIN
Binary file not shown.
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# docker-compose.override.yml
|
||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
env_file: .env
|
||||||
|
volumes:
|
||||||
|
- .:/home/app/
|
||||||
|
- /home/app/node_modules
|
||||||
Regular → Executable
+2
-2
@@ -3,8 +3,6 @@ version: "3"
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
build: .
|
build: .
|
||||||
volumes:
|
|
||||||
- ./:/home/app
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
ports:
|
ports:
|
||||||
@@ -13,6 +11,8 @@ services:
|
|||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:12.0-alpine
|
image: postgres:12.0-alpine
|
||||||
|
volumes:
|
||||||
|
- ./database:/var/lib/postgresql
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: savvy
|
POSTGRES_USER: savvy
|
||||||
POSTGRES_PASSWORD: savvy001!
|
POSTGRES_PASSWORD: savvy001!
|
||||||
|
|||||||
Generated
-9353
File diff suppressed because it is too large
Load Diff
Regular → Executable
+14
-8
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "floatapi",
|
"name": "floatpapi",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start:dev": "./node_modules/.bin/nodemon app.js",
|
"start:dev": "./node_modules/.bin/nodemon ./src/bin/www -w app.js -w src/server",
|
||||||
"dev-test": "nodemon -x 'npm test'",
|
"dev-test": "nodemon -x 'npm test'",
|
||||||
"test": "mocha --timeout 1500"
|
"test": "mocha --timeout 1500"
|
||||||
},
|
},
|
||||||
@@ -13,24 +13,30 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.0.1",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-validator": "^6.14.0",
|
"express-validator": "^6.14.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"morgan": "1.9.1",
|
"morgan": "1.9.1",
|
||||||
|
"node-gyp": "^9.0.0",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
"nodemon": "^2.0.15",
|
"nodemon": "^2.0.15",
|
||||||
"pg": "7.12.1",
|
"pg": "^7.12.1",
|
||||||
"pg-hstore": "2.3.3",
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "5.19.6"
|
"pg-promise": "^10.11.1",
|
||||||
|
"postgres": "^1.0.2",
|
||||||
|
"sequelize": "^6.17.0",
|
||||||
|
"sequelize-cli": "^6.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"chai-http": "4.3.0",
|
"chai-http": "4.3.0",
|
||||||
"eslint": "6.5.1",
|
"eslint": "^8.10.0",
|
||||||
"eslint-config-airbnb": "18.0.1",
|
"eslint-config-airbnb": "^18.2.1",
|
||||||
"eslint-plugin-import": "2.18.2",
|
"eslint-plugin-import": "2.18.2",
|
||||||
"eslint-plugin-jsx-a11y": "6.2.3",
|
"eslint-plugin-jsx-a11y": "6.2.3",
|
||||||
"eslint-plugin-react": "7.16.0",
|
"eslint-plugin-react": "7.16.0",
|
||||||
"mocha": "6.2.1"
|
"mocha": "^6.2.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -3,8 +3,8 @@
|
|||||||
if [ "$NODE_ENV" == "production" ] ; then
|
if [ "$NODE_ENV" == "production" ] ; then
|
||||||
npm run start
|
npm run start
|
||||||
else
|
else
|
||||||
npx sequelize db:migrate
|
#npx sequelize db:migrate
|
||||||
npx sequelize db:seed:all
|
#npx sequelize db:seed:all
|
||||||
npm run test
|
#npm run test
|
||||||
npm run start:dev
|
npm run start:dev
|
||||||
fi
|
fi
|
||||||
|
|||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"extends": "airbnb",
|
||||||
|
"installedESLint": true,
|
||||||
|
"plugins": ["react"]
|
||||||
|
}
|
||||||
Regular → Executable
+8
-2
@@ -7,10 +7,16 @@ app.use(logger("dev"));
|
|||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({ extended: false }));
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
|
||||||
require("./src/server/routes")(app);
|
require("./server/routes")(app);
|
||||||
|
app.get("/api", (req, res) =>
|
||||||
|
res.status(200).send({
|
||||||
|
message: "Welcome to Float API"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
app.get("*", (req, res) =>
|
app.get("*", (req, res) =>
|
||||||
res.status(200).send({
|
res.status(200).send({
|
||||||
message: "Welcome to the beginning of nothingness."
|
message: "Welcome to Float Mobility."
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
+54
-61
@@ -1,13 +1,11 @@
|
|||||||
var Sequelize = require('sequelize');
|
var Sequelize = require('sequelize');
|
||||||
const nodemailer = require('nodemailer');
|
const nodemailer = require('nodemailer');
|
||||||
const { body, validationResult } = require('express-validator');
|
const { body, validationResult } = require('express-validator');
|
||||||
|
const memberServices = require("../services").member;
|
||||||
const member = require("../models").member;
|
|
||||||
const memberServices = require("../services").members;
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
validate(method) {
|
validate(method) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case 'createUser':
|
case 'register':
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
body('username', 'userName doesn\'t exists').exists(),
|
body('username', 'userName doesn\'t exists').exists(),
|
||||||
@@ -23,14 +21,17 @@ module.exports = {
|
|||||||
console.log(errors)
|
console.log(errors)
|
||||||
return res.status(400).json({ errors: errors.array() });
|
return res.status(400).json({ errors: errors.array() });
|
||||||
}
|
}
|
||||||
|
|
||||||
return memberServices.create(req)
|
return memberServices.create(req)
|
||||||
.then(member => res.status(200).send("Register successfully"))
|
.then(member => {
|
||||||
.catch(error => res.status(400).send(error.errors));
|
res.status(200).send("Register succesfully")
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
res.status(400).send(error.errors)
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async login(req, res) {
|
login(req, res) {
|
||||||
return memberServices.login(req)
|
memberServices.login(req)
|
||||||
.then(accessToken => res.status(200).send(accessToken))
|
.then(accessToken => res.status(200).send(accessToken))
|
||||||
.catch(error => res.status(400).send(error.errors));
|
.catch(error => res.status(400).send(error.errors));
|
||||||
},
|
},
|
||||||
@@ -41,44 +42,41 @@ module.exports = {
|
|||||||
.catch(error => res.status(400).send(error.errors));
|
.catch(error => res.status(400).send(error.errors));
|
||||||
},
|
},
|
||||||
|
|
||||||
async forgotPassword(req, res) {
|
forgotPassword(req, res) {
|
||||||
try {
|
memberServices.forgotPassword(req)
|
||||||
const email = req.body.email;
|
.then(result => {
|
||||||
const user = await member.findOne({
|
console.log(result)
|
||||||
where: { username: email }
|
})
|
||||||
});
|
.catch(error => res.status(400).send(error.errors));
|
||||||
if (user) {
|
|
||||||
return res.status(200).send('Please check email');
|
|
||||||
} else {
|
|
||||||
res.send("Email doen't exist");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
res.status(500).send("Internal Server error Occured");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async resetPassword(req, res) {
|
resetPassword(req, res) {
|
||||||
const email = req.body.email;
|
memberServices.resetPassword(req)
|
||||||
const user = await member.findOne({
|
.then(result => {
|
||||||
where: { username: email }
|
res.status(200).send(result)
|
||||||
});
|
})
|
||||||
const salt = await bcrypt.genSaltSync(10);
|
.catch(error => res.status(400).send(error.errors));
|
||||||
const password = bcrypt.hashSync(req.body.password, salt);
|
|
||||||
user.password = password;
|
|
||||||
user.save();
|
|
||||||
res.status(200).send(user.email);
|
|
||||||
return member
|
|
||||||
.update({
|
|
||||||
password: password
|
|
||||||
}, { returning: true, where: { id: user.id } })
|
|
||||||
.then(([rowsUpdate, [updatedRow]]) => res.status(200).send(updatedRow))
|
|
||||||
.catch(error => res.status(400).send(error));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
update(req, res) {
|
confirmResetPassword(req, res) {
|
||||||
return member
|
memberServices.confirmResetPassword(req)
|
||||||
.update({
|
.then(result => {
|
||||||
|
res.status(200).send(result)
|
||||||
|
})
|
||||||
|
.catch(error => res.status(400).send(error.errors));
|
||||||
|
},
|
||||||
|
|
||||||
|
completeResetPassword(req, res) {
|
||||||
|
memberServices.completeResetPassword(req)
|
||||||
|
.then(result => {
|
||||||
|
res.status(200).send(result)
|
||||||
|
})
|
||||||
|
.catch(error => res.status(400).send(error.errors));
|
||||||
|
},
|
||||||
|
|
||||||
|
updateProfile(req, res) {
|
||||||
|
return memberServices
|
||||||
|
.updateProfile({
|
||||||
name: req.body.name,
|
name: req.body.name,
|
||||||
size: req.body.size,
|
size: req.body.size,
|
||||||
price: req.body.price,
|
price: req.body.price,
|
||||||
@@ -88,25 +86,20 @@ module.exports = {
|
|||||||
.catch(error => res.status(400).send(error));
|
.catch(error => res.status(400).send(error));
|
||||||
},
|
},
|
||||||
|
|
||||||
delete(req, res) {
|
updatePassword(req, res) {
|
||||||
return member
|
return memberServices
|
||||||
.destroy({
|
.updatePassword({
|
||||||
where: {
|
name: req.body.name,
|
||||||
id: req.params.id
|
size: req.body.size,
|
||||||
}
|
price: req.body.price,
|
||||||
})
|
status: req.body.status
|
||||||
.then(rowDeleted => {
|
}, { returning: true, where: { id: req.params.id } })
|
||||||
if (rowDeleted !== 1) {
|
.then(([rowsUpdate, [updatedRow]]) => res.status(200).send(updatedRow))
|
||||||
throw ({
|
|
||||||
"name": "ValidationError",
|
|
||||||
"errors": [{
|
|
||||||
message: 'Item not found'
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return res.status(200).json({ message: "Deleted successfully" });
|
|
||||||
})
|
|
||||||
.catch(error => res.status(400).send(error));
|
.catch(error => res.status(400).send(error));
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivate(req, res) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
const jwt = require("jsonwebtoken");
|
||||||
|
|
||||||
|
const config = process.env;
|
||||||
|
|
||||||
|
const verifyToken = (req, res, next) => {
|
||||||
|
const bearToken = req.headers["authorization"];
|
||||||
|
if (!bearToken) {
|
||||||
|
return res.status(403).send("A token is required for authentication");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const token = bearToken.split(' ');
|
||||||
|
const decoded = jwt.verify(token[1], process.env.TOKEN_SECRET);
|
||||||
|
req.user = decoded;
|
||||||
|
} catch (err) {
|
||||||
|
return res.status(401).send("Invalid Token");
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = verifyToken;
|
||||||
Regular → Executable
@@ -1,33 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
module.exports = {
|
|
||||||
up: (queryInterface, Sequelize) => {
|
|
||||||
return queryInterface.createTable('orderItems', {
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: true,
|
|
||||||
primaryKey: true,
|
|
||||||
type: Sequelize.INTEGER
|
|
||||||
},
|
|
||||||
orderId: {
|
|
||||||
type: Sequelize.INTEGER
|
|
||||||
},
|
|
||||||
itemId: {
|
|
||||||
type: Sequelize.INTEGER
|
|
||||||
},
|
|
||||||
quantity: {
|
|
||||||
type: Sequelize.INTEGER
|
|
||||||
},
|
|
||||||
createdAt: {
|
|
||||||
allowNull: false,
|
|
||||||
type: Sequelize.DATE
|
|
||||||
},
|
|
||||||
updatedAt: {
|
|
||||||
allowNull: false,
|
|
||||||
type: Sequelize.DATE
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
down: (queryInterface, Sequelize) => {
|
|
||||||
return queryInterface.dropTable('orderItems');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Executable
+44
@@ -0,0 +1,44 @@
|
|||||||
|
'use strict';
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const ResetPassword = sequelize.define('ResetPassword', {
|
||||||
|
username: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
member_id: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
reset_pin: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
reset_key: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
expired: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
|
||||||
|
tableName: 'resetpassword',
|
||||||
|
// don't forget to enable timestamps!
|
||||||
|
timestamps: true,
|
||||||
|
|
||||||
|
// I don't want createdAt
|
||||||
|
createdAt: "created",
|
||||||
|
|
||||||
|
// I want updatedAt to actually be called updateTimestamp
|
||||||
|
updatedAt: false
|
||||||
|
});
|
||||||
|
ResetPassword.associate = function (models) {
|
||||||
|
// associations
|
||||||
|
};
|
||||||
|
return ResetPassword;
|
||||||
|
};
|
||||||
Regular → Executable
+12
-3
@@ -7,21 +7,30 @@ const basename = path.basename(__filename);
|
|||||||
const env = process.env.NODE_ENV || 'development';
|
const env = process.env.NODE_ENV || 'development';
|
||||||
const config = require(__dirname + '/../config/config.json')[env];
|
const config = require(__dirname + '/../config/config.json')[env];
|
||||||
const db = {};
|
const db = {};
|
||||||
|
const DataTypes = Sequelize.DataTypes
|
||||||
let sequelize;
|
let sequelize;
|
||||||
if (config.use_env_variable) {
|
if (config.use_env_variable) {
|
||||||
sequelize = new Sequelize(process.env[config.use_env_variable], config);
|
sequelize = new Sequelize(process.env[config.use_env_variable], config);
|
||||||
} else {
|
} else {
|
||||||
sequelize = new Sequelize(config.database, config.username, config.password, config);
|
sequelize = new Sequelize(config.database, config.username, config.password, config);
|
||||||
}
|
}
|
||||||
|
sequelize
|
||||||
|
.authenticate()
|
||||||
|
.then(() => {
|
||||||
|
console.info('INFO - Database connected.')
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('ERROR - Unable to connect to the database:', err)
|
||||||
|
})
|
||||||
|
//sequelize.sync({ force: false })
|
||||||
fs
|
fs
|
||||||
.readdirSync(__dirname)
|
.readdirSync(__dirname)
|
||||||
.filter(file => {
|
.filter(file => {
|
||||||
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
|
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
|
||||||
})
|
})
|
||||||
.forEach(file => {
|
.forEach(file => {
|
||||||
const model = sequelize['import'](path.join(__dirname, file));
|
//const model = sequelize['import'](path.join(__dirname, file));
|
||||||
|
const model = require(path.join(__dirname, file)) (sequelize,DataTypes);
|
||||||
db[model.name] = model;
|
db[model.name] = model;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Regular → Executable
+49
-22
@@ -1,11 +1,24 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
module.exports = (sequelize, DataTypes) => {
|
module.exports = (sequelize, DataTypes) => {
|
||||||
const member = sequelize.define('member', {
|
const Member = sequelize.define('Member', {
|
||||||
|
username: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
unique:{
|
||||||
|
args: true, msg: "username already exists"
|
||||||
|
},
|
||||||
|
validate: {
|
||||||
|
len: {
|
||||||
|
args: [3, 50],
|
||||||
|
msg: 'Your username may be 5 to 50 characters only.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
email: {
|
email: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
unique: {
|
unique:{
|
||||||
msg: 'This email is already taken.'
|
args: true, msg: "email already exists"
|
||||||
},
|
},
|
||||||
validate: {
|
validate: {
|
||||||
isEmail: {
|
isEmail: {
|
||||||
@@ -13,25 +26,12 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
username: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
allowNull: false,
|
|
||||||
unique: {
|
|
||||||
msg: 'This username is already taken.'
|
|
||||||
},
|
|
||||||
validate: {
|
|
||||||
len: {
|
|
||||||
args: [5, 50],
|
|
||||||
msg: 'Your username may be 5 to 50 characters only.'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
password: {
|
password: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
validate: {
|
validate: {
|
||||||
len: {
|
len: {
|
||||||
args: [5, 72],
|
args: [6, 72],
|
||||||
msg: 'Your password may be 5 to 72 characters only.'
|
msg: 'Your password may be 5 to 72 characters only.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
validate: {
|
validate: {
|
||||||
len: {
|
len: {
|
||||||
args: [5, 50],
|
args: [2, 50],
|
||||||
msg: 'Your first name may be 5 to 50 characters only.'
|
msg: 'Your first name may be 5 to 50 characters only.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,14 +51,41 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
validate: {
|
validate: {
|
||||||
len: {
|
len: {
|
||||||
args: [5, 50],
|
args: [2, 50],
|
||||||
msg: 'Your last name may be 5 to 50 characters only.'
|
msg: 'Your last name may be 5 to 50 characters only.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, {});
|
phone: {
|
||||||
member.associate = function (models) {
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
validate: {
|
||||||
|
len: {
|
||||||
|
args: [2, 50],
|
||||||
|
msg: 'Your last name may be 5 to 50 characters only.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
|
||||||
|
tableName: 'members',
|
||||||
|
// don't forget to enable timestamps!
|
||||||
|
timestamps: true,
|
||||||
|
|
||||||
|
// I don't want createdAt
|
||||||
|
createdAt: "added",
|
||||||
|
|
||||||
|
// I want updatedAt to actually be called updateTimestamp
|
||||||
|
updatedAt: 'updated',
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
unique: true,
|
||||||
|
fields: ["username","email"] // Whatever other field you need to make unique
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
Member.associate = function (models) {
|
||||||
// associations
|
// associations
|
||||||
};
|
};
|
||||||
return member;
|
return Member;
|
||||||
};
|
};
|
||||||
Regular → Executable
+8
-12
@@ -1,17 +1,13 @@
|
|||||||
const memberController = require("../controllers").member;
|
const memberController = require("../controllers").member;
|
||||||
|
const auth = require("../middleware/auth");
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
app.get("/api", (req, res) =>
|
app.post("/api/v1/user/register", memberController.validate('register'), memberController.register);
|
||||||
res.status(200).send({
|
app.post("/api/v1/user/login", memberController.login);
|
||||||
message: "Welcome to the Pizza API!"
|
app.post("/api/v1/user/forgot-password", memberController.forgotPassword);
|
||||||
})
|
app.post("/api/v1/user/reset-password", memberController.resetPassword);
|
||||||
);
|
app.post("/api/v1/user/confirm-reset-password", memberController.confirmResetPassword);
|
||||||
|
app.post("/api/v1/user/complete-reset-password", memberController.completeResetPassword);
|
||||||
app.post("/api/v1/user/register", memberController.register);
|
app.get("/api/v1/user/profile", auth, memberController.profile);
|
||||||
app.put("/api/v1/user/login", memberController.login);
|
|
||||||
app.get("/api/v1/user/forgot-password", memberController.forgotPassword);
|
|
||||||
app.get("/api/v1/user/reset-password", memberController.resetPassword);
|
|
||||||
app.delete("/api/v1/user/profile", memberController.profile);
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Regular → Executable
Regular → Executable
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const member = require("./user/members");
|
const member = require("./user/member");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
member
|
member
|
||||||
|
|||||||
Executable
+233
@@ -0,0 +1,233 @@
|
|||||||
|
const jwt = require('jsonwebtoken');
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const Member = require("../../models").Member;
|
||||||
|
const resetPasswordService = require("./resetPassword");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async create(req) {
|
||||||
|
const { username, password, firstname, lastname, phone, email } = req.body;
|
||||||
|
const salt = bcrypt.genSaltSync(10);
|
||||||
|
const hashpassword = bcrypt.hashSync(password, salt);
|
||||||
|
const user = {
|
||||||
|
username: username,
|
||||||
|
password: hashpassword,
|
||||||
|
firstname: firstname,
|
||||||
|
lastname: lastname,
|
||||||
|
phone: phone,
|
||||||
|
email: email
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Member.create(user);
|
||||||
|
},
|
||||||
|
|
||||||
|
async login(req) {
|
||||||
|
try {
|
||||||
|
const user = await Member.findOne({
|
||||||
|
where: {
|
||||||
|
username: req.body.username,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
const cmp = await bcrypt.compare(req.body.password, user.password);
|
||||||
|
|
||||||
|
if (cmp) {
|
||||||
|
user.last_login = Date.now()
|
||||||
|
user.save()
|
||||||
|
const token = jwt.sign({
|
||||||
|
username: user.username
|
||||||
|
},
|
||||||
|
process.env.TOKEN_SECRET, { expiresIn: process.env.TOKEN_EXPIRES }
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
accessToken: token
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return "Wrong username or password.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Wrong username or password.";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(error)
|
||||||
|
return "Internal Server error Occured";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async forgotPassword(req) {
|
||||||
|
try {
|
||||||
|
const user = await Member.findOne({
|
||||||
|
where: { username: req.body.username }
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
const cmp = await bcrypt.compare(req.body.password, user.password);
|
||||||
|
|
||||||
|
if (cmp) {
|
||||||
|
user.last_login = Date.now()
|
||||||
|
user.save()
|
||||||
|
const token = jwt.sign({
|
||||||
|
username: user.username
|
||||||
|
},
|
||||||
|
process.env.TOKEN_SECRET, { expiresIn: process.env.TOKEN_EXPIRES }
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
accessToken: token
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return "Wrong username or password.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Wrong username or password.";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(error)
|
||||||
|
return "Internal Server error Occured";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async resetPassword(req) {
|
||||||
|
try {
|
||||||
|
const user = await Member.findOne({
|
||||||
|
where: {
|
||||||
|
email: req.body.email,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var date = new Date();
|
||||||
|
let reset_key = crypto.createHash('md5').update(date.toString()).digest("hex");
|
||||||
|
let reset_pin = Math.floor(100000 + Math.random() * 900000)
|
||||||
|
|
||||||
|
let expired = date.setDate(date.getDate() + 7);
|
||||||
|
var status = 3;
|
||||||
|
if (user) {
|
||||||
|
resetPasswordService.updateStatusExpired(user.id, 7);
|
||||||
|
status = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetPasswordData = {
|
||||||
|
username: user.username,
|
||||||
|
member_id: user.id,
|
||||||
|
reset_pin: reset_pin,
|
||||||
|
reset_key: reset_key,
|
||||||
|
expired: expired,
|
||||||
|
status: status
|
||||||
|
}
|
||||||
|
|
||||||
|
return await resetPasswordService.create(resetPasswordData);
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(error)
|
||||||
|
return "Invalid email";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirmResetPassword(req) {
|
||||||
|
try {
|
||||||
|
const user = await Member.findOne({
|
||||||
|
where: {
|
||||||
|
email: req.body.email,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
const exist = await resetPasswordService.getByCondition({
|
||||||
|
member_id: user.id,
|
||||||
|
status: 0,
|
||||||
|
reset_pin: req.body.resetPin.toString()
|
||||||
|
});
|
||||||
|
if (exist) {
|
||||||
|
resetPasswordService.updateStatusById(exist.id, 1);
|
||||||
|
return {
|
||||||
|
resetKey: exist.reset_key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "invalid PIN";
|
||||||
|
} else {
|
||||||
|
return "email is not existed";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(error)
|
||||||
|
return "Invalid email";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async completeResetPassword(req) {
|
||||||
|
try {
|
||||||
|
const user = await Member.findOne({
|
||||||
|
where: {
|
||||||
|
email: req.body.email,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (user) {
|
||||||
|
const exist = await resetPasswordService.getByCondition({
|
||||||
|
member_id: user.id,
|
||||||
|
status: 1,
|
||||||
|
reset_key: req.body.resetKey.toString()
|
||||||
|
});
|
||||||
|
if (exist) {
|
||||||
|
const salt = bcrypt.genSaltSync(10);
|
||||||
|
const hashpassword = bcrypt.hashSync(req.body.newPassword, salt);
|
||||||
|
Member
|
||||||
|
.update(
|
||||||
|
{
|
||||||
|
password: hashpassword
|
||||||
|
},
|
||||||
|
{
|
||||||
|
returning: true,
|
||||||
|
where: {
|
||||||
|
id: user.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(([rowsUpdate, [updatedRow]]) => {
|
||||||
|
console.log(rowsUpdate)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
|
||||||
|
resetPasswordService.updateStatusById(exist.id, 5);
|
||||||
|
return "Ok"
|
||||||
|
}
|
||||||
|
return "invalid PIN";
|
||||||
|
} else {
|
||||||
|
return "email is not existed";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.debug(error)
|
||||||
|
return "Invalid email";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async getProfile(req) {
|
||||||
|
const username = req.user.username;
|
||||||
|
return await Member.findOne({
|
||||||
|
where: { username: username },
|
||||||
|
attributes: ['username', 'email', 'phone', 'firstname', 'lastname']
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async deactivateAccount(req) {
|
||||||
|
return Member
|
||||||
|
.destroy({
|
||||||
|
where: {
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(rowDeleted => {
|
||||||
|
if (rowDeleted !== 1) {
|
||||||
|
throw ({
|
||||||
|
"name": "ValidationError",
|
||||||
|
"errors": [{
|
||||||
|
message: 'Item not found'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res.status(200).json({ message: "Deleted successfully" });
|
||||||
|
})
|
||||||
|
.catch(error => res.status(400).send(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
const member = require("../../models").member;
|
|
||||||
|
|
||||||
const jwt = require('jsonwebtoken');
|
|
||||||
var bcrypt = require('bcrypt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
async create(req) {
|
|
||||||
console.log(req.body)
|
|
||||||
const { username, password, firstname, lastname, phone, email } = req.body;
|
|
||||||
const user = {
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
firstname: firstname,
|
|
||||||
lastname: lastname,
|
|
||||||
phone: phone,
|
|
||||||
email: email
|
|
||||||
}
|
|
||||||
return await member.create(user);
|
|
||||||
},
|
|
||||||
async login(req) {
|
|
||||||
try {
|
|
||||||
const user = await member.findOne({
|
|
||||||
where: { username: req.body.username }
|
|
||||||
});
|
|
||||||
if (user) {
|
|
||||||
const cmp = await bcrypt.compare(req.body.password, user.password);
|
|
||||||
|
|
||||||
if (cmp) {
|
|
||||||
user.last_login = Date.now()
|
|
||||||
user.save()
|
|
||||||
console.log(user)
|
|
||||||
const token = jwt.sign({
|
|
||||||
username: user.username
|
|
||||||
},
|
|
||||||
process.env.TOKEN_SECRET, { expiresIn: process.env.TOKEN_EXPIRES }
|
|
||||||
);
|
|
||||||
console.log(token)
|
|
||||||
return {
|
|
||||||
accessToken: token
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return "Wrong username or password.";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "Wrong username or password.";
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return "Internal Server error Occured";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getProfile(req) {
|
|
||||||
const username = req.user.username;
|
|
||||||
return await member.findOne({
|
|
||||||
where: { username: username },
|
|
||||||
attributes: ['username', 'email', 'phone', 'firstname', 'lastname']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
Executable
+67
@@ -0,0 +1,67 @@
|
|||||||
|
const ResetPassword = require("../../models").ResetPassword;
|
||||||
|
const { Op } = require('sequelize');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async create(data) {
|
||||||
|
return await ResetPassword.create(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateStatusExpired(member_id, status) {
|
||||||
|
return ResetPassword
|
||||||
|
.update(
|
||||||
|
{
|
||||||
|
status: status
|
||||||
|
},
|
||||||
|
{
|
||||||
|
returning: true,
|
||||||
|
where: {
|
||||||
|
member_id: member_id,
|
||||||
|
status: {
|
||||||
|
[Op.notIn]: [3, 5]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(([rowsUpdate, [updatedRow]]) => {
|
||||||
|
console.log(rowsUpdate)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async getByStatus(status) {
|
||||||
|
return await ResetPassword.findOne({
|
||||||
|
where: { status: status },
|
||||||
|
attributes: ['member_id']
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateStatusById(id, status) {
|
||||||
|
return ResetPassword
|
||||||
|
.update(
|
||||||
|
{
|
||||||
|
status: status
|
||||||
|
},
|
||||||
|
{
|
||||||
|
returning: true,
|
||||||
|
where: {
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(([rowsUpdate, [updatedRow]]) => {
|
||||||
|
console.log(rowsUpdate)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async getByCondition(condition) {
|
||||||
|
return await ResetPassword.findOne({
|
||||||
|
where: condition,
|
||||||
|
attributes: ['id','member_id','reset_key']
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
Regular → Executable
Reference in New Issue
Block a user