Skip to content

Commit 0cd3193

Browse files
Merge pull request Human-Connection#22 from Human-Connection/feature/password-reset
Feature/password reset
2 parents 4321d56 + 25af919 commit 0cd3193

File tree

9 files changed

+126
-32
lines changed

9 files changed

+126
-32
lines changed

config/local.example.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,9 @@
44
"baseURL": "http://localhost:3030",
55
"frontURL": "http://localhost:3000",
66
"smtpConfig": {
7-
"host": "localhost",
7+
"host": "0.0.0.0",
88
"port": 1025,
9-
"secure": false,
10-
"ignoreTLS": true,
11-
"auth": {
12-
"user": "",
13-
"pass": ""
14-
}
9+
"ignoreTLS": true
1510
},
1611
"thumbor": {
1712
"url": "",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@import '../../layout/common';
1+
@import '../../../layout/common';
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@import '../../layout/common';
1+
@import '../../../layout/common';

email-templates/account/reset-password/de/html.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
</tr>
2121
<tr>
2222
<td class="aligncenter content-block">
23-
Wenn du diese Nachricht ignorierst bleibt dein passwort wie es ist.
23+
Wenn du diese Nachricht ignorierst, bleibt dein Passwort wie es ist.
2424
</td>
2525
</tr>
2626
<tr>
2727
<td class="aligncenter content-block" itemprop="handler" itemscope itemtype="http://schema.org/HttpActionHandler">
28-
Wenn du es nicht warst der dein Passwort zurücksetzen wollte <a href='mailto:{{returnEmail}}?subject=I did not reset my password&body=Someone unauthorized sent this reset password request.'>lass es uns wissen!</a>
28+
Wenn du es nicht warst, der dein Passwort zurücksetzen wollte, <a href='mailto:{{returnEmail}}?subject=I did not reset my password&body=Someone unauthorized sent this reset password request.'>lass es uns wissen!</a>
2929
</td>
3030
</tr>
3131
<tr>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@import '../../layout/common';
1+
@import '../../../layout/common';
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@import '../../layout/common';
1+
@import '../../../layout/common';

server/services/auth-management/notifier.js

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,33 @@ module.exports = function (app) {
3737
)
3838
);
3939

40+
let language = user.userSettings ? user.userSettings.uiLanguage : user.language || 'en';
41+
4042
const templatePath = path.join(
4143
__dirname,
4244
'../../../email-templates/account',
4345
templatename,
44-
user.language || 'en'
46+
language
4547
);
4648

47-
const hashLink = getLink(linktype, user.verifyToken || null);
49+
let token;
50+
51+
switch (linktype) {
52+
case 'invite-email':
53+
token = user.verifyToken;
54+
break;
55+
case 'verify':
56+
token = user.verifyToken;
57+
break;
58+
case 'reset':
59+
token = user.resetToken;
60+
break;
61+
case 'verifyChanges':
62+
token = user.changeToken;
63+
break;
64+
}
65+
66+
const hashLink = getLink(linktype, token || null);
4867
const frontURL = app.get('frontURL');
4968
const backURL = app.get('baseURL');
5069

