@igea/oac_backend 1.0.26 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@igea/oac_backend",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Backend service for the OAC project",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -2,7 +2,7 @@
2
2
  "protocol": "http",
3
3
  "url_register": "http://localhost:4001/register",
4
4
  "port_range": {
5
- "min": 5000, "max": 6000
5
+ "min": 4100, "max": 4199
6
6
  },
7
7
  "database": {
8
8
  "host": "127.0.0.1",
@@ -23,12 +23,18 @@
23
23
  },
24
24
  "jwt_secret": "@igea#",
25
25
  "smtp": {
26
- "host": "smtp.aruba.it",
26
+ "host": "smtps.aruba.it",
27
27
  "port": 465,
28
28
  "secure": true,
29
29
  "auth": {
30
- "user": "your_smtp_user",
31
- "pass": "your_smtp_password"
30
+ "user": "supporto@igea-soluzioni.it",
31
+ "pass": "<your_smtp_password>"
32
32
  }
33
+ },
34
+ "exposed":{
35
+ "protocol": "http",
36
+ "host": "localhost",
37
+ "port": "4000"
33
38
  }
39
+
34
40
  }
@@ -2,7 +2,7 @@
2
2
  "protocol": "http",
3
3
  "url_register": "http://localhost:4001/register",
4
4
  "port_range": {
5
- "min": 5000, "max": 6000
5
+ "min": 4100, "max": 4199
6
6
  },
7
7
  "database": {
8
8
  "host": "127.0.0.1",
@@ -27,8 +27,13 @@
27
27
  "port": 465,
28
28
  "secure": true,
29
29
  "auth": {
30
- "user": "your_smtp_user",
31
- "pass": "your_smtp_password"
30
+ "user": "supporto@igea-soluzioni.it",
31
+ "pass": "<your_smtp_password>"
32
32
  }
33
+ },
34
+ "exposed":{
35
+ "protocol": "http",
36
+ "host": "localhost",
37
+ "port": "4000"
33
38
  }
34
39
  }
@@ -1,6 +1,12 @@
1
1
  const express = require('express');
2
2
  const router = express.Router();
3
3
  const Users = require('../models/users');
4
+ const EmailSender = require('../models/EmailSender');
5
+ const config = require('../config');
6
+ const EXPOSED = config.exposed || {};
7
+ const { randomUUID } = require('crypto');
8
+
9
+
4
10
 
