var bcrypt = require('bcrypt'); var salt = bcrypt.genSaltSync(10); var path = require('path'); const api_version = path.resolve(__dirname, '..').split(path.sep).pop(); const jwt = require('jsonwebtoken') const { passwordEmail, register } = require('../utils/email') const fs = require('fs'); var uuid = require('uuid'); const tokenSecret = fs.readFileSync(path.resolve( __dirname, '..', 'utils/files/secret-token.key') , { encoding: 'utf-8' }); class auth { constructor(connection) { this.connection = connection } async signin(application, req) { try { const base64Credentials = req.headers.authorization.split(' ')[1]; const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii'); var credentialArray = credentials.split(':'); var email = credentialArray[0]; var pwd = credentialArray[1]; var userModel = await new application.app[api_version].models.user(this.connection); var data = await userModel.getOne({ email: email }) if (data != null) { if (bcrypt.compareSync(pwd, data.password)) { return await this.generateToken(data); } else { return { code: 401, error: 'Unauthorized access' } } } else { return { code: 401, error: 'Unauthorized access' } } } catch (error) { console.log("error model auth signin --> " + error); return { code: 500, error: 'Internal Server Error' } } } async signup(application, req) { try { var email = req.body.email; var pwd = bcrypt.hashSync(req.body.password, salt) var userModel = new application.app[api_version].models.user(this.connection); var data = await userModel.insertOne(email, pwd) if (data.code == 200) { var mailOptions = { from: 'demo@andrealmeida.net', to: email, sub: 'demo: registo completo 🚀' }; await register(mailOptions.from, mailOptions.to, mailOptions) return { code: 200, 'message': 'User created sucessfully!' }; } else { return { code: data.code, error: data.error } } } catch (error) { console.log("error model auth signup --> " + error.stack); return { code: 500, error: 'Internal Server Error' } } } async requestpassword(application, req) { try { var user_model = new application.app[api_version].models.user(this.connection); var data = await user_model.getOne({ email: req.body.email }) if (data != null) { let now = new Date() let ts = now.getTime() / 1000 let randomUUID = uuid.v1() + "_" + Math.floor(ts); let confirmUUID = await user_model.getOne({ 'recover_token': randomUUID }) if (confirmUUID == null) { data.recover_token = randomUUID data.recover_token_update = ts await data.save() var mailOptions = { from: 'demo@andrealmeida.net', to: data.email, recover_token: data.recover_token, sub: 'demo: recuperação de conta 🚀' }; await passwordEmail(mailOptions.from, mailOptions.to, mailOptions) return { code: 200, message: "Email sent" } } else { return { code: 400, error: 'Bad Request' } } } else { return { code: 400, error: 'Bad Request' } } } catch (error) { console.log("error requestpassword --> " + error); return { code: 500, error: 'Internal Server Error' } } } async recoverpassword(application, req) { try { var user_model = new application.app[api_version].models.user(this.connection); var data = await user_model.getOne({ 'email': req.body.email, 'recover_token': req.body.recover_token }) if (data != null) { data.password = bcrypt.hashSync(req.body.password, salt) data.recover_password = null; data.recover_token = null data.recover_token_update = null await data.save() return await this.generateToken(data) } else { return { code: 400, error: 'Bad Request' } } } catch (error) { console.log("error recoverpassword --> " + error); return { code: 500, error: 'Internal Server Error' } } } async changepassword(application, req) { try { var user_model = new application.app[api_version].models.user(this.connection); const auth_token = req.headers.hasOwnProperty('auth_token') ? req.headers.auth_token : req.headers.authorization var data = await user_model.getOne({ 'auth_token': auth_token, 'email': req.body.email }) if (data != null) { data.password = bcrypt.hashSync(req.body.password, salt) await data.save() return await this.generateToken(data) } else { return { code: 400, error: 'Bad Request' } } } catch (error) { console.log("error changepassword --> " + error); return { code: 500, error: 'Internal Server Error' } } } async generateToken(user_model) { let now = new Date() let ts = Math.floor(now / 1000) let auth_expire = 60 * 60 // 1 hour var auth_token = jwt.sign({ id: user_model.id }, tokenSecret, { expiresIn: auth_expire }); user_model.auth_token = auth_token user_model.auth_token_update = ts await user_model.save() return { code: 200, result: { "user": { "id": user_model.id, "email": user_model.email, }, "auth": { "token": auth_token, "created": ts, "expires": ts + auth_expire } } } } async deleteaccount(application, req) { try { const auth_token = req.headers.hasOwnProperty('auth_token') ? req.headers.auth_token : req.headers.authorization var userModel = new application.app[api_version].models.user(this.connection); let result = await userModel.deleteOne(auth_token) if (result.code === 200) { return { code: result.code, 'message': 'User deleted successfully!' }; } else { return { code: 400, error: 'User not found' } } } catch (error) { console.log("error model auth signup --> " + error.stack); return { code: 500, error: 'Internal Server Error' } } } } module.exports = function (application) { return auth; }