3
3
*/
4
4
5
5
'use strict' ;
6
-
6
+ const _ = require ( 'lodash' ) ;
7
7
const joi = require ( 'joi' ) ;
8
8
const logger = require ( '../common/logger' ) ;
9
9
const tcApiHelper = require ( '../common/tcApiHelper' ) ;
@@ -16,15 +16,19 @@ const emailSchema = joi.object().keys({
16
16
from : joi . string ( ) . email ( ) . required ( ) ,
17
17
recipients : joi . array ( ) . items (
18
18
joi . object ( ) . keys ( {
19
- userId : joi . number ( ) . integer ( ) . required ( ) ,
20
- email : joi . string ( ) . email ( ) . required ( ) ,
21
- } ) . required ( )
19
+ userId : joi . number ( ) . integer ( ) ,
20
+ userUUID : joi . string ( ) . uuid ( ) ,
21
+ email : joi . string ( ) . email ( ) ,
22
+ handle : joi . string ( ) ,
23
+ } ) . min ( 1 ) . required ( )
22
24
) . min ( 1 ) . required ( ) ,
23
25
cc : joi . array ( ) . items (
24
26
joi . object ( ) . keys ( {
25
27
userId : joi . number ( ) . integer ( ) ,
26
- email : joi . string ( ) . email ( ) . required ( ) ,
27
- } ) . required ( )
28
+ userUUID : joi . string ( ) . uuid ( ) ,
29
+ email : joi . string ( ) . email ( ) ,
30
+ handle : joi . string ( ) ,
31
+ } ) . min ( 1 ) . required ( )
28
32
) ,
29
33
data : joi . object ( ) . keys ( {
30
34
subject : joi . string ( ) ,
@@ -48,7 +52,14 @@ const webSchema = joi.object().keys({
48
52
serviceId : joi . string ( ) . valid ( constants . SETTINGS_WEB_SERVICE_ID ) . required ( ) ,
49
53
type : joi . string ( ) . required ( ) ,
50
54
details : joi . object ( ) . keys ( {
51
- userId : joi . number ( ) . integer ( ) . required ( ) ,
55
+ recipients : joi . array ( ) . items (
56
+ joi . object ( ) . keys ( {
57
+ userId : joi . number ( ) . integer ( ) ,
58
+ userUUID : joi . string ( ) . uuid ( ) ,
59
+ email : joi . string ( ) . email ( ) ,
60
+ handle : joi . string ( ) ,
61
+ } ) . min ( 1 ) . required ( )
62
+ ) . min ( 1 ) . required ( ) ,
52
63
contents : joi . object ( ) ,
53
64
version : joi . number ( ) . integer ( ) . required ( ) ,
54
65
} ) . required ( ) ,
@@ -63,18 +74,95 @@ function validator(data, schema) {
63
74
return true ;
64
75
}
65
76
77
+ function * completeMissingFields ( details , findEmail , findUserId ) {
78
+ const getFieldsByUserId = [ ] ;
79
+ const getFieldsByHandle = [ ] ;
80
+ const getFieldsByUserUUID = [ ] ;
81
+ const getFieldsByEmail = [ ] ;
82
+ function findMissingFields ( data , email , userId ) {
83
+ for ( const recipient of data ) {
84
+ if ( _ . isUndefined ( recipient . email ) && email ) {
85
+ if ( ! _ . isUndefined ( recipient . userId ) ) {
86
+ getFieldsByUserId . push ( recipient ) ;
87
+ } else if ( ! _ . isUndefined ( recipient . handle ) ) {
88
+ getFieldsByHandle . push ( recipient ) ;
89
+ } else {
90
+ getFieldsByUserUUID . push ( recipient ) ;
91
+ }
92
+ } else if ( _ . isUndefined ( recipient . userId ) && userId ) {
93
+ if ( ! _ . isUndefined ( recipient . handle ) ) {
94
+ getFieldsByHandle . push ( recipient ) ;
95
+ } else if ( ! _ . isUndefined ( recipient . email ) ) {
96
+ getFieldsByEmail . push ( recipient ) ;
97
+ } else {
98
+ getFieldsByUserUUID . push ( recipient ) ;
99
+ }
100
+ }
101
+ }
102
+ }
103
+
104
+ findMissingFields ( details . recipients , findEmail , findUserId ) ;
105
+ if ( _ . isArray ( details . cc ) && ! _ . isEmpty ( details . cc ) ) {
106
+ findMissingFields ( details . cc , findEmail , false ) ;
107
+ }
108
+ const foundUsersByHandleOrId = yield tcApiHelper . getUsersByHandlesAndUserIds ( getFieldsByHandle , getFieldsByUserId ) ;
109
+ if ( ! _ . isEmpty ( foundUsersByHandleOrId ) ) {
110
+ for ( const user of [ ...getFieldsByUserId , ...getFieldsByHandle ] ) {
111
+ const found = _ . find ( foundUsersByHandleOrId , ! _ . isUndefined ( user . handle )
112
+ ? [ 'handle' , user . handle ] : [ 'userId' , user . userId ] ) || { } ;
113
+ if ( ! _ . isUndefined ( found . email ) && _ . isUndefined ( user . email ) ) {
114
+ _ . assign ( user , { email : found . email } ) ;
115
+ }
116
+ if ( ! _ . isUndefined ( found . userId ) && _ . isUndefined ( user . userId ) ) {
117
+ _ . assign ( user , { userId : found . userId } ) ;
118
+ }
119
+ }
120
+ }
121
+ const foundUsersByEmail = yield tcApiHelper . getUsersByEmails ( getFieldsByEmail ) ;
122
+ if ( ! _ . isEmpty ( foundUsersByEmail ) ) {
123
+ for ( const user of getFieldsByEmail ) {
124
+ const found = _ . find ( foundUsersByEmail , [ 'email' , user . email ] ) || { } ;
125
+ if ( ! _ . isUndefined ( found . id ) ) {
126
+ _ . assign ( user , { userId : found . id } ) ;
127
+ }
128
+ }
129
+ }
130
+ const foundUsersByUUID = yield tcApiHelper . getUsersByUserUUIDs ( getFieldsByUserUUID ) ;
131
+ if ( ! _ . isEmpty ( foundUsersByUUID ) ) {
132
+ for ( const user of getFieldsByUserUUID ) {
133
+ const found = _ . find ( foundUsersByUUID , [ 'id' , user . userUUID ] ) || { } ;
134
+ if ( ! _ . isUndefined ( found . externalProfiles ) && ! _ . isEmpty ( found . externalProfiles ) ) {
135
+ _ . assign ( user , { userId : _ . toInteger ( _ . get ( found . externalProfiles [ 0 ] , 'externalId' ) ) } ) ;
136
+ }
137
+ }
138
+ if ( findEmail ) {
139
+ const usersHaveId = _ . filter ( getFieldsByUserUUID , u => ! _ . isUndefined ( u . userId ) ) ;
140
+ const foundUsersById = yield tcApiHelper . getUsersByHandlesAndUserIds ( [ ] , usersHaveId ) ;
141
+ if ( ! _ . isEmpty ( foundUsersById ) ) {
142
+ for ( const user of getFieldsByUserUUID ) {
143
+ const found = _ . find ( foundUsersById , [ 'userId' , user . userId ] ) || { } ;
144
+ if ( ! _ . isUndefined ( found . email ) ) {
145
+ _ . assign ( user , { email : found . email } ) ;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
66
153
/**
67
154
* Handle notification message
68
155
* @param {Object } message the Kafka message
69
156
* @returns {Array } the notifications
70
157
*/
71
158
function * handle ( message ) {
72
159
const notifications = [ ] ;
73
- for ( const data of message . payload ) {
160
+ for ( const data of message . payload . notifications ) {
74
161
try {
75
162
switch ( data . serviceId ) {
76
163
case constants . SETTINGS_EMAIL_SERVICE_ID :
77
164
if ( validator ( data , emailSchema ) ) {
165
+ yield completeMissingFields ( data . details , true , true ) ;
78
166
yield tcApiHelper . notifyUserViaEmail ( data ) ;
79
167
}
80
168
break ;
@@ -85,9 +173,10 @@ function* handle(message) {
85
173
break ;
86
174
case constants . SETTINGS_WEB_SERVICE_ID :
87
175
if ( validator ( data , webSchema ) ) {
88
- const notification = yield tcApiHelper . notifyUserViaWeb ( data ) ;
89
- if ( notification ) {
90
- notifications . push ( notification ) ;
176
+ yield completeMissingFields ( data . details , false , true ) ;
177
+ const _notifications = yield tcApiHelper . notifyUserViaWeb ( data ) ;
178
+ if ( _notifications ) {
179
+ notifications . push ( ..._notifications ) ;
91
180
}
92
181
}
93
182
break ;
@@ -107,14 +196,16 @@ handle.schema = {
107
196
originator : joi . string ( ) . required ( ) ,
108
197
timestamp : joi . date ( ) . required ( ) ,
109
198
'mime-type' : joi . string ( ) . required ( ) ,
110
- payload : joi . array ( ) . items (
111
- joi . object ( ) . keys ( {
112
- serviceId : joi . string ( ) . valid (
113
- constants . SETTINGS_EMAIL_SERVICE_ID ,
114
- constants . SETTINGS_SLACK_SERVICE_ID ,
115
- constants . SETTINGS_WEB_SERVICE_ID ) . required ( ) ,
116
- } ) . unknown ( )
117
- ) . min ( 1 ) . required ( ) ,
199
+ payload : joi . object ( ) . keys ( {
200
+ notifications : joi . array ( ) . items (
201
+ joi . object ( ) . keys ( {
202
+ serviceId : joi . string ( ) . valid (
203
+ constants . SETTINGS_EMAIL_SERVICE_ID ,
204
+ constants . SETTINGS_SLACK_SERVICE_ID ,
205
+ constants . SETTINGS_WEB_SERVICE_ID ) . required ( ) ,
206
+ } ) . unknown ( )
207
+ ) . min ( 1 ) . required ( ) ,
208
+ } ) . required ( ) ,
118
209
} ) . required ( ) ,
119
210
} ;
120
211
0 commit comments