5
11
  module.exports = function(jwtLib){
6
12
  /**
@@ -67,6 +73,39 @@ module.exports = function(jwtLib){
67
73
  });
68
74
  });
69
75
 
76
+ router.post('/password_recovery', (req, res) => {
77
+ let body = req.body
78
+ let user_or_email = body.user
79
+ Users.fromUserOrEmail(user_or_email)
80
+ .then(async response => {
81
+ let email = response.email
82
+ console.log(`Send email to ${email} with recovery instructions`)
83
+ const token = randomUUID();
84
+ await Users.setPasswordRecoveryToken(response.id, token)
85
+ const activationLink = `${EXPOSED.protocol}://${EXPOSED.host}:${EXPOSED.port}/frontend/users/reset_password/${response.id}/${token}`
86
+ EmailSender.sendPasswordRecoveryEmail(
87
+ email, activationLink
88
+ ).then( () => {
89
+ console.log("Email sent")
90
+ res.json({
91
+ success: true
92
+ });
93
+ }).catch( err => {
94
+ console.log("Error sending email", err)
95
+ res.json({
96
+ success: false,
97
+ message: `${ err }`
98
+ });
99
+ })
100
+ }).catch(err => {
101
+ console.log(err)
102
+ res.json({
103
+ success: false,
104
+ message: `${ err }`
105
+ });
106
+ })
107
+ })
108
+
70
109
  return router
71
110
 
72
111
  }
package/src/index.js CHANGED
@@ -9,10 +9,10 @@ const jwtLib = jwtLibFactory({
9
9
  secret: process.env.JWT_SECRET || config.jwt_secret,
10
10
  excludePaths: [
11
11
  `/${serviceName}/auth/authenticate`,
12
+ `/${serviceName}/auth/password_recovery`,
12
13
  `/${serviceName}/auth/echo`,
13
14
  `/${serviceName}/health`,
14
15
  `/${serviceName}/fuseki/upload/vocabularies`
15
-
16
16
  ],
17
17
  signOptions: { expiresIn: '15m' }
18
18
  });
@@ -0,0 +1,52 @@
1
+ const nodemailer = require('nodemailer');
2
+ const config = require('../config');
3
+ const SMTP = config.smtp || {};
4
+
5
+ class EmailSender {
6
+
7
+ static sendPasswordRecoveryEmail(userEmail, recoveryLink) {
8
+ // Logic to send email
9
+ console.log(`Sending password recovery email to ${userEmail} with link: ${recoveryLink}`);
10
+ return this.sendEmail(userEmail, {
11
+ subject: 'Password Recovery Instructions',
12
+ text: `Please use the following link to recover your password: ${recoveryLink}`,
13
+ html: `<p>Please use the following link to recover your password:</p><a href="${recoveryLink}">${recoveryLink}</a>`
14
+ });
15
+ }
16
+
17
+ static sendEmail(email, message) {
18
+ return new Promise(async (resolve, reject) => {
19
+ try {
20
+ const smtpOptions = {
21
+ host: SMTP.host,
22
+ port: SMTP.port,
23
+ secure: SMTP.secure, // true for 465, false for other ports
24
+ auth: {
25
+ user: SMTP.auth.user,
26
+ pass: SMTP.auth.pass,
27
+ }
28
+ }
29
+ console.log(smtpOptions)
30
+ let transporter = nodemailer.createTransport(smtpOptions);
31
+
32
+ let mailOptions = {
33
+ from: `"OAC" <${SMTP.auth.user}>`, // sender address
34
+ to: email, // list of receivers
35
+ subject: message.subject, // Subject line
36
+ text: message.text, // plain text body
37
+ html: message.html, // html body
38
+ };
39
+
40
+ let info = await transporter.sendMail(mailOptions);
41
+ console.log('Message sent: %s', info.messageId);
42
+ resolve(info);
43
+ } catch (error) {
44
+ console.error('Error sending email:', error);
45
+ reject(error);
46
+ }
47
+ });
48
+ }
49
+
50
+ }
51
+
52
+ module.exports = EmailSender;
@@ -34,6 +34,30 @@ class Users {
34
34
  }
35
35
  });
36
36
  }
37
+
38
+ static fromUserOrEmail(userOrEmail){
39
+
40
+ return new Promise(async (resolve, reject) => {
41
+ try{
42
+ let userFound = await db(table)
43
+ .where(function() {
44
+ this.whereRaw(
45
+ '(username = ? OR email = ?)',
46
+ [userOrEmail, userOrEmail]
47
+ );
48
+ })
49
+ .first();
50
+ if(userFound && userFound["is_active"]) {
51
+ delete userFound["password"]
52
+ resolve(userFound)
53
+ }else{
54
+ reject(new Error("User not found or not active"))
55
+ }
56
+ }catch(e){
57
+ reject(e)
58
+ }
59
+ });
60
+ }
37
61
 
38
62
  static find(id){
39
63
  return new Promise(async (resolve, reject) => {
@@ -99,46 +123,20 @@ class Users {
99
123
  });
100
124
  }
101
125
 
102
- static sendResetPassword(user_or_email, resetToken, resetLink) {
126
+ static setPasswordRecoveryToken(id, resetToken) {
103
127
  return new Promise(async (resolve, reject) => {
104
- let user = null;
105
128
  try {
106
- user = await db(table)
107
- .where(function() {
108
- this.where('username', user_or_email)
109
- .orWhere('email', user_or_email);
110
- })
111
- .first();
112
- } catch (e) {
113
- return reject(e);
114
- }
115
- if(!user){
116
- return resolve();
117
- }
118
-
119
- // TODO:
120
- // Here we have to store the resetToken and expiration date (utc)
121
- // in the database associated with the user
122
-
123
- // Send the email
124
- try{
125
- const smtpConfig = config.smtp;
126
- let transporter = nodemailer.createTransport(smtpConfig);
127
- let mailOptions = {
128
- from: smtpConfig.auth.user,
129
- to: user.email,
130
- subject: 'Password Reset',
131
- text: `Hello ${user.name},\n\nYou can reset your password using the following link:\n${resetLink}\n\nIf you did not request a password reset, please ignore this email.\n\nBest regards,\nYour Company`
132
- };
133
- transporter.sendMail(mailOptions, (error, info) => {
134
- if (error) {
135
- return reject(error);
136
- }
137
- resolve();
129
+ let count = await db(table)
130
+ .where({ id })
131
+ .update({
132
+ id,
133
+ reset_token: resetToken,
134
+ reset_token_expiration: Math.ceil((new Date().getTime())/1000)
138
135
  });
139
- }catch(e){
140
- reject(e)
141
- }
136
+ resolve();
137
+ } catch (e) {
138
+ reject(e);
139
+ }
142
140
  });
143
141
  }
144
142