Skip to content

Commit a44dafa

Browse files
committed
email verification OTP
1 parent ff5390a commit a44dafa

15 files changed

+334
-168
lines changed

packages/backend/src/config/getDeliveryServiceProperties.test.ts

+30-31
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,12 @@ describe('ReadDeliveryServiceProperties', () => {
2121
messageTTL: 12345,
2222
sizeLimit: 456,
2323
notificationChannel: [],
24-
smtpHost: 'smtp.host',
25-
smtpPort: 587,
26-
smtpEmail: '[email protected]',
27-
smtpUsername: '[email protected]',
28-
smtpPassword: 'dm312345',
2924
});
3025

3126
expect(config).toStrictEqual({
3227
messageTTL: 12345,
3328
sizeLimit: 456,
3429
notificationChannel: [],
35-
smtpHost: 'smtp.host',
36-
smtpPort: 587,
37-
smtpEmail: '[email protected]',
38-
smtpUsername: '[email protected]',
39-
smtpPassword: 'dm312345',
4030
});
4131
});
4232

@@ -61,11 +51,6 @@ describe('ReadDeliveryServiceProperties', () => {
6151
},
6252
},
6353
],
64-
smtpHost: 'smtp.host',
65-
smtpPort: 587,
66-
smtpEmail: '[email protected]',
67-
smtpUsername: '[email protected]',
68-
smtpPassword: 'dm312345',
6954
}),
7055
{ encoding: 'utf-8' },
7156
);
@@ -89,23 +74,28 @@ describe('ReadDeliveryServiceProperties', () => {
8974
},
9075
},
9176
],
92-
smtpHost: 'smtp.host',
93-
smtpPort: 587,
94-
smtpEmail: '[email protected]',
95-
smtpUsername: '[email protected]',
96-
smtpPassword: 'dm312345',
9777
});
9878
});
9979
it('Adds default properties if config.yml is not fully specified', () => {
10080
writeFileSync(
10181
path,
10282
stringify({
10383
messageTTL: 12345,
104-
smtpHost: 'smtp.host',
105-
smtpPort: 587,
106-
smtpEmail: '[email protected]',
107-
smtpUsername: '[email protected]',
108-
smtpPassword: 'dm312345',
84+
notificationChannel: [
85+
{
86+
type: NotificationChannelType.EMAIL,
87+
config: {
88+
host: 'mail.alice.com',
89+
port: 465,
90+
secure: true,
91+
auth: {
92+
user: 'foo',
93+
pass: 'bar',
94+
},
95+
senderAddress: '[email protected]',
96+
},
97+
},
98+
],
10999
}),
110100
{ encoding: 'utf-8' },
111101
);
@@ -114,12 +104,21 @@ describe('ReadDeliveryServiceProperties', () => {
114104
expect(config).toStrictEqual({
115105
messageTTL: 12345,
116106
sizeLimit: 100000,
117-
notificationChannel: [],
118-
smtpHost: 'smtp.host',
119-
smtpPort: 587,
120-
smtpEmail: '[email protected]',
121-
smtpUsername: '[email protected]',
122-
smtpPassword: 'dm312345',
107+
notificationChannel: [
108+
{
109+
type: NotificationChannelType.EMAIL,
110+
config: {
111+
host: 'mail.alice.com',
112+
port: 465,
113+
secure: true,
114+
auth: {
115+
user: 'foo',
116+
pass: 'bar',
117+
},
118+
senderAddress: '[email protected]',
119+
},
120+
},
121+
],
123122
});
124123
});
125124
});

packages/backend/src/config/getDeliveryServiceProperties.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@ import { parse } from 'yaml';
22
import { existsSync, readFileSync } from 'fs';
33
import { resolve } from 'path';
44
import { logInfo, validateSchema } from '@dm3-org/dm3-lib-shared';
5-
import { schema, DeliveryServiceProperties } from '@dm3-org/dm3-lib-delivery';
5+
import {
6+
schema,
7+
DeliveryServiceProperties,
8+
NotificationChannelType,
9+
} from '@dm3-org/dm3-lib-delivery';
610

