├── helpers ├── runParallel.js ├── token.js ├── fileSystem.js ├── customeMessage.js ├── autoExpire.js ├── forgotTemplate.js └── emailTemplate.js ├── libs ├── jwt.js └── bcrypt.js ├── .eslintrc ├── routes ├── users.route │ ├── result.route.js │ ├── delete.route.js │ ├── results.route.js │ ├── update.route.js │ └── create.route.js ├── roles.route │ ├── result.route.js │ ├── results.route.js │ ├── update.route.js │ ├── delete.route.js │ └── create.route.js ├── credits.route │ ├── result.route.js │ ├── results.route.js │ ├── delete.route.js │ ├── create.route.js │ └── update.route.js ├── subjects.route │ ├── delete.route.js │ ├── result.route.js │ ├── results.route.js │ ├── create.route.js │ └── update.route.js ├── register.route │ ├── resend.route.js │ ├── forgot.route.js │ ├── reset.route.js │ ├── activation.route.js │ ├── login.route.js │ └── register.route.js └── defaults.route.js ├── configs └── Connection.js ├── models ├── Roles.model.js ├── ResetPass.model.js ├── Credits.model.js ├── Subjects.model.js └── Users.model.js ├── package.json ├── server.js ├── app.js ├── controllers ├── users.controller │ ├── result.controller.js │ ├── results.controller.js │ ├── delete.controller.js │ ├── update.controller.js │ └── create.controller.js ├── roles.controller │ ├── results.controller.js │ ├── result.controller.js │ ├── delete.controller.js │ ├── create.controller.js │ └── update.controller.js ├── subjects.controller │ ├── result.controller.js │ ├── results.controller.js │ ├── delete.controller.js │ ├── create.controller.js │ └── update.controller.js ├── credits.controller │ ├── results.controller.js │ ├── result.controller.js │ ├── delete.controller.js │ ├── create.controller.js │ └── update.controller.js └── register.controller │ ├── reset.controller.js │ ├── activation.controller.js │ ├── login.controller.js │ ├── forgot.controller.js │ ├── resend.controller.js │ └── register.controller.js ├── middlewares ├── authToken.js └── authRole.js ├── readme.md └── .gitignore /helpers/runParallel.js: -------------------------------------------------------------------------------- 1 | class Parallel { 2 | 3 | // function for run parallel route 4 | static run(data = []) { 5 | 6 | return data; 7 | } 8 | } 9 | 10 | module.exports = { Parallel }; -------------------------------------------------------------------------------- /libs/jwt.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | class Jwt { 3 | createToken(payload, options) { 4 | 5 | return jwt.sign(payload, process.env.SECRET_TOKEN, options); 6 | } 7 | } 8 | 9 | module.exports = { Jwt }; -------------------------------------------------------------------------------- /helpers/token.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto'); 2 | class TokenSecret { 3 | 4 | // function for generate automatic token for activation login 5 | static secretToken() { 6 | 7 | return crypto.randomBytes(35).toString('hex'); 8 | } 9 | } 10 | 11 | module.exports = { TokenSecret }; -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "semi":["error", "always"], 4 | "camelcase":"error", 5 | "comma-dangle":"off", 6 | "indent":["error", 2], 7 | "prefer-const": ["error", { 8 | "destructuring": "any", 9 | "ignoreReadBeforeAssign": false 10 | }] 11 | }, 12 | "extends": ["node/style-guide"] 13 | } -------------------------------------------------------------------------------- /routes/users.route/result.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultUserController } = require('../../controllers/users.controller/result.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/user/result/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultUserController(req, res).Controler(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/roles.route/result.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultRolesController } = require('../../controllers/roles.controller/result.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/role/result/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultRolesController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/roles.route/results.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultsRolesController } = require('../../controllers/roles.controller/results.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/role/results', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultsRolesController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/roles.route/update.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { UpdateRolesController } = require('../../controllers/roles.controller/update.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.put('/role/update/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new UpdateRolesController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/users.route/delete.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { DeleteUserController } = require('../../controllers/users.controller/delete.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.delete('/user/delete/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new DeleteUserController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/users.route/results.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultsUserController } = require('../../controllers/users.controller/results.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/user/results', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultsUserController(req, res).Controler(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/roles.route/delete.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { DeleteRolesController } = require('../../controllers/roles.controller/delete.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.delete('/role/delete/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new DeleteRolesController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/credits.route/result.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultCredistController } = require('../../controllers/credits.controller/result.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/credit/result/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultCredistController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/credits.route/results.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultsCredistController } = require('../../controllers/credits.controller/results.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/credit/results', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultsCredistController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/credits.route/delete.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { DeleteCreditsController } = require('../../controllers/credits.controller/delete.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.delete('/credit/delete/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new DeleteCreditsController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/subjects.route/delete.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { DeleteSubjectController } = require('../../controllers/subjects.controller/delete.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.delete('/subject/delete/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new DeleteSubjectController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/subjects.route/result.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultsSubjectController } = require('../../controllers/subjects.controller/result.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/subject/result/:id', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultsSubjectController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /routes/subjects.route/results.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { ResultsSubjectController } = require('../../controllers/subjects.controller/results.controller'); 4 | const AuthToken = require('../../middlewares/authToken'); 5 | const AuthRole = require('../../middlewares/authRole'); 6 | router.get('/subject/results', AuthToken, AuthRole, (req, res) => { 7 | 8 | return new ResultsSubjectController(req, res).Controller(); 9 | }); 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /configs/Connection.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | // class Connetion { 3 | // static MongooseConnect() { 4 | 5 | // const connection = mongoose.createConnection(process.env.MONGOO_URI, { useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true }); 6 | // return connection; 7 | // } 8 | // } 9 | 10 | const Connection = mongoose.createConnection(process.env.MONGOO_URI, { useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true }); 11 | module.exports = { Connection }; -------------------------------------------------------------------------------- /libs/bcrypt.js: -------------------------------------------------------------------------------- 1 | const bcryptjs = require('bcryptjs'); 2 | class EncryptPassword { 3 | 4 | // function for hash password 5 | static hashPassword(password, salt) { 6 | 7 | return bcryptjs.hashSync(password, salt); 8 | } 9 | 10 | // function for verification password 11 | static verifyPassword(password, hash, callback) { 12 | return bcryptjs.compare(password, hash, (err, success) => { 13 | 14 | return callback(err, success); 15 | 16 | }); 17 | } 18 | 19 | } 20 | 21 | module.exports = { EncryptPassword }; -------------------------------------------------------------------------------- /models/Roles.model.js: -------------------------------------------------------------------------------- 1 | const { Connection } = require('../configs/Connection'); 2 | const mongoose = require('mongoose'); 3 | const setSchema = new mongoose.Schema({ 4 | 5 | name: { 6 | 7 | type: String, 8 | trim: true, 9 | required: true, 10 | }, 11 | 12 | permission: { 13 | 14 | type: String, 15 | trim: true, 16 | required: true, 17 | }, 18 | 19 | create_at: { 20 | 21 | type: Date, 22 | default: null 23 | }, 24 | 25 | update_at: { 26 | 27 | type: Date, 28 | default: null 29 | } 30 | }); 31 | 32 | const roleSchema = Connection.model('roles', setSchema); 33 | 34 | module.exports = roleSchema; -------------------------------------------------------------------------------- /helpers/fileSystem.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | class FileSystem { 3 | constructor() { 4 | 5 | this.fs = fs; 6 | } 7 | 8 | // function for handling create file automatic 9 | createFile(data) { 10 | 11 | const { fs } = this; 12 | 13 | //create directory 14 | fs.mkdirSync('../../../dist', { recursive: true }); 15 | //create new file 16 | return fs.writeFileSync('../../../dist/data.txt', data, 'utf-8'); 17 | } 18 | 19 | // function for handling read file automatic 20 | readFile() { 21 | 22 | const { fs } = this; 23 | 24 | //read file 25 | return fs.readFileSync('../../dist/data.txt', 'utf-8'); 26 | } 27 | } 28 | 29 | module.exports = { FileSystem }; -------------------------------------------------------------------------------- /routes/register.route/resend.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { RefeshToken } = require('../../controllers/register.controller/resend.controller'); 6 | router.get('/resendtoken', (req, res) => { 7 | 8 | const { email } = req.body; 9 | 10 | const msg = new CustomeMessage(res); 11 | 12 | if (v.isEmpty(email)) { 13 | 14 | msg.success('success', 200, { 15 | 16 | response: { 17 | 18 | status: 'success', 19 | code: 200, 20 | method: req.method, 21 | message: 'Oops..field is required' 22 | } 23 | }); 24 | 25 | } else { 26 | 27 | return new RefeshToken(req, res).Controller(); 28 | } 29 | 30 | }); 31 | 32 | module.exports = router; -------------------------------------------------------------------------------- /routes/register.route/forgot.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { ForgotController } = require('../../controllers/register.controller/forgot.controller'); 6 | router.post('/forgotpassword', (req, res) => { 7 | 8 | const { email } = req.body; 9 | 10 | const msg = new CustomeMessage(res); 11 | 12 | if (v.isEmpty(email)) { 13 | 14 | msg.success('success', 200, { 15 | 16 | response: { 17 | 18 | status: 'success', 19 | code: res.statusCode, 20 | method: req.method, 21 | message: 'Oops..field is required' 22 | } 23 | }); 24 | 25 | } else { 26 | 27 | return new ForgotController(req, res).Controller(); 28 | } 29 | 30 | }); 31 | 32 | module.exports = router; -------------------------------------------------------------------------------- /helpers/customeMessage.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events'); 2 | const events = new EventEmitter; 3 | class CustomeMessage { 4 | constructor(res) { 5 | 6 | this.response = res; 7 | this.events = events; 8 | } 9 | 10 | // custome message for handling success 11 | async success(event, statusCode, message) { 12 | 13 | let { response, events } = this; 14 | events.once(event, () => { 15 | 16 | return response.status(statusCode).json(message); 17 | }); 18 | 19 | return await events.emit(event); 20 | } 21 | 22 | // custome message for handling error 23 | async error(event, statusCode, message) { 24 | 25 | let { response, events } = this; 26 | events.once(event, () => { 27 | 28 | return response.status(statusCode).json(message); 29 | }); 30 | 31 | return await events.emit(event); 32 | } 33 | 34 | } 35 | 36 | module.exports = { CustomeMessage }; -------------------------------------------------------------------------------- /routes/register.route/reset.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { ResetController } = require('../../controllers/register.controller/reset.controller'); 6 | const authToken = require('../../middlewares/authToken'); 7 | router.post('/resetpassword', authToken, (req, res) => { 8 | 9 | const { password } = req.body; 10 | 11 | const msg = new CustomeMessage(res); 12 | 13 | if (v.isEmpty(password)) { 14 | 15 | msg.success('success', 200, { 16 | 17 | response: { 18 | 19 | status: 'success', 20 | code: 200, 21 | method: req.method, 22 | message: 'Oops..field is required' 23 | } 24 | }); 25 | } 26 | 27 | return new ResetController(req, res).Controller(); 28 | }); 29 | 30 | module.exports = router; -------------------------------------------------------------------------------- /models/ResetPass.model.js: -------------------------------------------------------------------------------- 1 | const { Connection } = require('../configs/Connection'); 2 | const mongoose = require('mongoose'); 3 | const setSchema = new mongoose.Schema({ 4 | 5 | username: { 6 | 7 | type: String, 8 | trim: true, 9 | required: true, 10 | }, 11 | 12 | email: { 13 | 14 | type: String, 15 | unique: true, 16 | trim: true, 17 | required: true, 18 | }, 19 | 20 | token: { 21 | 22 | type: String, 23 | unique: true, 24 | trim: true, 25 | required: true 26 | }, 27 | 28 | newPass: { 29 | 30 | type: String, 31 | trim: true, 32 | required: true 33 | }, 34 | 35 | create_at: { 36 | 37 | type: Date, 38 | default: null 39 | }, 40 | 41 | update_at: { 42 | 43 | type: Date, 44 | default: null 45 | } 46 | }); 47 | 48 | const resetPassSchema = Connection.model('resetpass', setSchema); 49 | 50 | module.exports = resetPassSchema; -------------------------------------------------------------------------------- /helpers/autoExpire.js: -------------------------------------------------------------------------------- 1 | const User = require('../models/Users.model'); 2 | const { FileSystem } = require('../helpers/fileSystem'); 3 | class AutoExpired { 4 | 5 | // function for handling expaired token activation login, max 3 minutes 6 | static autoExpired() { 7 | setInterval(async() => { 8 | 9 | // read file from disk, hash been create automatic 10 | 11 | const readFile = new FileSystem().readFile(); 12 | 13 | // check file math or not with data from database 14 | await User.findOne({ email: readFile }).then(async result => { 15 | 16 | console.log(result); 17 | 18 | if (!result) { 19 | 20 | return true; 21 | 22 | } else { 23 | 24 | // update data if data is match 25 | 26 | await User.updateOne({ _id: result._id }, { token: null }); 27 | } 28 | }); 29 | 30 | }, 180000); 31 | } 32 | } 33 | 34 | module.exports = { AutoExpired }; -------------------------------------------------------------------------------- /routes/register.route/activation.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { ActivationController } = require('../../controllers/register.controller/activation.controller'); 6 | router.get('/activation', (req, res) => { 7 | 8 | const { email, token } = req.query; 9 | 10 | const msg = new CustomeMessage(res); 11 | 12 | if (v.isEmpty(email) || v.isEmpty(token)) { 13 | 14 | msg.error('error', 200, { 15 | 16 | response: { 17 | 18 | status: 'error', 19 | code: res.statusCode, 20 | method: req.method, 21 | url: req.originalUrl, 22 | message: 'Activation token failed, please give me token valid', 23 | } 24 | }); 25 | 26 | } else { 27 | 28 | return new ActivationController(req, res).Controller(); 29 | } 30 | }); 31 | 32 | module.exports = router; -------------------------------------------------------------------------------- /routes/roles.route/create.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { CreateRolesController } = require('../../controllers/roles.controller/create.controller'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.post('/role/create', AuthToken, AuthRole, (req, res, next) => { 9 | 10 | const { name, permission } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(name) || v.isEmpty(permission)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | code: res.statusCode, 19 | method: req.method, 20 | url: req.originalUrl, 21 | message: 'Oops..field is required' 22 | }); 23 | 24 | } else { 25 | 26 | // init create roles controller 27 | return new CreateRolesController(req, res).Controller(); 28 | } 29 | }); 30 | 31 | module.exports = router; -------------------------------------------------------------------------------- /routes/credits.route/create.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CreateCreditsController } = require('../../controllers/credits.controller/create.controller'); 5 | const { CustomeMessage } = require('../../helpers/customeMessage'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.post('/credit/create', AuthToken, AuthRole, (req, res) => { 9 | 10 | const { subid, userid, uas, uts, final } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(subid) || v.isEmpty(userid) || v.isEmpty(uas) || v.isEmpty(uts) || v.isEmpty(final)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | response: { 19 | 20 | status: 'success', 21 | code: res.statusCode, 22 | method: req.method, 23 | url: req.originalUrl, 24 | message: 'Oops..field is required' 25 | } 26 | }); 27 | 28 | } else { 29 | 30 | return new CreateCreditsController(req, res).Controller(); 31 | } 32 | 33 | }); 34 | 35 | module.exports = router; -------------------------------------------------------------------------------- /routes/credits.route/update.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { UpdateCredistController } = require('../../controllers/credits.controller/update.controller'); 5 | const { CustomeMessage } = require('../../helpers/customeMessage'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.put('/credit/update/:id', AuthToken, AuthRole, (req, res) => { 9 | 10 | const { subid, userid, uas, uts, final } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(subid) || v.isEmpty(userid) || v.isEmpty(uas) || v.isEmpty(uts) || v.isEmpty(final)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | response: { 19 | 20 | status: 'success', 21 | code: res.statusCode, 22 | method: req.method, 23 | url: req.originalUrl, 24 | message: 'Oops..field is required', 25 | } 26 | }); 27 | 28 | } else { 29 | 30 | return new UpdateCredistController(req, res).Controller(); 31 | } 32 | }); 33 | 34 | module.exports = router; -------------------------------------------------------------------------------- /routes/subjects.route/create.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CreateSubjectController } = require('../../controllers/subjects.controller/create.controller'); 5 | const { CustomeMessage } = require('../../helpers/customeMessage'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.post('/subject/create', AuthToken, AuthRole, (req, res) => { 9 | 10 | const { credid, lecid, name, code, sum, sks } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(name) || v.isEmpty(code) || v.isEmpty(sum) || v.isEmpty(lecid) || v.isEmpty(sks) || v.isEmpty(credid)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | response: { 19 | 20 | status: 'success', 21 | code: res.statusCode, 22 | method: req.method, 23 | url: req.originalUrl, 24 | message: 'Oops..field is required' 25 | } 26 | }); 27 | 28 | } else { 29 | 30 | return new CreateSubjectController(req, res).Controller(); 31 | } 32 | 33 | }); 34 | 35 | module.exports = router; -------------------------------------------------------------------------------- /routes/subjects.route/update.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { UpdateSubjectController } = require('../../controllers/subjects.controller/update.controller'); 5 | const { CustomeMessage } = require('../../helpers/customeMessage'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.put('/subject/update/:id', AuthToken, AuthRole, (req, res) => { 9 | 10 | const { credid, lecid, name, code, sem, sks } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(credid) || v.isEmpty(lecid) || v.isEmpty(name) || v.isEmpty(code) || v.isEmpty(sem) || v.isEmpty(sks)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | response: { 19 | 20 | status: 'success', 21 | code: res.statusCode, 22 | method: req.method, 23 | url: req.originalUrl, 24 | message: 'Oops..fields is required', 25 | } 26 | }); 27 | 28 | } else { 29 | 30 | return new UpdateSubjectController(req, res).Controller(); 31 | } 32 | }); 33 | 34 | module.exports = router; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mini-project", 3 | "version": "1.0.0", 4 | "description": "challange mini project praxis academy", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "restuwahyu13" 14 | }, 15 | "keywords": [ 16 | "nodejs", 17 | "express" 18 | ], 19 | "author": "restuwahyu13", 20 | "license": "ISC", 21 | "dependencies": { 22 | "@sendgrid/mail": "^6.5.1", 23 | "bcryptjs": "^2.4.3", 24 | "body-parser": "^1.19.0", 25 | "dotenv": "^8.2.0", 26 | "express": "^4.17.1", 27 | "helmet": "^3.21.2", 28 | "jsonwebtoken": "^8.5.1", 29 | "moment": "^2.24.0", 30 | "mongoose": "^5.9.1", 31 | "mongoose-plugin-autoinc": "^1.1.9", 32 | "run-parallel": "^1.1.9", 33 | "shortid": "^2.2.15", 34 | "validator": "^12.2.0" 35 | }, 36 | "devDependencies": { 37 | "eslint": "^6.8.0", 38 | "eslint-config-node": "^4.0.0", 39 | "morgan": "^1.9.1", 40 | "nodemon": "^2.0.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /models/Credits.model.js: -------------------------------------------------------------------------------- 1 | const { Connection } = require('../configs/Connection'); 2 | const autoIncrement = require('mongoose-plugin-autoinc'); 3 | const mongoose = require('mongoose'); 4 | const setSchema = new mongoose.Schema({ 5 | 6 | subject_id: { 7 | 8 | type: Number, 9 | unique: true, 10 | trim: true, 11 | required: true, 12 | ref: 'subjects' 13 | }, 14 | 15 | user_id: { 16 | 17 | type: String, 18 | unique: true, 19 | trim: true, 20 | required: true, 21 | ref: 'users' 22 | }, 23 | 24 | score_uas: { 25 | 26 | type: Number, 27 | trim: true, 28 | required: true 29 | }, 30 | 31 | score_uts: { 32 | 33 | type: Number, 34 | trim: true, 35 | required: true 36 | }, 37 | 38 | score_final: { 39 | 40 | type: Number, 41 | trim: true, 42 | required: true 43 | }, 44 | 45 | create_at: { 46 | 47 | type: Date, 48 | default: null 49 | }, 50 | 51 | update_at: { 52 | 53 | type: Date, 54 | default: null 55 | } 56 | 57 | }); 58 | 59 | setSchema.plugin(autoIncrement.plugin, { 60 | 61 | model: 'credits', 62 | field: 'creditsId', 63 | startAt: 1, 64 | }); 65 | 66 | const roleSchema = Connection.model('credits', setSchema); 67 | 68 | module.exports = roleSchema; -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const cluster = require('cluster'); 2 | const os = require('os'); 3 | const http = require('http'); 4 | const app = require('./app'); 5 | 6 | if (cluster.isMaster) { 7 | 8 | let cpuCore = os.cpus().length; 9 | 10 | for (let i = 0; i < cpuCore; i++) { 11 | 12 | cluster.fork(); 13 | } 14 | 15 | let workerId; 16 | let workerCount = []; 17 | 18 | for (workerId in cluster.workers) { 19 | 20 | workerCount.push(workerId); 21 | } 22 | workerCount.forEach(async workerId => { 23 | 24 | await cluster.workers[workerId].send({ 25 | 26 | from: 'master', 27 | text: 'SIGKILL' 28 | }); 29 | }); 30 | cluster.on('online', worker => { 31 | 32 | if (worker.isConnected()) console.log(`worker is active ${worker.process.pid}`); 33 | 34 | }); 35 | cluster.on('exit', worker => { 36 | 37 | if (worker.isDead()) console.log(`worker is dead ${worker.process.pid}`); 38 | 39 | cluster.fork(); 40 | }); 41 | 42 | 43 | } else { 44 | 45 | if (cluster.isWorker) { 46 | process.on('message', msg => { 47 | 48 | if (msg.type == 'SIGKILL') { 49 | 50 | process.exit(0); 51 | 52 | } else { 53 | 54 | http.createServer(app).listen(process.env.PORT, () => console.log('server is running')); 55 | } 56 | }); 57 | } 58 | } -------------------------------------------------------------------------------- /models/Subjects.model.js: -------------------------------------------------------------------------------- 1 | const { Connection } = require('../configs/Connection'); 2 | const autoIncrement = require('mongoose-plugin-autoinc'); 3 | const mongoose = require('mongoose'); 4 | const setSchema = new mongoose.Schema({ 5 | 6 | credits_id: { 7 | 8 | type: Number, 9 | trim: true, 10 | required: true, 11 | ref: 'credits' 12 | }, 13 | 14 | lecture_id: { 15 | 16 | type: String, 17 | trim: true, 18 | required: true, 19 | ref: 'users' 20 | }, 21 | 22 | name: { 23 | 24 | type: String, 25 | trim: true, 26 | required: true, 27 | }, 28 | 29 | code: { 30 | 31 | type: String, 32 | unique: true, 33 | trim: true, 34 | required: true, 35 | }, 36 | 37 | semester: { 38 | 39 | type: Number, 40 | trim: true, 41 | required: true 42 | }, 43 | 44 | sks: { 45 | 46 | type: Number, 47 | trim: true, 48 | required: true 49 | }, 50 | 51 | created_at: { 52 | 53 | type: Date, 54 | default: null 55 | }, 56 | 57 | updated_at: { 58 | 59 | type: Date, 60 | default: null 61 | } 62 | 63 | }); 64 | 65 | setSchema.plugin(autoIncrement.plugin, { 66 | 67 | model: 'subjects', 68 | field: 'subjectId', 69 | startAt: 1 70 | }); 71 | 72 | const subjectsSchema = Connection.model('subjects', setSchema); 73 | 74 | module.exports = subjectsSchema; -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config({ path: './.env' }); 2 | const express = require('express'); 3 | const bodyParser = require('body-parser'); 4 | const logger = require('morgan'); 5 | const mongoose = require('mongoose'); 6 | const helmet = require('helmet'); 7 | const app = express(); 8 | const { DefaultRoutes } = require('./routes/defaults.route'); 9 | const { AutoExpired } = require('./helpers/autoExpire'); 10 | 11 | // hadnling protection from csrf or xss 12 | app.use(helmet({ 13 | 14 | contentSecurityPolicy: { 15 | 16 | directives: { 17 | 18 | defaultSrc: ["'self'"], 19 | scriptSrc: ["'self'", "'unsafe-inline'"], 20 | styleSrc: ["'self'", "'unsafe-inline'"], 21 | } 22 | }, 23 | frameguard: { action: 'deny' }, 24 | xssFilter: { setOnOldIE: true, reportUri: 'mode=block' }, 25 | hidePoweredBy: { setTo: 'Go v1.13' }, 26 | expectCt: { enforce: true, maxAge: 86400 }, 27 | referrerPolicy: { policy: 'no-referrer' }, 28 | noCache: true, 29 | noSniff: true, 30 | ieNoOpen: true, 31 | permittedCrossDomainPolicies: { permittedPolicies: 'none' }, 32 | dnsPrefetchControl: { allow: false } 33 | 34 | })); 35 | // pasring data from body with www/urlencoded 36 | app.use(bodyParser.urlencoded({ extended: false })); 37 | // handling json data 38 | app.use(bodyParser.json()); 39 | // logger 40 | app.use(logger('dev')); 41 | //init global promise 42 | mongoose.Promise = global.Promise; 43 | //init routes default 44 | new DefaultRoutes(app).Routes(); 45 | //init auto expired 46 | AutoExpired.autoExpired(); 47 | 48 | module.exports = app; -------------------------------------------------------------------------------- /routes/register.route/login.route.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | const express = require('express'); 3 | const router = express.Router(); 4 | const User = require('../../models/Users.model'); 5 | const v = require('validator').default; 6 | const { LoginController } = require('../../controllers/register.controller/login.controller'); 7 | const { CustomeMessage } = require('../../helpers/customeMessage'); 8 | const { EncryptPassword } = require('../../libs/bcrypt'); 9 | router.post('/login', async(req, res) => { 10 | 11 | const { username, email, password } = req.body; 12 | 13 | const msg = new CustomeMessage(res); 14 | 15 | const userCheck = await User.find({ $or: [{ username: username }, { email: email }] }); 16 | 17 | if (!userCheck[0]) { 18 | 19 | msg.error('error', 404, { 20 | 21 | response: { 22 | 23 | status: 'error', 24 | code: res.statusCode, 25 | method: req.method, 26 | url: req.originalUrl, 27 | message: 'Oops...account is not defined, please register http://localhost:3000/register' 28 | } 29 | }); 30 | 31 | } else { 32 | await EncryptPassword.verifyPassword(password, userCheck[0]['password'], (err, success) => { 33 | 34 | if (success) { 35 | 36 | return new LoginController(req, res).Controller(); 37 | 38 | } else { 39 | 40 | msg.error('success', 403, { 41 | 42 | status: 'error', 43 | code: 403, 44 | method: req.method, 45 | url: req.originalUrl, 46 | message: `Oops..username or password wrong` 47 | }); 48 | } 49 | }); 50 | } 51 | }); 52 | 53 | module.exports = router; -------------------------------------------------------------------------------- /controllers/users.controller/result.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class ResultUserController { 4 | constructor(req, res) { 5 | 6 | this.id = req.params.id; 7 | this.req = req; 8 | this.res = res; 9 | this.msg = new CustomeMessage(res); 10 | } 11 | async Controler() { 12 | 13 | const { id, req, res, msg } = this; 14 | await User.findById(id).lean(true).then(result => { 15 | 16 | if (!result) { 17 | 18 | msg.error('error', 404, { 19 | 20 | response: { 21 | 22 | status: 'error', 23 | code: 404, 24 | method: req.method, 25 | url: req.originalUrl, 26 | message: `Oops..data not found in database or deleted` 27 | } 28 | }); 29 | 30 | } else { 31 | 32 | msg.success('success', 200, { 33 | 34 | response: { 35 | 36 | status: 'success', 37 | code: res.statusCode, 38 | method: req.method, 39 | url: req.originalUrl, 40 | message: `Yeah..data already to use`, 41 | data: result 42 | } 43 | }); 44 | } 45 | }).catch(err => { 46 | 47 | msg.error('error', 500, { 48 | 49 | response: { 50 | 51 | status: 'error', 52 | code: 500, 53 | method: req.method, 54 | url: req.originalUrl, 55 | message: `Internal server error ${err}`, 56 | } 57 | }); 58 | }); 59 | } 60 | } 61 | 62 | module.exports = { ResultUserController }; -------------------------------------------------------------------------------- /controllers/roles.controller/results.controller.js: -------------------------------------------------------------------------------- 1 | const Roles = require('../../models/Roles.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class ResultsRolesController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.msg = new CustomeMessage(res); 9 | } 10 | async Controller() { 11 | 12 | const { req, res, msg } = this; 13 | await Roles.find({}).select('name permission create_at').lean(true).then(result => { 14 | 15 | if (!result) { 16 | 17 | msg.error('error', 404, { 18 | 19 | response: { 20 | 21 | status: 'error', 22 | code: 404, 23 | method: req.method, 24 | url: req.originalUrl, 25 | message: 'Oops..data not found in database or deleted' 26 | } 27 | }); 28 | 29 | } else { 30 | 31 | msg.success('success', 200, { 32 | 33 | response: { 34 | 35 | status: 'succes', 36 | code: res.statusCode, 37 | method: req.method, 38 | url: req.originalUrl, 39 | message: 'Data is ready to use', 40 | data: { results: result } 41 | } 42 | }); 43 | } 44 | }).catch(err => { 45 | 46 | msg.error('error', 500, { 47 | 48 | response: { 49 | 50 | status: 'error', 51 | code: 500, 52 | method: req.method, 53 | url: req.originalUrl, 54 | message: `Internal Server Error ${err}` 55 | } 56 | }); 57 | }); 58 | } 59 | } 60 | 61 | module.exports = { ResultsRolesController }; -------------------------------------------------------------------------------- /models/Users.model.js: -------------------------------------------------------------------------------- 1 | const { Connection } = require('../configs/Connection'); 2 | const mongoose = require('mongoose'); 3 | const setSchema = new mongoose.Schema({ 4 | 5 | name: { 6 | 7 | type: String, 8 | unique: true, 9 | trim: true, 10 | required: true, 11 | }, 12 | 13 | email: { 14 | 15 | type: String, 16 | unique: true, 17 | trim: true, 18 | required: true 19 | }, 20 | 21 | username: { 22 | 23 | type: String, 24 | trim: true, 25 | required: true 26 | }, 27 | 28 | gender: { 29 | 30 | type: String, 31 | trim: true, 32 | required: true 33 | }, 34 | 35 | role_id: { 36 | 37 | type: String, 38 | trim: true, 39 | ref: 'roles', 40 | default: null 41 | }, 42 | 43 | password: { 44 | 45 | type: String, 46 | trim: true, 47 | required: true 48 | }, 49 | 50 | handphone: { 51 | 52 | type: Number, 53 | trim: true, 54 | required: true 55 | }, 56 | 57 | permission: { 58 | 59 | type: String, 60 | trim: true, 61 | default: null 62 | }, 63 | 64 | token: { 65 | 66 | type: String, 67 | trim: true, 68 | required: true, 69 | default: null 70 | }, 71 | 72 | auth_token: { 73 | 74 | type: String, 75 | trim: true, 76 | default: null 77 | }, 78 | 79 | active_token: { 80 | 81 | type: Date, 82 | default: null 83 | }, 84 | 85 | create_at: { 86 | 87 | type: Date, 88 | default: null 89 | }, 90 | 91 | update_at: { 92 | 93 | type: Date, 94 | default: null 95 | } 96 | }); 97 | 98 | const userSchema = Connection.model('users', setSchema); 99 | 100 | module.exports = userSchema; -------------------------------------------------------------------------------- /controllers/users.controller/results.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class ResultsUserController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.msg = new CustomeMessage(res); 9 | } 10 | async Controler() { 11 | 12 | const { req, res, msg } = this; 13 | await User.find().select('name username email gender handphone create_at').lean(true).then(result => { 14 | 15 | if (!result) { 16 | 17 | msg.error('error', 404, { 18 | 19 | response: { 20 | 21 | status: 'error', 22 | code: 404, 23 | method: req.method, 24 | url: req.originalUrl, 25 | message: `Oops..data not found in database or deleted` 26 | } 27 | }); 28 | 29 | } else { 30 | 31 | msg.success('success', 200, { 32 | 33 | response: { 34 | 35 | status: 'success', 36 | code: res.statusCode, 37 | method: req.method, 38 | url: req.originalUrl, 39 | message: `Yeah..data already to use`, 40 | data: { results: result } 41 | } 42 | }); 43 | } 44 | }).catch(err => { 45 | 46 | msg.error('error', 500, { 47 | 48 | response: { 49 | 50 | status: 'error', 51 | code: 500, 52 | method: req.method, 53 | url: req.originalUrl, 54 | message: `Internal server error ${err}`, 55 | } 56 | }); 57 | }); 58 | } 59 | } 60 | 61 | module.exports = { ResultsUserController }; -------------------------------------------------------------------------------- /controllers/roles.controller/result.controller.js: -------------------------------------------------------------------------------- 1 | const Roles = require('../../models/Roles.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class ResultRolesController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.msg = new CustomeMessage(res); 10 | } 11 | async Controller() { 12 | 13 | const { req, res, id, msg } = this; 14 | await Roles.findById(id).select('name permission create_at').lean(true).then(result => { 15 | 16 | if (!result) { 17 | 18 | msg.error('error', 404, { 19 | 20 | response: { 21 | 22 | status: 'error', 23 | code: 404, 24 | method: req.method, 25 | url: req.originalUrl, 26 | message: 'Oops..data not found in database or deleted' 27 | } 28 | }); 29 | 30 | } else { 31 | 32 | msg.success('sucess', 200, { 33 | 34 | response: { 35 | 36 | status: 'succes', 37 | code: res.statusCode, 38 | method: req.method, 39 | url: req.originalUrl, 40 | message: 'Yeah..data already to use', 41 | data: { result: result } 42 | } 43 | }); 44 | } 45 | }).catch(err => { 46 | 47 | msg.error('error', 500, { 48 | 49 | response: { 50 | 51 | status: 'error', 52 | code: 500, 53 | method: req.method, 54 | url: req.originalUrl, 55 | message: `Internal Server Error ${err}` 56 | } 57 | }); 58 | }); 59 | } 60 | } 61 | 62 | module.exports = { ResultRolesController }; -------------------------------------------------------------------------------- /routes/register.route/register.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { RegisterController } = require('../../controllers/register.controller/register.controller'); 6 | router.post('/register', (req, res, next) => { 7 | 8 | const { name, username, email, gender, phone, password, cpassword } = req.body; 9 | 10 | const msg = new CustomeMessage(res); 11 | 12 | if (v.isEmpty(name) || v.isEmpty(username) || v.isEmpty(email) || v.isEmpty(gender) || 13 | v.isEmpty(phone) || v.isEmpty(password) || v.isEmpty(cpassword)) { 14 | 15 | msg.success('success', 200, { 16 | 17 | status: 'success', 18 | code: res.statusCode, 19 | method: req.method, 20 | url: req.originalUrl, 21 | message: 'Oops..Field is required' 22 | }); 23 | 24 | } else if (!v.isEmail(email)) { 25 | 26 | msg.success('success', 200, { 27 | 28 | status: 'success', 29 | code: res.statusCode, 30 | method: req.method, 31 | url: req.originalUrl, 32 | message: `Oops..email ${email} is not valid your using ilegal caracter` 33 | }); 34 | 35 | } else if (!cpassword.match(password) || !password.match(cpassword)) { 36 | 37 | msg.success('success', 200, { 38 | 39 | code: res.statusCode, 40 | method: req.method, 41 | url: req.originalUrl, 42 | message: 'Opps..Your password dont`n match' 43 | }); 44 | 45 | } else if (password.length < 6 || cpassword.length < 6) { 46 | 47 | msg.success('success', 200, { 48 | 49 | code: res.statusCode, 50 | method: req.method, 51 | url: req.originalUrl, 52 | message: 'Opps..Password min 6 caracter' 53 | }); 54 | 55 | } else { 56 | 57 | return new RegisterController(req, res, next).Controller(); 58 | } 59 | }); 60 | 61 | module.exports = router; -------------------------------------------------------------------------------- /routes/users.route/update.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const v = require('validator').default; 4 | const { UpdateUserController } = require('../../controllers/users.controller/update.controller'); 5 | const { CustomeMessage } = require('../../helpers/customeMessage'); 6 | const AuthToken = require('../../middlewares/authToken'); 7 | const AuthRole = require('../../middlewares/authRole'); 8 | router.put('/user/update/:id', AuthToken, AuthRole, (req, res) => { 9 | 10 | const { name, username, email, password, cpassword } = req.body; 11 | 12 | const msg = new CustomeMessage(res); 13 | 14 | if (v.isEmpty(name) || v.isEmpty(username) || v.isEmpty(email) || v.isEmpty(password) || v.isEmpty(cpassword)) { 15 | 16 | msg.success('success', 200, { 17 | 18 | response: { 19 | 20 | status: 'success', 21 | code: res.statusCode, 22 | method: req.method, 23 | message: 'Oops..fields is required' 24 | } 25 | }); 26 | 27 | } else if (!v.isEmail(email)) { 28 | 29 | msg.success('success', 200, { 30 | 31 | response: { 32 | 33 | status: 'success', 34 | code: res.statusCode, 35 | method: req.method, 36 | message: 'Oops..email is not valid' 37 | } 38 | }); 39 | 40 | } else if (!cpassword.match(password) || !password.match(cpassword)) { 41 | 42 | msg.success('success', 200, { 43 | 44 | response: { 45 | 46 | status: 'success', 47 | code: res.statusCode, 48 | method: req.method, 49 | message: 'Oops..password is not match' 50 | } 51 | }); 52 | 53 | } else if (password.lengt < 8 || cpassword.length < 8) { 54 | 55 | msg.success('success', 200, { 56 | 57 | response: { 58 | 59 | status: 'success', 60 | code: res.statusCode, 61 | method: req.method, 62 | message: 'Oops..password min 8 caracter' 63 | } 64 | }); 65 | 66 | } else { 67 | 68 | return new UpdateUserController(req, res).Controller(); 69 | } 70 | 71 | }); 72 | 73 | module.exports = router; -------------------------------------------------------------------------------- /controllers/subjects.controller/result.controller.js: -------------------------------------------------------------------------------- 1 | const Subject = require('../../models/Subjects.model'); 2 | const Credits = require('../../models/Credits.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | class ResultsSubjectController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.id = req.params.id; 10 | this.msg = new CustomeMessage(res); 11 | } 12 | async Controller() { 13 | 14 | const { req, res, id, msg } = this; 15 | await Subject.findOne({ _id: id }).select('credits_id lecture_id name code semester sks').populate('lecture_id', 'name username email gender').lean(true).then(async result => { 16 | 17 | if (!result) { 18 | 19 | msg.error('error', 404, { 20 | 21 | response: { 22 | 23 | status: 'error', 24 | code: 404, 25 | method: req.method, 26 | url: req.originalUrl, 27 | message: 'Oops..data not found or deleted' 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | const credits = await Credits.findOne({ creditsId: result['credits_id'] }).select('score_uas score_uts score_final').lean(true); 34 | 35 | msg.success('success', 200, { 36 | 37 | response: { 38 | 39 | status: 'success', 40 | code: res.statusCode, 41 | method: req.method, 42 | url: req.originalUrl, 43 | message: 'Yeah..data already to use', 44 | data: { results: [result].concat(credits) } 45 | } 46 | }); 47 | } 48 | }).catch(err => { 49 | 50 | msg.error('error', 500, { 51 | 52 | response: { 53 | 54 | status: 'success', 55 | code: res.statusCode, 56 | method: req.method, 57 | url: req.originalUrl, 58 | message: `Internal server error ${err}` 59 | } 60 | }); 61 | }); 62 | } 63 | } 64 | 65 | module.exports = { ResultsSubjectController }; -------------------------------------------------------------------------------- /controllers/subjects.controller/results.controller.js: -------------------------------------------------------------------------------- 1 | const Subject = require('../../models/Subjects.model'); 2 | const Credits = require('../../models/Credits.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | class ResultsSubjectController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.msg = new CustomeMessage(res); 10 | } 11 | async Controller() { 12 | 13 | const { req, res, msg } = this; 14 | await Subject.find().select('credits_id lecture_id name code semester sks').populate('lecture_id', 'name username email gender').lean(true).then(async result => { 15 | 16 | if (!result) { 17 | 18 | msg.error('error', 404, { 19 | 20 | response: { 21 | 22 | status: 'error', 23 | code: 404, 24 | method: req.method, 25 | url: req.originalUrl, 26 | message: 'Oops..data failed to result', 27 | data: { results: result } 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | const credits = await Credits.findOne({ creditsId: result[0]['credits_id'] }).select('score_uas score_uts score_final').lean(true); 34 | 35 | msg.success('success', 200, { 36 | 37 | response: { 38 | 39 | status: 'success', 40 | code: res.statusCode, 41 | method: req.method, 42 | url: req.originalUrl, 43 | message: 'Yeah..data already to use', 44 | data: { results: result.concat(credits) } 45 | } 46 | }); 47 | } 48 | }).catch(err => { 49 | 50 | msg.error('error', 500, { 51 | 52 | response: { 53 | 54 | status: 'success', 55 | code: res.statusCode, 56 | method: req.method, 57 | url: req.originalUrl, 58 | message: `Internal server error ${err}` 59 | } 60 | }); 61 | }); 62 | } 63 | } 64 | 65 | module.exports = { ResultsSubjectController }; -------------------------------------------------------------------------------- /controllers/users.controller/delete.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class DeleteUserController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.user = User; 10 | this.msg = new CustomeMessage(res); 11 | } 12 | async Controller() { 13 | 14 | const { req, res, id, user, msg } = this; 15 | await user.findById(id).lean(true).then(async result => { 16 | 17 | if (!result) { 18 | 19 | msg.error('error', 404, { 20 | 21 | response: { 22 | 23 | status: 'error', 24 | code: 404, 25 | method: req.method, 26 | url: req.originalUrl, 27 | message: 'Oops..data not found in database or deleted' 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | const doc = await user.deleteOne({ _id: id }); 34 | 35 | if (doc.deletedCount > 0) { 36 | 37 | msg.success('success', 200, { 38 | 39 | response: 'success', 40 | code: res.statusCode, 41 | method: req.method, 42 | url: req.originalUrl, 43 | message: 'Yeah..data sucesfully to deleted', 44 | }); 45 | 46 | } else { 47 | 48 | msg.error('error', 403, { 49 | 50 | response: 'error', 51 | code: 403, 52 | method: req.method, 53 | url: req.originalUrl, 54 | message: 'Oops..data failed to deleted', 55 | }); 56 | } 57 | } 58 | }).catch(err => { 59 | 60 | msg.error('error', 500, { 61 | 62 | response: 'error', 63 | code: 500, 64 | method: req.method, 65 | url: req.originalUrl, 66 | message: `Internal server error ${err}` 67 | }); 68 | }); 69 | } 70 | } 71 | 72 | module.exports = { DeleteUserController }; -------------------------------------------------------------------------------- /controllers/credits.controller/results.controller.js: -------------------------------------------------------------------------------- 1 | const Credits = require('../../models/Credits.model'); 2 | const Subject = require('../../models/Subjects.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | class ResultsCredistController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.msg = new CustomeMessage(res); 10 | } 11 | async Controller() { 12 | 13 | const { req, res, msg } = this; 14 | 15 | // result all data from credits model 16 | await Credits.find().select('subject_id lecture_id score_uas score_uts score_final').populate('user_id', 'name username email gender').lean(true).then(async result => { 17 | 18 | if (!result) { 19 | 20 | msg.error('error', 404, { 21 | 22 | response: { 23 | 24 | status: 'error', 25 | code: 404, 26 | method: req.method, 27 | url: req.originalUrl, 28 | message: 'Oops..data not found in database or deleted' 29 | } 30 | }); 31 | 32 | } else { 33 | 34 | // result all data from subject model 35 | 36 | const subject = await Subject.findOne({ creditsId: result[0]['creditsId'] }).select('name code semester sks').lean(true); 37 | 38 | msg.success('success', 200, { 39 | 40 | response: { 41 | 42 | status: 'success', 43 | code: res.statusCode, 44 | method: req.method, 45 | url: req.originalUrl, 46 | message: 'Yeah..data already to use', 47 | data: { results: result.concat(subject) } 48 | } 49 | }); 50 | } 51 | }).catch(err => { 52 | 53 | msg.error('error', 500, { 54 | 55 | response: { 56 | 57 | status: 'error', 58 | code: 500, 59 | method: req.method, 60 | url: req.originalUrl, 61 | message: `Internal server error ${err}` 62 | } 63 | }); 64 | }); 65 | } 66 | } 67 | 68 | module.exports = { ResultsCredistController }; -------------------------------------------------------------------------------- /controllers/credits.controller/result.controller.js: -------------------------------------------------------------------------------- 1 | const Credits = require('../../models/Credits.model'); 2 | const Subject = require('../../models/Subjects.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | class ResultCredistController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.id = req.params.id; 10 | this.msg = new CustomeMessage(res); 11 | } 12 | async Controller() { 13 | 14 | const { req, res, id, msg } = this; 15 | 16 | // result all data from creditsId model 17 | await Credits.findById(id).select('subject_id lecture_id score_uas score_uts score_final').populate('user_id', 'name username email gender').lean(true).then(async result => { 18 | 19 | if (!result) { 20 | 21 | msg.error('error', 404, { 22 | 23 | response: { 24 | 25 | status: 'error', 26 | code: 404, 27 | method: req.method, 28 | url: req.originalUrl, 29 | message: 'Oops..data not found in database or deleted' 30 | } 31 | }); 32 | 33 | } else { 34 | 35 | // result all data from subject model 36 | 37 | const subject = await Subject.findOne({ creditsId: result['creditsId'] }).select('name code semester sks').lean(true); 38 | 39 | msg.success('success', 200, { 40 | 41 | response: { 42 | 43 | status: 'success', 44 | code: res.statusCode, 45 | method: req.method, 46 | url: req.originalUrl, 47 | message: 'Yeah..data already to use', 48 | data: { results: [result].concat(subject) } 49 | } 50 | }); 51 | } 52 | }).catch(err => { 53 | 54 | msg.error('error', 500, { 55 | 56 | response: { 57 | 58 | status: 'success', 59 | code: 500, 60 | method: req.method, 61 | url: req.originalUrl, 62 | message: `Internal server error ${err}` 63 | } 64 | }); 65 | }); 66 | } 67 | } 68 | 69 | module.exports = { ResultCredistController }; -------------------------------------------------------------------------------- /controllers/roles.controller/delete.controller.js: -------------------------------------------------------------------------------- 1 | const Roles = require('../../models/Roles.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class DeleteRolesController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.msg = new CustomeMessage(res); 10 | } 11 | async Controller() { 12 | 13 | const { req, res, id, msg } = this; 14 | await Roles.findById(id).lean(true).then(result => { 15 | 16 | if (!result) { 17 | 18 | msg.error('error', 404, { 19 | 20 | response: { 21 | 22 | status: 'error', 23 | code: 404, 24 | method: req.method, 25 | url: req.originalUrl, 26 | message: 'Oops..data not found in database or deleted' 27 | } 28 | }); 29 | 30 | } else { 31 | 32 | return Roles.deleteOne({ _id: id }); 33 | } 34 | }).then(doc => { 35 | 36 | if (doc.ok > 0) { 37 | 38 | msg.success('success', 200, { 39 | 40 | response: { 41 | 42 | status: 'succes', 43 | code: res.statusCode, 44 | method: req.method, 45 | url: req.originalUrl, 46 | message: 'Yeah..data succesfully to deleted' 47 | } 48 | }); 49 | 50 | } else { 51 | 52 | msg.error('error', 403, { 53 | 54 | response: { 55 | 56 | status: 'error', 57 | code: 403, 58 | method: req.method, 59 | url: req.originalUrl, 60 | message: 'Oops..data failed to deleted' 61 | } 62 | }); 63 | } 64 | }).catch(err => { 65 | 66 | res.status(500).json({ 67 | 68 | res: { 69 | 70 | code: res.statusCode, 71 | method: req.method, 72 | url: req.originalUrl, 73 | message: `Internal server error ${err}` 74 | } 75 | }); 76 | }); 77 | } 78 | } 79 | 80 | module.exports = { DeleteRolesController }; -------------------------------------------------------------------------------- /middlewares/authToken.js: -------------------------------------------------------------------------------- 1 | const User = require('../models/Users.model'); 2 | const { CustomeMessage } = require('../helpers/customeMessage'); 3 | const jwt = require('jsonwebtoken'); 4 | module.exports = async(req, res, next) => { 5 | 6 | // function custome message 7 | 8 | const msg = new CustomeMessage(res); 9 | 10 | // function get token from headers 11 | 12 | const token = req.headers.authorization.split(' ')[1]; 13 | 14 | // function check token is valid 15 | 16 | if (token) { 17 | 18 | // check if token is match with data from database 19 | 20 | const checkToken = await User.findOne({ auth_token: token }); 21 | 22 | if (!checkToken) { 23 | 24 | msg.error('error', 401, { 25 | 26 | response: { 27 | 28 | status: 'error', 29 | code: 401, 30 | method: req.method, 31 | url: req.originalUrl, 32 | message: 'Oops..Unauthorized access, your token is not valid' 33 | } 34 | }); 35 | 36 | } else { 37 | 38 | // function verification token from header with authorization bearer 39 | return jwt.verify(token, process.env.SECRET_TOKEN, (err, decoded) => { 40 | 41 | if (!decoded) { 42 | 43 | // message if token not valid or expaired 44 | 45 | msg.error('error', 401, { 46 | 47 | response: { 48 | 49 | status: 'error', 50 | code: 401, 51 | method: req.method, 52 | url: req.originalUrl, 53 | message: `Oops..Unauthorized access, please give valid token` 54 | } 55 | }); 56 | 57 | } else { 58 | 59 | // return next if token is valid 60 | 61 | return next(); 62 | } 63 | }); 64 | } 65 | 66 | } else { 67 | 68 | // message if token not found for authorization 69 | 70 | msg.error('error', 404, { 71 | 72 | response: { 73 | 74 | status: 'error', 75 | code: 404, 76 | method: req.method, 77 | url: req.originalUrl, 78 | message: `Oops..Token not found please give valid token` 79 | } 80 | }); 81 | } 82 | } -------------------------------------------------------------------------------- /controllers/subjects.controller/delete.controller.js: -------------------------------------------------------------------------------- 1 | const Subject = require('../../models/Subjects.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class DeleteSubjectController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.msg = new CustomeMessage(res); 10 | this.subject = Subject; 11 | } 12 | async Controller() { 13 | 14 | const { req, res, id, msg, subject } = this; 15 | await subject.findById(id).then(result => { 16 | 17 | if (!result) { 18 | 19 | msg.error('error', 404, { 20 | 21 | response: { 22 | 23 | status: 'error', 24 | code: 404, 25 | method: req.method, 26 | url: req.originalUrl, 27 | message: 'Oops..data not found in database or deleted' 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | return subject.deleteOne({ _id: id }); 34 | } 35 | }).then(doc => { 36 | 37 | if (doc.ok > 0) { 38 | 39 | msg.success('success', 200, { 40 | 41 | response: { 42 | 43 | status: 'success', 44 | code: res.statusCode, 45 | method: req.method, 46 | url: req.originalUrl, 47 | message: 'Yeah..data successfully to deleted' 48 | } 49 | }); 50 | 51 | } else { 52 | 53 | msg.error('error', 403, { 54 | 55 | response: { 56 | 57 | status: 'error', 58 | code: 403, 59 | method: req.method, 60 | url: req.originalUrl, 61 | message: 'Oops..data failed to deleted' 62 | } 63 | }); 64 | } 65 | }).catch(err => { 66 | 67 | msg.error('error', 500, { 68 | 69 | response: { 70 | 71 | status: 'error', 72 | code: 500, 73 | method: req.method, 74 | url: req.originalUrl, 75 | message: `Internal server error ${err}` 76 | } 77 | }); 78 | }); 79 | } 80 | } 81 | 82 | module.exports = { DeleteSubjectController }; -------------------------------------------------------------------------------- /controllers/roles.controller/create.controller.js: -------------------------------------------------------------------------------- 1 | const Roles = require('../../models/Roles.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class CreateRolesController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.name = req.body.name; 9 | this.permission = req.body.permission; 10 | this.create_at = new Date; 11 | this.msg = new CustomeMessage(res); 12 | } 13 | async Controller() { 14 | 15 | const { req, res, name, permission, create_at, msg } = this; 16 | await Roles.findOne({ name: name, permission: permission }).then(result => { 17 | 18 | if (result) { 19 | 20 | msg.error('error', 409, { 21 | 22 | response: { 23 | 24 | status: 'error', 25 | code: 409, 26 | method: req.method, 27 | message: 'Oops..data already exist in database' 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | const data = new Roles({ name, permission, create_at }); 34 | 35 | return data.save(); 36 | } 37 | }).then(doc => { 38 | 39 | if (doc) { 40 | 41 | msg.success('success', 200, { 42 | 43 | response: { 44 | 45 | status: 'error', 46 | code: res.statusCode, 47 | method: req.method, 48 | message: 'Yeah..data sucessfuly to store in database', 49 | data: { result: doc } 50 | } 51 | }); 52 | 53 | } else { 54 | 55 | msg.error('error', 403, { 56 | 57 | response: { 58 | 59 | status: 'error', 60 | code: 403, 61 | method: req.method, 62 | message: 'Oops..data failed to store in database' 63 | } 64 | }); 65 | } 66 | }).catch(err => { 67 | 68 | msg.error('error', 500, { 69 | 70 | response: { 71 | 72 | status: 'error', 73 | code: 500, 74 | method: req.method, 75 | message: `Internal server error ${err}` 76 | } 77 | }); 78 | }) 79 | } 80 | } 81 | 82 | module.exports = { CreateRolesController }; -------------------------------------------------------------------------------- /controllers/credits.controller/delete.controller.js: -------------------------------------------------------------------------------- 1 | const Credits = require('../../models/Credits.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class DeleteCreditsController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.msg = new CustomeMessage(res); 10 | this.credits = Credits; 11 | } 12 | async Controller() { 13 | 14 | const { req, res, id, msg, credits } = this; 15 | await credits.findById(id).then(result => { 16 | 17 | if (!result) { 18 | 19 | msg.error('error', 404, { 20 | 21 | response: { 22 | 23 | status: 'error', 24 | code: res.statusCode, 25 | method: req.method, 26 | url: req.originalUrl, 27 | message: 'Oops..data not found in database or deleted' 28 | } 29 | }); 30 | 31 | } else { 32 | 33 | return credits.deleteOne({ _id: id }); 34 | } 35 | }).then(doc => { 36 | 37 | if (doc.deletedCount > 0) { 38 | 39 | msg.success('success', 200, { 40 | 41 | response: { 42 | 43 | status: 'success', 44 | code: res.statusCode, 45 | method: req.method, 46 | url: req.originalUrl, 47 | message: 'Yeah..data successfully to deleted' 48 | } 49 | }); 50 | 51 | } else { 52 | 53 | msg.error('error', 403, { 54 | 55 | response: { 56 | 57 | status: 'error', 58 | code: 403, 59 | method: req.method, 60 | url: req.originalUrl, 61 | message: 'Oops..data failed to deleted' 62 | } 63 | }); 64 | } 65 | }).catch(err => { 66 | 67 | msg.error('error', 404, { 68 | 69 | response: { 70 | 71 | status: 'error', 72 | code: res.statusCode, 73 | method: req.method, 74 | url: req.originalUrl, 75 | message: `Internal server error ${err}` 76 | } 77 | }); 78 | }); 79 | } 80 | } 81 | 82 | module.exports = { DeleteCreditsController }; -------------------------------------------------------------------------------- /controllers/roles.controller/update.controller.js: -------------------------------------------------------------------------------- 1 | const Roles = require('../../models/Roles.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class UpdateRolesController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.name = req.body.name; 10 | this.permission = req.body.permission; 11 | this.update_at = new Date; 12 | this.msg = new CustomeMessage(res); 13 | } 14 | async Controller() { 15 | 16 | const { req, res, id, name, permission, update_at, msg } = this; 17 | await Roles.findById(id).lean(true).then(result => { 18 | 19 | if (!result) { 20 | 21 | msg.error('error', 404, { 22 | 23 | response: { 24 | 25 | status: 'error', 26 | code: 404, 27 | method: req.method, 28 | url: req.originalUrl, 29 | message: 'Oops..data not found in database or deleted' 30 | } 31 | }); 32 | 33 | } else { 34 | 35 | const data = { name, permission, update_at } 36 | 37 | return Roles.updateOne({ _id: id }, {...data }); 38 | } 39 | }).then(doc => { 40 | 41 | if (doc) { 42 | 43 | msg.success('success', 200, { 44 | 45 | response: { 46 | 47 | status: 'succes', 48 | code: res.statusCode, 49 | method: req.method, 50 | url: req.originalUrl, 51 | message: 'Yeah..data successfuly to updated' 52 | } 53 | }); 54 | 55 | } else { 56 | 57 | msg.error('error', 404, { 58 | 59 | response: { 60 | 61 | status: 'error', 62 | code: 404, 63 | method: req.method, 64 | url: req.originalUrl, 65 | message: 'Oops..data failed to updated' 66 | } 67 | }); 68 | } 69 | }).catch(err => { 70 | 71 | msg.error('error', 500, { 72 | 73 | response: { 74 | 75 | status: 'error', 76 | code: 500, 77 | method: req.method, 78 | url: req.originalUrl, 79 | message: `Internal server error ${err}` 80 | } 81 | }); 82 | }); 83 | } 84 | } 85 | 86 | module.exports = { UpdateRolesController }; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Example Mini-Project with Express 2 | 3 | Berikut adalah simple **Mini project** Sistem Akademik Sekolah studi kasus from [kraken47](https://bit.ly/326ShGb) and [Praxis Academy](https://pandao.github.io/editor.md/en.html) 4 | 5 | #### Cara Menjalankan: 6 | - install semua module dengan mengetikan `npm install` pada terminal 7 | - jalankan dengan mengetik `npm run dev` atau `yarn run dev` pada terminal 8 | 9 | #### Features: 10 | 11 | - [x] **Advanced Login and Register** 12 | - [x] **Forgot and Reset Password** 13 | - [x] **Activation Token Login with Sendgrind Email** 14 | - [x] **Resend Token Activation** 15 | - [x] **Automatic Expired Token login** 16 | - [x] **Automatic Random Token Activation** 17 | - [x] **Encryption Password** 18 | - [x] **Custome Message Error and Success** 19 | - [x] **Custome Email Template and Reset Password Template** 20 | - [x] **Auth with JWT and Auth with Role Permission** 21 | - [x] **Service Worker Multi Tread Core** 22 | - [x] **Any More** 23 | 24 | #### Endpoits: 25 | 26 | | Name | Route Name | Request Method | 27 | | ----------------------- | ------------------| ------------------- | 28 | | Register | http://localhost:3000/register | POST 29 | | Login | http://localhost:3000/login | POST 30 | | Activation Token | http://localhost:3000/activation | GET 31 | | Resend Token | http://localhost:3000/resendtoken | GET 32 | | Forgot Password | http://localhost:3000/forgotpassword | POST 33 | | Reset Password | http://localhost:3000/resetpassword | POST 34 | | **User Create** | http://localhost:3000/user/create | **POST** 35 | | User Results | http://localhost:3000/user/results | GET 36 | | User Result | http://localhost:3000/user/result/:id | GET 37 | | User Delete | http://localhost:3000/user/delete/:id | DELETE 38 | | User Update | http://localhost:3000/user/update/:id | PUT 39 | | **Role Create** | http://localhost:3000/role/create | **POST** 40 | | Role Results | http://localhost:3000/role/results | GET 41 | | Role Result | http://localhost:3000/role/result/:id | GET 42 | | Role Delete | http://localhost:3000/role/delete/:id | DELETE 43 | | Role Update | http://localhost:3000/role/update/:id | PUT 44 | | **Subject Create** | http://localhost:3000/subject/create | **POST** 45 | | Subject Results | http://localhost:3000/role/subject/results | GET 46 | | Subject Result | http://localhost:3000/role/subject/result/:id | GET 47 | | Subject Delete | http://localhost:3000/role/subject/delete/:id | DELETE 48 | | Subject Update | http://localhost:3000/role/subject/update/:id | PUT 49 | | **Credit Create** | http://localhost:3000/credit/create | **POST** 50 | | Credit Results | http://localhost:3000/role/credit/results | GET 51 | | Credit Result | http://localhost:3000/role/credit/result/:id | GET 52 | | Credit Delete | http://localhost:3000/role/credit/delete/:id | DELETE 53 | | Credit Update | http://localhost:3000/role/credit/update/:id | PUT -------------------------------------------------------------------------------- /controllers/subjects.controller/create.controller.js: -------------------------------------------------------------------------------- 1 | const Subject = require('../../models/Subjects.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class CreateSubjectController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.credits_id = req.body.credid; 9 | this.lecture_id = req.body.lecid; 10 | this.name = req.body.name; 11 | this.code = req.body.code; 12 | this.semester = req.body.semester; 13 | this.sks = req.body.sks; 14 | this.created_at = new Date; 15 | this.msg = new CustomeMessage(res); 16 | } 17 | async Controller() { 18 | 19 | const { req, res, credits_id, lecture_id, name, code, semester, sks, created_at, msg } = this; 20 | await Subject.findOne({ name: name, semester: semester }).then(result => { 21 | 22 | if (result) { 23 | 24 | msg.error('error', 409, { 25 | 26 | response: { 27 | 28 | status: 'error', 29 | code: 409, 30 | method: req.method, 31 | message: 'Oops..data already exist in database' 32 | } 33 | }); 34 | 35 | } else { 36 | 37 | const data = new Subject({ credits_id, lecture_id, name, code, semester, sks, created_at }); 38 | 39 | return data.save(); 40 | } 41 | }).then(doc => { 42 | 43 | if (doc) { 44 | 45 | msg.success('success', 200, { 46 | 47 | response: { 48 | 49 | status: 'success', 50 | code: res.statusCode, 51 | method: req.method, 52 | url: req.originalUrl, 53 | message: 'Yeah..data successfuly to store in database' 54 | } 55 | }); 56 | 57 | } else { 58 | 59 | msg.error('error', 403, { 60 | 61 | response: { 62 | 63 | status: 'success', 64 | code: 403, 65 | method: req.method, 66 | url: req.originalUrl, 67 | message: 'Oops..data failed to store in database' 68 | } 69 | }); 70 | } 71 | }).catch(err => { 72 | 73 | msg.error('error', 500, { 74 | 75 | response: { 76 | 77 | status: 'error', 78 | code: 500, 79 | method: req.method, 80 | url: req.originalUrl, 81 | message: `Internal server error ${err}` 82 | } 83 | }); 84 | }); 85 | } 86 | } 87 | 88 | module.exports = { CreateSubjectController }; -------------------------------------------------------------------------------- /controllers/subjects.controller/update.controller.js: -------------------------------------------------------------------------------- 1 | const Subject = require('../../models/Subjects.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class UpdateSubjectController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.credits_id = req.body.credid; 10 | this.lecture_id = req.body.lecid; 11 | this.name = req.body.name; 12 | this.code = req.body.code; 13 | this.semester = req.body.sem; 14 | this.sks = req.body.sks; 15 | this.update_at = new Date; 16 | this.msg = new CustomeMessage(res); 17 | } 18 | async Controller() { 19 | 20 | const { req, res, id, credits_id, lecture_id, name, code, semester, sks, update_at, msg } = this; 21 | await Subject.findById(id).lean(true).then(result => { 22 | 23 | if (!result) { 24 | 25 | msg.error('error', 404, { 26 | 27 | response: { 28 | 29 | status: 'error', 30 | code: 404, 31 | method: req.method, 32 | url: req.originalUrl, 33 | message: 'Oops..data not found in database or deleted' 34 | } 35 | }); 36 | 37 | } else { 38 | 39 | const data = { credits_id, lecture_id, name, code, semester, sks, update_at }; 40 | 41 | return Subject.updateOne({ _id: id }, {...data }); 42 | } 43 | }).then(doc => { 44 | 45 | if (doc) { 46 | 47 | msg.success('success', 200, { 48 | 49 | response: { 50 | 51 | status: 'success', 52 | code: res.statusCode, 53 | method: req.method, 54 | url: req.originalUrl, 55 | message: 'Yeah..data successfuly to updated' 56 | } 57 | }); 58 | 59 | } else { 60 | 61 | msg.error('error', 403, { 62 | 63 | response: { 64 | 65 | status: 'error', 66 | code: 403, 67 | method: req.method, 68 | url: req.originalUrl, 69 | message: 'Oops..data failed to updated' 70 | } 71 | }); 72 | } 73 | }).catch(err => { 74 | 75 | msg.error('error', 500, { 76 | 77 | response: { 78 | 79 | status: 'error', 80 | code: 500, 81 | method: req.method, 82 | url: req.originalUrl, 83 | message: `Internal server error ${err}` 84 | } 85 | }); 86 | }); 87 | } 88 | } 89 | 90 | module.exports = { UpdateSubjectController }; -------------------------------------------------------------------------------- /controllers/credits.controller/create.controller.js: -------------------------------------------------------------------------------- 1 | const Credits = require('../../models/Credits.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class CreateCreditsController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.subject_id = req.body.subid; 9 | this.user_id = req.body.user_id; 10 | this.score_uas = req.body.score_uas; 11 | this.score_uts = req.body.score_uts; 12 | this.score_final = req.body.score_final; 13 | this.create_at = new Date; 14 | this.credits = Credits; 15 | this.msg = new CustomeMessage(res); 16 | } 17 | async Controller() { 18 | 19 | const { req, res, subject_id, user_id, score_uas, score_uts, score_final, create_at, credits, msg } = this; 20 | await credits.findOne({ user_id: user_id }).then(result => { 21 | 22 | if (result) { 23 | 24 | msg.error('error', 409, { 25 | 26 | response: { 27 | 28 | status: 'success', 29 | code: 409, 30 | method: req.method, 31 | url: req.originalUrl, 32 | message: 'Oops..data already exist in database' 33 | } 34 | }); 35 | 36 | } else { 37 | 38 | const data = new Credits({ subject_id, user_id, score_uas, score_uts, score_final, create_at }); 39 | 40 | return data.save(); 41 | } 42 | }).then(doc => { 43 | 44 | if (doc) { 45 | 46 | msg.success('success', 200, { 47 | 48 | response: { 49 | 50 | status: 'success', 51 | code: res.statusCode, 52 | method: req.method, 53 | url: req.originalUrl, 54 | message: 'Yeah..data sucessfuly to store in database' 55 | } 56 | }); 57 | 58 | } else { 59 | 60 | msg.error('error', 403, { 61 | 62 | response: { 63 | 64 | status: 'success', 65 | code: 403, 66 | method: req.method, 67 | url: req.originalUrl, 68 | message: 'Oops..data failed to store in database' 69 | } 70 | }); 71 | } 72 | }).catch(err => { 73 | 74 | msg.error('error', 500, { 75 | 76 | response: { 77 | 78 | status: 'success', 79 | code: 500, 80 | method: req.method, 81 | url: req.originalUrl, 82 | message: `Internal server error ${err}` 83 | } 84 | }); 85 | }); 86 | } 87 | } 88 | 89 | module.exports = { CreateCreditsController }; -------------------------------------------------------------------------------- /routes/users.route/create.route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { CreateUserController } = require('../../controllers/users.controller/create.controller'); 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const AuthToken = require('../../middlewares/authToken'); 6 | const AuthRole = require('../../middlewares/authRole'); 7 | router.post('/user/create', AuthToken, AuthRole, (req, res) => { 8 | 9 | const msg = new CustomeMessage(res); 10 | const { name, username, email, gender, phone, password, cpassword } = req.body; 11 | const usernameRegex = /['`~!@#$%^&*()_+={}[];,<>']/gi; 12 | const emailRegex = /^['`~!#$%^&*()_+={}[];,<>']/gi; 13 | 14 | if (name === '' || username === '' || email === '' || gender === '' || phone === '' || 15 | password === '' || cpassword === '') { 16 | 17 | return msg.success('success', 200, { 18 | 19 | code: res.statusCode, 20 | method: req.method, 21 | url: req.originalUrl, 22 | message: 'Oops..Field is required' 23 | }); 24 | 25 | } else if (usernameRegex.exec(username.match(usernameRegex))) { 26 | 27 | return msg.success('success', 200, { 28 | 29 | code: res.statusCode, 30 | method: req.method, 31 | url: req.originalUrl, 32 | message: `Oops..username ${username} is not valid your using ilegal caracter` 33 | }); 34 | 35 | } else if (emailRegex.exec(email.match(emailRegex))) { 36 | 37 | return msg.success('success', 200, { 38 | 39 | code: res.statusCode, 40 | method: req.method, 41 | url: req.originalUrl, 42 | message: `Oops..email ${email} is not valid your using ilegal caracter` 43 | }); 44 | 45 | // else if (email.endsWith('@gmail.com') === false) { 46 | 47 | // return msg.success('success', 200, { 48 | 49 | // code: res.statusCode, 50 | // method: req.method, 51 | // url: req.originalUrl, 52 | // message: `Oops..email ${email} is not valid please using google mail` 53 | // }); 54 | 55 | // } else if (!cpassword.match(password) || !password.match(cpassword)) { 56 | 57 | return msg.success('success', 200, { 58 | 59 | code: res.statusCode, 60 | method: req.method, 61 | url: req.originalUrl, 62 | message: 'Opps..Your password dont`n match' 63 | }); 64 | 65 | } else if (password.length < 6 || cpassword.length < 6) { 66 | 67 | return msg.success('success', 200, { 68 | 69 | code: res.statusCode, 70 | method: req.method, 71 | url: req.originalUrl, 72 | message: 'Opps..Password min 6 caracter' 73 | }); 74 | 75 | } else { 76 | 77 | return new CreateUserController(req, res).Controller(); 78 | } 79 | }); 80 | 81 | module.exports = router; -------------------------------------------------------------------------------- /controllers/credits.controller/update.controller.js: -------------------------------------------------------------------------------- 1 | const Credits = require('../../models/Credits.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | class UpdateCredistController { 4 | constructor(req, res) { 5 | 6 | this.req = req; 7 | this.res = res; 8 | this.id = req.params.id; 9 | this.subject_id = req.body.subid; 10 | this.user_id = req.body.userid; 11 | this.score_uas = req.body.uas; 12 | this.score_uts = req.body.uts; 13 | this.score_final = req.body.final; 14 | this.msg = new CustomeMessage(res); 15 | } 16 | async Controller() { 17 | 18 | const { req, res, id, subject_id, user_id, score_uas, score_uts, score_final, msg } = this; 19 | 20 | // check if data already exist or not in database before update credits 21 | await Credits.findById(id).lean(true).then(result => { 22 | 23 | if (!result) { 24 | 25 | msg.error('error', 404, { 26 | 27 | response: { 28 | 29 | status: 'error', 30 | code: 404, 31 | method: req.method, 32 | url: req.originalUrl, 33 | message: 'Oops..data not found in database or deleted' 34 | } 35 | }); 36 | 37 | } else { 38 | 39 | // get data from body 40 | const data = { subject_id, user_id, score_uas, score_uts, score_final }; 41 | 42 | // update data if data already exists in database 43 | return Credits.updateOne({ _id: id }, {...data }); 44 | } 45 | }).then(doc => { 46 | 47 | if (doc) { 48 | 49 | msg.success('success', 200, { 50 | 51 | response: { 52 | 53 | status: 'success', 54 | code: res.statusCode, 55 | method: req.method, 56 | url: req.originalUrl, 57 | message: 'Yeah..data successfuly to updated' 58 | } 59 | }); 60 | 61 | } else { 62 | 63 | msg.error('error', 403, { 64 | 65 | response: { 66 | 67 | status: 'error', 68 | code: 403, 69 | method: req.method, 70 | url: req.originalUrl, 71 | message: 'Oops..data failed to updated' 72 | } 73 | }); 74 | } 75 | }).catch(err => { 76 | 77 | msg.error('error', 500, { 78 | 79 | response: { 80 | 81 | status: 'error', 82 | code: 500, 83 | method: req.method, 84 | url: req.originalUrl, 85 | message: `Internal server error ${err}` 86 | } 87 | }); 88 | }); 89 | } 90 | } 91 | 92 | module.exports = { UpdateCredistController }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,windows,visualstudiocode 3 | # Edit at https://www.gitignore.io/?templates=node,windows,visualstudiocode 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional REPL history 62 | .node_repl_history 63 | 64 | # Output of 'npm pack' 65 | *.tgz 66 | 67 | # Yarn Integrity file 68 | .yarn-integrity 69 | 70 | # dotenv environment variables file 71 | .env 72 | .env.test 73 | 74 | # parcel-bundler cache (https://parceljs.org/) 75 | .cache 76 | 77 | # next.js build output 78 | .next 79 | 80 | # nuxt.js build output 81 | .nuxt 82 | 83 | # rollup.js default build output 84 | dist/ 85 | 86 | # Uncomment the public line if your project uses Gatsby 87 | # https://nextjs.org/blog/next-9-1#public-directory-support 88 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav 89 | # public 90 | 91 | # Storybook build outputs 92 | .out 93 | .storybook-out 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # Temporary folders 108 | tmp/ 109 | temp/ 110 | 111 | ### VisualStudioCode ### 112 | .vscode/* 113 | !.vscode/settings.json 114 | !.vscode/tasks.json 115 | !.vscode/launch.json 116 | !.vscode/extensions.json 117 | 118 | ### VisualStudioCode Patch ### 119 | # Ignore all local history of files 120 | .history 121 | 122 | ### Windows ### 123 | # Windows thumbnail cache files 124 | Thumbs.db 125 | Thumbs.db:encryptable 126 | ehthumbs.db 127 | ehthumbs_vista.db 128 | 129 | # Dump file 130 | *.stackdump 131 | 132 | # Folder config file 133 | [Dd]esktop.ini 134 | 135 | # Recycle Bin used on file shares 136 | $RECYCLE.BIN/ 137 | 138 | # Windows Installer files 139 | *.cab 140 | *.msi 141 | *.msix 142 | *.msm 143 | *.msp 144 | 145 | # Windows shortcuts 146 | *.lnk 147 | 148 | # End of https://www.gitignore.io/api/node,windows,visualstudiocode -------------------------------------------------------------------------------- /controllers/register.controller/reset.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | const { EncryptPassword } = require('../../libs/bcrypt'); 4 | class ResetController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.password = req.body.password; 10 | this.encrypt = EncryptPassword; 11 | this.msg = new CustomeMessage(res); 12 | } 13 | async Controller() { 14 | 15 | // get data from body 16 | const { req, res, password, encrypt, msg } = this; 17 | 18 | // get token from headers with bearer 19 | const getToken = req.headers.authorization; 20 | 21 | // get token from headers and replace bearer text 22 | const setToken = getToken.substring(7, 300); 23 | 24 | // check if token auth from header match with in token auth from database 25 | await User.findOne({ auth_token: setToken }).then(result => { 26 | 27 | if (!result) { 28 | 29 | msg.error('error', 401, { 30 | 31 | response: { 32 | 33 | status: 'error', 34 | code: 401, 35 | method: res.method, 36 | url: req.originalUrl, 37 | message: `Opps...token authorization don't match` 38 | } 39 | }); 40 | 41 | } else { 42 | 43 | // function for hash password before reset password 44 | const hashPass = encrypt.hashPassword(password, 10); 45 | 46 | // function update password user after reset password 47 | return User.updateOne({ _id: result._id }, { password: hashPass }); 48 | } 49 | }).then(doc => { 50 | 51 | if (doc.ok > 0) { 52 | 53 | msg.success('success', 200, { 54 | 55 | response: { 56 | 57 | status: 'success', 58 | code: res.statusCode, 59 | method: res.method, 60 | url: req.originalUrl, 61 | message: `Yeah...reset password successfuly` 62 | } 63 | }); 64 | 65 | } else { 66 | 67 | msg.error('error', 403, { 68 | 69 | response: { 70 | 71 | status: 'error', 72 | code: 403, 73 | method: res.method, 74 | url: req.originalUrl, 75 | message: `Oops...reset password failed` 76 | } 77 | }); 78 | } 79 | }).catch(err => { 80 | 81 | msg.error('error', 500, { 82 | 83 | response: { 84 | 85 | status: 'error', 86 | code: 500, 87 | method: res.method, 88 | url: req.originalUrl, 89 | message: `Internal server error ${err}` 90 | } 91 | }); 92 | }); 93 | } 94 | } 95 | 96 | module.exports = { ResetController }; -------------------------------------------------------------------------------- /controllers/users.controller/update.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const { CustomeMessage } = require('../../helpers/customeMessage'); 3 | const { EncryptPassword } = require('../../libs/bcrypt'); 4 | class UpdateUserController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.id = req.params.id; 10 | this.name = req.body.name; 11 | this.username = req.body.username; 12 | this.email = req.body.email; 13 | this.pass = req.body.password; 14 | this.cpassword = req.body.cpassword; 15 | this.handphone = req.body.handphone; 16 | this.update_at = new Date; 17 | this.msg = new CustomeMessage(res); 18 | this.encrypt = EncryptPassword; 19 | } 20 | async Controller() { 21 | 22 | const { 23 | req, 24 | res, 25 | id, 26 | name, 27 | username, 28 | email, 29 | pass, 30 | cpassword, 31 | handphone, 32 | update_at, 33 | msg, 34 | encrypt 35 | } = this; 36 | 37 | const password = encrypt.hashPassword(pass, 10); 38 | 39 | const data = { name, username, email, handphone, update_at, password, cpassword }; 40 | await User.findById(id).then(result => { 41 | 42 | if (!result) { 43 | 44 | msg.error('error', 404, { 45 | 46 | response: { 47 | 48 | status: 'error', 49 | code: 404, 50 | method: req.method, 51 | url: req.url, 52 | message: 'Oops..data not found in database or deleted' 53 | } 54 | }); 55 | 56 | } else { 57 | 58 | return User.updateOne({ _id: id }, {...data }) 59 | } 60 | }).then(doc => { 61 | 62 | if (doc.ok > 0) { 63 | 64 | msg.success('success', 200, { 65 | 66 | response: { 67 | 68 | status: 'success', 69 | code: res.statusCode, 70 | method: req.method, 71 | url: req.url, 72 | message: 'Yeah..data successfully to updated' 73 | } 74 | }); 75 | 76 | } else { 77 | 78 | msg.error('error', 403, { 79 | 80 | response: { 81 | 82 | status: 'error', 83 | code: 404, 84 | method: req.method, 85 | url: req.url, 86 | message: 'Oops..data failed to updated', 87 | data: { result: {...doc } } 88 | } 89 | }); 90 | } 91 | }).catch(err => { 92 | 93 | msg.error('error', 500, { 94 | 95 | response: { 96 | 97 | status: 'error', 98 | code: 500, 99 | method: req.method, 100 | url: req.url, 101 | message: `Internal server error ${err}` 102 | } 103 | }); 104 | }); 105 | } 106 | } 107 | 108 | module.exports = { UpdateUserController }; -------------------------------------------------------------------------------- /controllers/register.controller/activation.controller.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | const User = require('../../models/Users.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | class ActivationController { 5 | constructor(req, res) { 6 | 7 | this.req = req; 8 | this.res = res; 9 | this.email = req.query.email; 10 | this.token = req.query.token; 11 | this.active_token = new Date; 12 | this.msg = new CustomeMessage(res); 13 | } 14 | async Controller() { 15 | 16 | const { req, res, email, token, active_token, msg } = this; 17 | 18 | // check if data already exist or not in database before active_token 19 | await User.findOne({ email: email }).then(result => { 20 | 21 | if (!result) { 22 | 23 | msg.error('error', 404, { 24 | 25 | response: { 26 | 27 | status: 'error', 28 | code: 404, 29 | method: req.method, 30 | url: req.originalUrl, 31 | message: 'Oops..data not found in database or deleted', 32 | } 33 | }); 34 | 35 | } else { 36 | 37 | // check token hash been active or not 38 | if (result.token === null || result.token !== token) { 39 | 40 | msg.error('error', 401, { 41 | 42 | response: { 43 | 44 | status: 'error', 45 | code: 401, 46 | method: req.method, 47 | url: req.originalUrl, 48 | message: 'Oops..Token activation expired, please send new token', 49 | } 50 | }); 51 | 52 | } else { 53 | 54 | // update token in database after activation token successfully 55 | return User.updateOne({ _id: result._id }, { active_token: active_token }); 56 | } 57 | } 58 | }).then(doc => { 59 | 60 | if (doc.ok > 0) { 61 | 62 | msg.success('success', 200, { 63 | 64 | response: { 65 | 66 | status: 'success', 67 | code: res.statusCode, 68 | method: req.method, 69 | url: req.originalUrl, 70 | message: 'Yeah..your account is active, please login http://localhost:3000/login', 71 | } 72 | }); 73 | 74 | } else { 75 | 76 | msg.error('error', 403, { 77 | 78 | response: { 79 | 80 | status: 'error', 81 | code: 403, 82 | method: req.method, 83 | url: req.originalUrl, 84 | message: 'Oops..your account is not active', 85 | } 86 | }); 87 | } 88 | }).catch(err => { 89 | 90 | msg.success('error', 500, { 91 | 92 | response: { 93 | 94 | status: 'error', 95 | code: 500, 96 | method: req.method, 97 | url: req.originalUrl, 98 | message: `Internal server error ${err}`, 99 | } 100 | }); 101 | }); 102 | } 103 | } 104 | 105 | module.exports = { ActivationController }; -------------------------------------------------------------------------------- /middlewares/authRole.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | const Role = require('../models/Roles.model'); 3 | const User = require('../models/Users.model'); 4 | const { CustomeMessage } = require('../helpers/customeMessage'); 5 | module.exports = async(req, res, next) => { 6 | 7 | //init custome message 8 | const msg = new CustomeMessage(res); 9 | 10 | //get token from header 11 | const token = req.headers.authorization.split(' ')[1]; 12 | 13 | //check data already exist or not in database 14 | await User.findOne({ auth_token: token }).populate('role_id', 'name permission').exec(async(err, doc) => { 15 | 16 | if (!doc) { 17 | 18 | return next(); 19 | 20 | } else { 21 | 22 | // check if user permission is value is mahasiswa 23 | 24 | if (doc.permission === 'mahasiswa') { 25 | 26 | // url endpoint validation access feature 27 | 28 | const urlOne = req.originalUrl.replace('user', 'subject'); 29 | const urlTwo = req.originalUrl.replace('role', 'subject'); 30 | const urlThree = req.originalUrl.replace('credit', 'subject'); 31 | 32 | if (req.method === 'GET' && req.originalUrl === urlOne && req.originalUrl === urlTwo && 33 | req.originalUrl === urlThree) { 34 | 35 | // return next section if data is true 36 | return next(); 37 | 38 | } else { 39 | 40 | // message error if user access url is not valid 41 | 42 | msg.error('error', 403, { 43 | 44 | response: { 45 | 46 | status: 'error', 47 | code: 403, 48 | method: req.method, 49 | message: `Oops..your canno't access this feature, your permission ${doc.permission}` 50 | } 51 | }); 52 | } 53 | 54 | } else { 55 | 56 | //check roles permission in database if role premission is dosen 57 | 58 | const role = await Role.findOne({ permission: doc.role_id.permission }); 59 | 60 | // check if user permission is value is dosen 61 | 62 | if (role.permission === 'dosen') { 63 | 64 | // url endpoint validation access feature 65 | 66 | const urlOne = req.originalUrl.replace('user', 'credit'); 67 | const urlTwo = req.originalUrl.replace('role', 'credit'); 68 | 69 | if (req.originalUrl === urlOne && req.originalUrl === urlTwo) { 70 | 71 | // return next section if data is true 72 | 73 | return next(); 74 | 75 | } else { 76 | 77 | // message error if user access url is not valid 78 | 79 | msg.error('error', 401, { 80 | 81 | response: { 82 | 83 | status: 'error', 84 | code: 401, 85 | method: req.method, 86 | message: `Oops..your canno't access this feature, your permission ${doc.role_id.permission}` 87 | } 88 | }); 89 | } 90 | 91 | } else { 92 | 93 | // return next section if data is true 94 | 95 | return next(); 96 | } 97 | } 98 | } 99 | }); 100 | } -------------------------------------------------------------------------------- /controllers/register.controller/login.controller.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | const User = require('../../models/Users.model'); 3 | const { CustomeMessage } = require('../../helpers/customeMessage'); 4 | const { Jwt } = require('../../libs/jwt'); 5 | class LoginController { 6 | constructor(req, res) { 7 | 8 | this.req = req; 9 | this.res = res; 10 | this.username = req.body.username; 11 | this.email = req.body.email; 12 | this.jwt = new Jwt(); 13 | this.msg = new CustomeMessage(res); 14 | } 15 | async Controller() { 16 | 17 | let { req, res, username, email, jwt, msg } = this; 18 | 19 | // check if data already exist or not in database before login to homepage 20 | await User.find({ $or: [{ username: username }, { email: email }] }).lean(true).then(async result => { 21 | 22 | if (!result) { 23 | 24 | msg.error('error', 404, { 25 | 26 | response: { 27 | 28 | status: 'error', 29 | code: 404, 30 | method: req.method, 31 | url: req.originalUrl, 32 | message: `Oops..User Not found please register link below http://localhost:3000/register` 33 | } 34 | }); 35 | 36 | } else { 37 | 38 | // message if account is not activation 39 | 40 | if (result[0]['active_token'] == null) { 41 | 42 | msg.error('success', 403, { 43 | 44 | response: { 45 | 46 | status: 'error', 47 | code: 403, 48 | method: req.method, 49 | url: req.originalUrl, 50 | message: 'Oops...account is not active, please resend token http://localhost:3000/resend' 51 | } 52 | }); 53 | 54 | } else { 55 | 56 | // set token jwt 57 | const token = jwt.createToken({...result[0]['_id'] }, { expiresIn: '1d', algorithm: 'HS384' }); 58 | 59 | // get data from database, for macth token 60 | const getAuthToken = await User.findOne({ email: result[0]['email'] }).lean(true); 61 | 62 | // update token if id is match 63 | await User.updateOne({ _id: getAuthToken._id }, { auth_token: token }); 64 | 65 | // message after login success 66 | msg.success('success', 200, { 67 | 68 | response: { 69 | 70 | status: 'succes', 71 | code: res.statusCode, 72 | method: req.method, 73 | url: req.originalUrl, 74 | message: 'Yeah...Login successfuly', 75 | token: { 76 | secret: token, 77 | expirein: '24hours' 78 | } 79 | } 80 | }); 81 | } 82 | } 83 | }).catch(err => { 84 | 85 | msg.error('error', 500, { 86 | 87 | response: { 88 | 89 | status: 'error', 90 | code: 500, 91 | method: req.method, 92 | url: req.originalUrl, 93 | message: `Internal server error ${err}` 94 | } 95 | }); 96 | }); 97 | } 98 | } 99 | 100 | module.exports = { LoginController }; -------------------------------------------------------------------------------- /controllers/register.controller/forgot.controller.js: -------------------------------------------------------------------------------- 1 | const User = require('../../models/Users.model'); 2 | const sgemail = require('@sendgrid/mail'); 3 | const { ForgotTemplate } = require('../../helpers/forgotTemplate'); 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { Jwt } = require('../../libs/jwt'); 6 | class ForgotController { 7 | constructor(req, res) { 8 | 9 | this.req = req; 10 | this.res = res; 11 | this.username = req.body.username; 12 | this.email = req.body.email; 13 | this.msg = new CustomeMessage(res); 14 | this.mailer = sgemail; 15 | this.date = new Date; 16 | this.jwt = new Jwt(); 17 | this.template; 18 | 19 | } 20 | async Controller() { 21 | 22 | const { req, res, username, email, msg, mailer, date, jwt } = this; 23 | 24 | // check if data already exist or not in database before forgot password 25 | await User.find({ $or: [{ username: username }, { email: email }] }).then(async result => { 26 | 27 | if (!result[0]) { 28 | 29 | msg.error('error', 404, { 30 | 31 | response: { 32 | 33 | status: 'error', 34 | code: 404, 35 | method: req.method, 36 | url: req.originalUrl, 37 | message: 'Oops..data not found in database or deleted' 38 | } 39 | }); 40 | 41 | } else { 42 | 43 | // extract data if data already exist in database 44 | await result.map(async data => { 45 | 46 | // create token jwt 47 | const token = jwt.createToken({ _id: data._id }, { expiresIn: '1d', algorithm: 'HS384' }); 48 | 49 | // set template email before sending to client 50 | this.template = new ForgotTemplate(data['username'], data['email'], date, token); 51 | 52 | // sendgrind api key 53 | mailer.setApiKey(process.env.SG_SECRET_KEY_API); 54 | 55 | // set email message before sending to client 56 | const message = { 57 | 58 | from: 'admin@techgen.com', 59 | to: result[0]['email'], 60 | subject: 'Your token for reset password', 61 | html: this.template.forgotTemplate(), 62 | } 63 | 64 | // sending message to client 65 | mailer.send(message); 66 | 67 | // update token auth after forgot password successfully 68 | await User.updateOne({ _id: data._id }, { auth_token: token }); 69 | 70 | // message after forgot password successfully 71 | msg.success('success', 200, { 72 | 73 | response: { 74 | 75 | status: 'success', 76 | code: res.statusCode, 77 | method: req.method, 78 | message: `Yeah..new password hash been send, please check your ${data['email']}`, 79 | token: { secret: token } 80 | } 81 | }); 82 | }); 83 | } 84 | }).catch(err => { 85 | 86 | msg.error('error', 500, { 87 | 88 | response: { 89 | 90 | status: 'errror', 91 | code: 500, 92 | method: req.method, 93 | url: req.originalUrl, 94 | message: `Internal server error ${err}` 95 | } 96 | }); 97 | }); 98 | } 99 | } 100 | 101 | module.exports = { ForgotController }; -------------------------------------------------------------------------------- /controllers/register.controller/resend.controller.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | const { TokenSecret } = require('../../helpers/token'); 3 | const { EmailTemplate } = require('../../helpers/emailTemplate'); 4 | const { CustomeMessage } = require('../../helpers/customeMessage'); 5 | const { FileSystem } = require('../../helpers/fileSystem'); 6 | const User = require('../../models/Users.model'); 7 | let sgemail = require('@sendgrid/mail'); 8 | class RefeshToken { 9 | constructor(req, res) { 10 | 11 | this.req = req; 12 | this.res = res; 13 | this.email = req.body.email; 14 | this.token = TokenSecret.secretToken(); 15 | this.msg = new CustomeMessage(res); 16 | this.fileSystem = new FileSystem().createFile(this.email); 17 | } 18 | async Controller() { 19 | 20 | const { req, res, email, token, msg } = this; 21 | 22 | // check if email already or not in dabase 23 | await User.findOne({ email: email }).then(async result => { 24 | 25 | if (!result) { 26 | 27 | msg.error('error', 404, { 28 | 29 | response: { 30 | 31 | status: 'Error', 32 | code: 404, 33 | method: req.method, 34 | message: 'Oops..data not found in database or deleted' 35 | } 36 | }); 37 | 38 | } else { 39 | 40 | // get data from body 41 | const { _id, name, email, password, create_at } = result; 42 | 43 | // email template 44 | const template = new EmailTemplate(name, email, password, create_at, token).emailTemplate(); 45 | 46 | // sendgrind api key 47 | sgemail.setApiKey(process.env.SG_SECRET_KEY_API); 48 | 49 | // set message before sending to client 50 | const message = { 51 | 52 | to: email, 53 | from: 'admin@techgen.com', 54 | subject: 'new token activation member', 55 | html: template, 56 | } 57 | 58 | //sending message to client 59 | sgemail.send(message); 60 | 61 | // update token and set back null active_token 62 | return User.updateOne({ _id: _id }, { token: token, active_token: null }); 63 | 64 | } 65 | }).then(doc => { 66 | 67 | if (doc.ok > 0) { 68 | 69 | msg.success('success', 200, { 70 | 71 | response: { 72 | 73 | status: 'sucess', 74 | code: res.statusCode, 75 | method: req.method, 76 | url: req.originalUrl, 77 | message: `new token hash been send to ${email} please check https://mail.google.com/`, 78 | token: { 79 | secret: token 80 | } 81 | } 82 | }); 83 | 84 | } else { 85 | 86 | msg.error('error', 403, { 87 | 88 | response: { 89 | 90 | status: 'error', 91 | code: 403, 92 | method: req.method, 93 | url: req.originalUrl, 94 | message: `Oops..new token failed to send ${email}`, 95 | } 96 | }); 97 | } 98 | }).catch(err => { 99 | 100 | msg.error('error', 500, { 101 | 102 | response: { 103 | 104 | status: 'error', 105 | code: 500, 106 | method: req.method, 107 | url: req.originalUrl, 108 | message: `Internal server error ${err}` 109 | } 110 | }); 111 | }); 112 | } 113 | } 114 | 115 | module.exports = { RefeshToken }; -------------------------------------------------------------------------------- /routes/defaults.route.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | // register route 3 | 4 | const { Parallel } = require('../helpers/runParallel'); 5 | 6 | const LoginUsersRoute = require('../routes/register.route/login.route'); 7 | const RegisterUsersRoute = require('../routes/register.route/register.route'); 8 | const ActivationUsersRoute = require('../routes/register.route/activation.route'); 9 | const ResendTokenUserRoute = require('../routes/register.route/resend.route'); 10 | const ForgotPasswordUserRoute = require('../routes/register.route/forgot.route'); 11 | const ResetPasswordUserRoute = require('../routes/register.route/reset.route'); 12 | 13 | //role route 14 | const CreateRolesRoute = require('../routes/roles.route/create.route'); 15 | const ResultRolesRoute = require('../routes/roles.route/result.route'); 16 | const ResultsRolesRoute = require('../routes/roles.route/results.route'); 17 | const DeleteRolesRoute = require('../routes/roles.route/delete.route'); 18 | const UpdateRolesRoute = require('../routes/roles.route/update.route'); 19 | 20 | // user route 21 | const CreateUserRoute = require('../routes/users.route/create.route'); 22 | const ResultsUserRoute = require('../routes/users.route/results.route'); 23 | const ResultUserRoute = require('../routes/users.route/result.route'); 24 | const DeleteUserRoute = require('../routes/users.route/delete.route'); 25 | const UpdateUserRoute = require('../routes/users.route/update.route'); 26 | 27 | // credits route 28 | const CreateCreditsRoute = require('../routes/credits.route/create.route'); 29 | const ResultsCreditsRoute = require('../routes/credits.route/results.route'); 30 | const ResultCreditsRoute = require('../routes/credits.route/result.route'); 31 | const DeleteCreditsRoute = require('../routes/credits.route/delete.route'); 32 | const UpdateCreditsRoute = require('../routes/credits.route/update.route'); 33 | 34 | // subject routes 35 | const CreateSubjectRoute = require('../routes/subjects.route/create.route'); 36 | const ResultsSubjectRoute = require('../routes/subjects.route/results.route'); 37 | const ResultSubjectRoute = require('../routes/subjects.route/result.route'); 38 | const DeleteSubjectRoute = require('../routes/subjects.route/delete.route'); 39 | const UpdateSubjectRoute = require('../routes/subjects.route/update.route'); 40 | 41 | class DefaultRoutes { 42 | constructor(app) { 43 | 44 | this.app = app; 45 | } 46 | 47 | // function default route controller in here 48 | Routes() { 49 | 50 | const { app } = this; 51 | 52 | app.use('/', Parallel.run([ 53 | 54 | //init register routes 55 | LoginUsersRoute, 56 | RegisterUsersRoute, 57 | ActivationUsersRoute, 58 | ResendTokenUserRoute, 59 | ForgotPasswordUserRoute, 60 | ResetPasswordUserRoute, 61 | 62 | //init user routes 63 | CreateUserRoute, 64 | ResultsUserRoute, 65 | ResultUserRoute, 66 | DeleteUserRoute, 67 | UpdateUserRoute, 68 | 69 | //init register routes 70 | CreateRolesRoute, 71 | ResultRolesRoute, 72 | ResultsRolesRoute, 73 | DeleteRolesRoute, 74 | UpdateRolesRoute, 75 | 76 | //init credits routes 77 | CreateCreditsRoute, 78 | ResultsCreditsRoute, 79 | ResultCreditsRoute, 80 | DeleteCreditsRoute, 81 | UpdateCreditsRoute, 82 | 83 | //init credits routes 84 | CreateSubjectRoute, 85 | ResultsSubjectRoute, 86 | ResultSubjectRoute, 87 | DeleteSubjectRoute, 88 | UpdateSubjectRoute 89 | 90 | ])); 91 | 92 | // init roles routes 93 | // app.use('/role', CreateRolesRoute); 94 | // app.use('/role', ResultRolesRoute); 95 | // app.use('/role', ResultsRolesRoute); 96 | // app.use('/role', UpdateRolesRoute); 97 | // app.use('/role', DeleteRolesRoute); 98 | 99 | // //init register routes 100 | // app.use('/login', LoginUsersRoute); 101 | // app.use('/register', RegisterUsersRoute); 102 | // app.use('/activation', ActivationUsersRoute); 103 | // app.use('/resendtoken', ResendTokenUserRoute); 104 | // app.use('/forgotpassword', ForgotPasswordUserRoute); 105 | // app.use('/resetpassword', ResetPasswordUserRoute); 106 | 107 | // //init user routes 108 | // app.use('/user', CreateUserRoute); 109 | // app.use('/', ResultsUserRoute); 110 | // app.use('/user', ResultUserRoute); 111 | // app.use('/user', DeleteUserRoute); 112 | // app.use('/user', UpdateUserRoute); 113 | 114 | // //init credits routes 115 | // app.use('/credit', CreateCreditsRoute); 116 | // app.use('/credit', ResultsCreditsRoute); 117 | // app.use('/credit', ResultCreditsRoute); 118 | // app.use('/credit', DeleteCreditsRoute); 119 | // app.use('/credit', UpdateCreditsRoute); 120 | 121 | // //init credits routes 122 | // app.use('/subject', CreateSubjectRoute); 123 | // app.use('/subject', ResultsSubjectRoute); 124 | // app.use('/subject', ResultSubjectRoute); 125 | // app.use('/subject', DeleteSubjectRoute); 126 | // app.use('/subject', UpdateSubjectRoute); 127 | } 128 | } 129 | 130 | module.exports = { DefaultRoutes }; -------------------------------------------------------------------------------- /helpers/forgotTemplate.js: -------------------------------------------------------------------------------- 1 | class ForgotTemplate { 2 | constructor(username, email, date_at, token) { 3 | 4 | this.username = username; 5 | this.email = email; 6 | this.date_at = date_at; 7 | this.token = token; 8 | } 9 | 10 | // forgot password template 11 | forgotTemplate() { 12 | 13 | const { username, email, date_at, token } = this; 14 | 15 | return ` 16 | 17 | 18 | 19 |
20 |Hello Dear ${username}
150 |Kepada member YTH 151 | berikut adalah account anda:
152 |Username: ${username}
154 |Email: ${email}
155 |Date: ${date_at}
156 |Token: ${token}
157 |Hello Dear ${name}
151 |Kepada member YTH 152 | berikut adalah account anda:
153 |Email: ${email}
155 |Password: ${password}
156 |Create_At: ${create_at}
157 |Token: ${token}
158 |