@@ -62,7 +81,7 @@ module.exports = function (app) {
6281
name: user.name || user.email,
6382
email: user.email,
6483
code: user.code || null,
65-
language: user.language || 'en',
84+
language: language,
6685
link: hashLink,
6786
returnEmail: returnEmail,
6887
frontURL,
@@ -95,9 +114,7 @@ module.exports = function (app) {
95114
if (app.get('debug')) {
96115
const filename = String(Date.now()) + '.html';
97116
const filepath = path.join(__dirname, '../../../tmp/emails/', filename);
98-
fs.outputFile(filepath, email.html).catch(err => {
99-
app.error('Error saving email', err);
100-
});
117+
fs.outputFileSync(filepath, email.html);
101118
}
102119

103120
return app
@@ -124,23 +141,31 @@ module.exports = function (app) {
124141
user
125142
);
126143
case 'resendVerifySignup':
127-
return buildEmail('verify-email', 'Confirm signup', 'verify', user);
144+
return buildEmail(
145+
'verify-email',
146+
'Confirm signup',
147+
'verify',
148+
user);
128149
case 'verifySignup':
129150
return buildEmail(
130151
'email-verified',
131152
'Email address verified',
132153
'verify',
133154
user
134155
);
135-
case 'resetPwd':
136-
return buildEmail('reset-password', 'Password reset', 'reset', user);
137156
case 'sendResetPwd':
138157
return buildEmail(
139-
'password-was-reset',
140-
'Your password was reset',
158+
'reset-password',
159+
'Password reset',
141160
'reset',
142161
user
143162
);
163+
case 'resetPwd':
164+
return buildEmail(
165+
'password-reset',
166+
'Your password was reset',
167+
'reset',
168+
user);
144169
case 'passwordChange':
145170
return buildEmail(
146171
'password-change',

server/services/users/users.hooks.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,25 @@ const candosSchema = {
4949
}
5050
};
5151

52+
const userSettingsPrivateSchema = {
53+
include: {
54+
service: 'usersettings',
55+
nameAs: 'userSettings',
56+
parentField: '_id',
57+
childField: 'userId',
58+
asArray: false
59+
}
60+
};
61+
5262
const userSettingsSchema = {
5363
include: {
5464
service: 'usersettings',
5565
nameAs: 'userSettings',
5666
parentField: '_id',
5767
childField: 'userId',
68+
query: {
69+
$select: ['uiLanguage', 'contentLanguages'],
70+
},
5871
asArray: false
5972
}
6073
};
@@ -139,6 +152,7 @@ module.exports = {
139152
all: [
140153
populate({ schema: badgesSchema }),
141154
populate({ schema: candosSchema }),
155+
populate({ schema: userSettingsSchema }),
142156
cleanupBasicData
143157
],
144158
find: [
@@ -147,15 +161,12 @@ module.exports = {
147161
],
148162
get: [
149163
thumbnails(thumbnailOptions),
150-
151164
// remove personal data if its not the current authenticated user
152-
iff(isProvider('external'),
153-
when(isOwnEntry(false), [
154-
cleanupPersonalData
155-
])
165+
iff(isOwnEntry(false),
166+
cleanupPersonalData,
156167
),
157168
iff(isOwnEntry(),
158-
populate({ schema: userSettingsSchema })
169+
populate({ schema: userSettingsPrivateSchema })
159170
)
160171
],
161172
create: [

test/services/auth-management.test.js

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,73 @@
11
const assert = require('assert');
22
const app = require('../../server/app');
3+
const service = app.service('authManagement');
4+
const userService = app.service('users');
5+
const fs = require('fs-extra');
6+
const path = require('path');
7+
const cheerio = require('cheerio');
8+
let user = null;
39

410
describe('\'authManagement\' service', () => {
5-
it('registered the service', () => {
6-
const service = app.service('authManagement');
11+
before(function(done) {
12+
this.server = app.listen(3031);
13+
this.server.once('listening', () => done());
14+
});
15+
16+
after(function(done) {
17+
this.server.close(done);
18+
});
19+
20+
beforeEach(async () => {
21+
await app.get('mongooseClient').connection.dropDatabase();
22+
user = await userService.create({
23+
24+
password: '1234',
25+
name: 'Peter',
26+
role: 'admin'
27+
});
28+
});
29+
30+
afterEach(async () => {
31+
await app.get('mongooseClient').connection.dropDatabase();
32+
user = null;
33+
});
734

35+
it('registered the service', () => {
836
assert.ok(service, 'Registered the service');
937
});
38+
39+
it('can reset password', async () => {
40+
await service.create({
41+
action: 'sendResetPwd',
42+
value: {
43+
email: user.email
44+
}
45+
});
46+
47+
const token = await getTokenFromMail();
48+
49+
const result = await service.create({
50+
action: 'resetPwdLong',
51+
value: {
52+
token,
53+
password: '123456'
54+
}
55+
});
56+
assert.ok(result, 'password can be reset');
57+
});
1058
});
59+
60+
const getTokenFromMail = async () => {
61+
// Get token from tmp email file
62+
const mailDir = path.join(__dirname, '../../tmp/emails');
63+
const fileName = await fs.readdirSync(mailDir)[0];
64+
const mailFile = path.join(mailDir, fileName);
65+
const mailContent = await fs.readFileSync(mailFile, 'utf8');
66+
const $ = await cheerio.load(mailContent);
67+
let url;
68+
await $('a.btn-primary').each((i, el) => {
69+
url = el.attribs['href'];
70+
});
71+
const token = url.split('/').pop();
72+
return token;
73+
};

0 commit comments

Comments
 (0)