711
const DEFAULT_CONFIG_FILE_PATH = resolve(__dirname, './../config.yml');
812
const DEFAULT_DELIVERY_SERVICE_PROPERTIES: DeliveryServiceProperties = {
913
messageTTL: 0,
1014
//100Kb
1115
sizeLimit: 100000,
12-
notificationChannel: [],
13-
smtpHost: '',
14-
smtpPort: 0,
15-
smtpEmail: '',
16-
smtpUsername: '',
17-
smtpPassword: '',
16+
notificationChannel: [
17+
{
18+
type: NotificationChannelType.EMAIL,
19+
config: {
20+
smtpHost: 'smtp.gmail.com',
21+
smtpPort: 587,
22+
smtpEmail: '[email protected]',
23+
smtpUsername: '[email protected]',
24+
smtpPassword: 'ujxe wvic zpfz dzgs',
25+
},
26+
},
27+
],
1828
};
1929

2030
export function getDeliveryServiceProperties(

packages/backend/src/notifications.test.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ describe('Notifications', () => {
250250

251251
const token = await createAuthToken();
252252

253+
const addNewNotificationChannelMock = jest.fn();
253254
const addUsersNotificationChannelMock = jest.fn();
255+
const setOtpMock = jest.fn();
254256

255257
app.locals.db = {
256258
getSession: async (ensName: string) =>
@@ -265,7 +267,20 @@ describe('Notifications', () => {
265267
getIdEnsName: async (ensName: string) => ensName,
266268
getGlobalNotification: async (ensName: string) =>
267269
Promise.resolve({ isEnabled: true }),
270+
getUsersNotificationChannels: async (ensName: string) =>
271+
Promise.resolve([
272+
{
273+
type: NotificationChannelType.EMAIL,
274+
config: {
275+
recipientValue: '[email protected]',
276+
isEnabled: true,
277+
isVerified: false,
278+
},
279+
},
280+
]),
281+
addNewNotificationChannel: addNewNotificationChannelMock,
268282
addUsersNotificationChannel: addUsersNotificationChannelMock,
283+
setOtp: setOtpMock,
269284
};
270285
app.locals.web3Provider = {
271286
resolveName: async () =>
@@ -283,15 +298,6 @@ describe('Notifications', () => {
283298
});
284299

285300
expect(status).toBe(200);
286-
expect(addUsersNotificationChannelMock).toHaveBeenCalledWith(
287-
'bob.eth',
288-
{
289-
type: 'EMAIL',
290-
config: {
291-
recipientValue: '[email protected]',
292-
},
293-
},
294-
);
295301
});
296302
});
297303

packages/backend/src/notifications.ts

+6-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { normalizeEnsName } from '@dm3-org/dm3-lib-profile';
44
import express from 'express';
55
import { auth } from './utils';
66
import { validateNotificationChannel } from './validation/notification/notificationChannelValidation';
7-
import { generateEmailVerificationNotification } from '@dm3-org/dm3-lib-delivery';
7+
import { addNewNotificationChannel } from '@dm3-org/dm3-lib-delivery';
8+
import { getDeliveryServiceProperties } from './config/getDeliveryServiceProperties';
89

910
// Exporting a function that returns an Express router
1011
export default () => {
@@ -92,19 +93,14 @@ export default () => {
9293
error: 'Global notifications is off',
9394
});
9495
} else {
95-
// Adding a user's notification channel to the database
96-
await req.app.locals.db.addUsersNotificationChannel(account, {
97-
type: notificationChannelType,
98-
config: {
99-
recipientValue: recipientValue,
100-
},
101-
});
102-
10396
// send OTP for email verification
104-
await generateEmailVerificationNotification(
97+
await addNewNotificationChannel(
10598
notificationChannelType,
99+
recipientValue,
106100
account,
101+
getDeliveryServiceProperties().notificationChannel,
107102
req.app.locals.db.getUsersNotificationChannels,
103+
req.app.locals.db.addUsersNotificationChannel,
108104
req.app.locals.db.setOtp,
109105
);
110106

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { NotificationChannelType } from '@dm3-org/dm3-lib-delivery';
2+
import { IDatabase, Redis, getDatabase, getRedisClient } from '../getDatabase';
3+
import winston from 'winston';
4+
5+
const USER_ADDRESS = '0x25A643B6e52864d0eD816F1E43c0CF49C83B8292';
6+
7+
global.logger = winston.createLogger({
8+
transports: [new winston.transports.Console()],
9+
});
10+
11+
describe('Email Verification OTP', () => {
12+
let redisClient: Redis;
13+
let db: IDatabase;
14+
15+
beforeEach(async () => {
16+
redisClient = await getRedisClient();
17+
db = await getDatabase(redisClient);
18+
await redisClient.flushDb();
19+
});
20+
21+
afterEach(async () => {
22+
await redisClient.flushDb();
23+
await redisClient.disconnect();
24+
});
25+
26+
it('Set Email Verification OTP', async () => {
27+
const otp = '19283';
28+
const generatedAt = new Date();
29+
30+
// fetch OTP from Redis
31+
const priorOtp = await db.getOtp(
32+
USER_ADDRESS,
33+
NotificationChannelType.EMAIL,
34+
);
35+
36+
// User's email otp is null initially
37+
expect(priorOtp).toEqual(null);
38+
39+
// set email OTP
40+
await db.setOtp(
41+
USER_ADDRESS,
42+
otp,
43+
NotificationChannelType.EMAIL,
44+
generatedAt,
45+
);
46+
47+
// fetch OTP from Redis after setting OTP
48+
const afterSettingOtp = await db.getOtp(
49+
USER_ADDRESS,
50+
NotificationChannelType.EMAIL,
51+
);
52+
53+
const expectedData = {
54+
generatedAt: generatedAt,
55+
otp: otp,
56+
type: NotificationChannelType.EMAIL,
57+
};
58+
59+
expect(JSON.stringify(afterSettingOtp)).toEqual(
60+
JSON.stringify(expectedData),
61+
);
62+
});
63+
});

packages/lib/delivery/src/Delivery.ts

-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,4 @@ export interface DeliveryServiceProperties {
55
//Number of bytes an envelop object should not exceed
66
sizeLimit: number;
77
notificationChannel: NotificationChannel[];
8-
// properties for email service
9-
smtpHost: string;
10-
smtpPort: number;
11-
smtpEmail: string;
12-
smtpUsername: string;
13-
smtpPassword: string;
148
}

packages/lib/delivery/src/Messages.test.ts

+8-32
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,11 @@ import { UserProfile, normalizeEnsName } from '@dm3-org/dm3-lib-profile';
44
import { BigNumber, ethers } from 'ethers';
55
import { testData } from '../../../../test-data/encrypted-envelops.test';
66
import { stringify } from '../../shared/src/stringify';
7-
87
import { getConversationId, getMessages, incomingMessage } from './Messages';
98
import { Session } from './Session';
109
import { SpamFilterRules } from './spam-filter/SpamFilterRules';
11-
12-
import {
13-
NEW_MSG_EMAIL_TEMPLATE,
14-
NEW_MSG_EMAIL_SUBJECT,
15-
} from './notifications/templates/newMessage';
16-
import {
17-
NotificationChannelType,
18-
NotificationType,
19-
} from './notifications/types';
10+
import { NotificationChannelType } from './notifications/types';
11+
import { getDeliveryServiceProperties } from '../../../backend/src/config/getDeliveryServiceProperties';
2012

2113
const SENDER_NAME = 'alice.eth';
2214
const RECEIVER_NAME = 'bob.eth';
@@ -458,8 +450,9 @@ describe('Messages', () => {
458450
{
459451
type: NotificationChannelType.EMAIL,
460452
config: {
461-
recipientEmailId: '[email protected]',
462-
notificationType: NotificationType.NEW_MESSAGE,
453+
recipientEmailId: '[email protected]',
454+
isVerified: true,
455+
isEnabled: true,
463456
},
464457
},
465458
]);
@@ -484,18 +477,7 @@ describe('Messages', () => {
484477
keysA.signingKeyPair,
485478
keysA.encryptionKeyPair,
486479
2 ** 14,
487-
[
488-
{
489-
type: NotificationChannelType.EMAIL,
490-
config: {
491-
492-
port: 1234,
493-
username: '[email protected]',
494-
password: 'bar',
495-
emailID: '[email protected]',
496-
},
497-
},
498-
],
480+
getDeliveryServiceProperties().notificationChannel,
499481
getSession,
500482
storeNewMessage,
501483
sendMessageViaSocketMock,
@@ -507,14 +489,8 @@ describe('Messages', () => {
507489
getNotificationChannels,
508490
);
509491

510-
expect(sendMailMock).toHaveBeenCalledWith({
511-
512-
html: NEW_MSG_EMAIL_TEMPLATE(
513-
testData.delvieryInformationBUnecrypted,
514-
),
515-
subject: NEW_MSG_EMAIL_SUBJECT,
516-
517-
});
492+
expect(sendMailMock).toHaveBeenCalled();
493+
518494
//Check if the message was submitted to the socket
519495
expect(sendMessageViaSocketMock).not.toBeCalled();
520496
});

0 commit comments

Comments
 (0)