Skip to content

Commit 5e9dd48

Browse files
authored
feat(condo): DOMA-12992 encrypt data in push messages (#7271)
* feat(condo): DOMA-12992 encrypt data in push messages * chore(condo): DOMA-12992 remove console.logs * fix(condo): DOMA-12992 after review fixes and aloooot of small tests fixes * fix(condo): DOMA-12992 after automatic review fixes * fix(condo): DOMA-12992 another small after automatic review fix * fix(condo): DOMA-12992 and another small after automatic review fix * fix(condo): DOMA-12992 try to make data preparation clearer * chore(condo): DOMA-12992 small review fix and rebase with new adapter
1 parent 92f9284 commit 5e9dd48

File tree

14 files changed

+688
-215
lines changed

14 files changed

+688
-215
lines changed

apps/condo/domains/notification/adapters/appleAdapter.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ class AppleAdapter {
147147
* Prepares notification for either/both sending to Apple push and/or emulation if FAKE tokens present
148148
* Converts single notification to notifications array (for multiple tokens provided) for batch request
149149
* @param notificationRaw
150-
* @param data
150+
* @param dataByToken
151151
* @param tokens
152152
* @returns {*[][]}
153153
*/
154-
static prepareBatchData (notificationRaw, data, tokens = [], pushTypes = {}, appIds) {
154+
static prepareBatchData (notificationRaw, dataByToken = {}, tokens = [], pushTypes = {}, appIds) {
155155
const notification = AppleAdapter.validateAndPrepareNotification(notificationRaw)
156156
const notifications = [] // User can have many Remote Clients. Message is created for the user, so from 1 message there can be many notifications
157157
const fakeNotifications = []
@@ -161,12 +161,14 @@ class AppleAdapter {
161161
const isFakeToken = pushToken.startsWith(PUSH_FAKE_TOKEN_SUCCESS) || pushToken.startsWith(PUSH_FAKE_TOKEN_FAIL)
162162
const target = isFakeToken ? fakeNotifications : notifications
163163
const pushType = pushTypes[pushToken] || PUSH_TYPE_DEFAULT
164-
const preparedData = AppleAdapter.prepareData(data, pushToken)
164+
const data = dataByToken[pushToken]
165+
if (!data) return
166+
165167
const pushData = pushType === PUSH_TYPE_SILENT_DATA
166168
? {
167169
token: pushToken,
168170
data: {
169-
...preparedData,
171+
...data,
170172
'_title': notification.title,
171173
'_body': notification.body,
172174
},
@@ -176,14 +178,17 @@ class AppleAdapter {
176178
}
177179
: {
178180
token: pushToken,
179-
data: preparedData,
181+
data: data,
180182
notification,
181183
...DEFAULT_PUSH_SETTINGS,
182184
type: pushType,
183185
appId: get(appIds, pushToken),
184186
}
185187

186-
if (!APPS_WITH_DISABLED_NOTIFICATIONS.includes(get(appIds, pushToken)) && !APPS_WITH_DISABLED_NOTIFICATIONS.includes(data.app)) target.push(pushData)
188+
if (
189+
!APPS_WITH_DISABLED_NOTIFICATIONS.includes(get(appIds, pushToken))
190+
&& (!data.app || !APPS_WITH_DISABLED_NOTIFICATIONS.includes(data.app))
191+
) target.push(pushData)
187192

188193
if (!pushContext[pushType]) pushContext[pushType] = pushData
189194
})
@@ -203,10 +208,10 @@ class AppleAdapter {
203208
* @param pushTypes
204209
* @returns {Promise<null|(boolean|T|{state: string, error: *})[]>}
205210
*/
206-
async sendNotification ({ notification, data, tokens, pushTypes, appIds, metaByToken } = {}, isVoIP = false) {
211+
async sendNotification ({ notification, dataByToken, tokens, pushTypes, appIds, metaByToken } = {}, isVoIP = false) {
207212
if (!tokens || isEmpty(tokens)) return [false, { error: 'No pushTokens available.' }]
208213

209-
const [notifications, fakeNotifications, pushContext] = AppleAdapter.prepareBatchData(notification, data, tokens, pushTypes, appIds)
214+
const [notifications, fakeNotifications, pushContext] = AppleAdapter.prepareBatchData(notification, dataByToken, tokens, pushTypes, appIds)
210215
let result = AppleAdapter.getEmptyResult()
211216

212217
if (!isNull(this.#config) && !isEmpty(notifications)) {

apps/condo/domains/notification/adapters/appleAdapter.spec.js

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,19 @@ describe('Apple adapter utils', () => {
3939

4040
it('should succeed sending push notification to fake success push token', async () => {
4141
const tokens = [PUSH_FAKE_TOKEN_SUCCESS]
42+
const dataByToken = Object.fromEntries(
43+
tokens.map(token => [token, {
44+
app : 'condo',
45+
type: 'notification',
46+
}])
47+
)
4248
const [isOk, result] = await adapter.sendNotification({
4349
tokens,
4450
notification: {
4551
title: 'Doma.ai',
4652
body: `${dayjs().format()} Condo greets you!`,
4753
},
48-
data: {
49-
app : 'condo',
50-
type: 'notification',
51-
},
54+
dataByToken: dataByToken,
5255
})
5356

5457
expect(isOk).toBeTruthy()
@@ -153,9 +156,11 @@ describe('Apple adapter utils', () => {
153156
title: 'Doma.ai',
154157
body: `${dayjs().format()} Condo greets you!`,
155158
},
156-
data: {
157-
app : 'condo',
158-
type: 'notification',
159+
dataByToken: {
160+
[PUSH_FAKE_TOKEN_FAIL]: {
161+
app: 'condo',
162+
type: 'notification',
163+
},
159164
},
160165
})
161166

@@ -171,15 +176,19 @@ describe('Apple adapter utils', () => {
171176
})
172177

173178
it('should succeed sending push notification to fake success and fake fail push tokens', async () => {
179+
const data = {
180+
app : 'condo',
181+
type: 'notification',
182+
}
174183
const [isOk, result] = await adapter.sendNotification({
175184
tokens: [PUSH_FAKE_TOKEN_SUCCESS, PUSH_FAKE_TOKEN_FAIL],
176185
notification: {
177186
title: 'Doma.ai',
178187
body: `${dayjs().format()} Condo greets you!`,
179188
},
180-
data: {
181-
app : 'condo',
182-
type: 'notification',
189+
dataByToken: {
190+
[PUSH_FAKE_TOKEN_SUCCESS]: data,
191+
[PUSH_FAKE_TOKEN_FAIL]: data,
183192
},
184193
})
185194

@@ -206,9 +215,11 @@ describe('Apple adapter utils', () => {
206215
title: 'Doma.ai',
207216
body: `${dayjs().format()} Condo greets you!`,
208217
},
209-
data: {
210-
app : 'condo',
211-
type: 'notification',
218+
dataByToken: {
219+
[PUSH_FAKE_TOKEN_SUCCESS]: {
220+
app : 'condo',
221+
type: 'notification',
222+
},
212223
},
213224
pushTypes: {
214225
[PUSH_FAKE_TOKEN_SUCCESS]: PUSH_TYPE_DEFAULT,
@@ -239,9 +250,11 @@ describe('Apple adapter utils', () => {
239250
title: 'Doma.ai',
240251
body: `${dayjs().format()} Condo greets you!`,
241252
},
242-
data: {
243-
app : 'condo',
244-
type: 'notification',
253+
dataByToken: {
254+
[PUSH_FAKE_TOKEN_SUCCESS]: {
255+
app: 'condo',
256+
type: 'notification',
257+
},
245258
},
246259
pushTypes: {
247260
[PUSH_FAKE_TOKEN_SUCCESS]: PUSH_TYPE_SILENT_DATA,
@@ -272,9 +285,11 @@ describe('Apple adapter utils', () => {
272285
notification: {
273286
body: `${dayjs().format()} Condo greets you!`,
274287
},
275-
data: {
276-
app : 'condo',
277-
type: 'notification',
288+
dataByToken: {
289+
[PUSH_FAKE_TOKEN_SUCCESS]: {
290+
app: 'condo',
291+
type: 'notification',
292+
},
278293
},
279294
})
280295
).rejects.toThrow(EMPTY_NOTIFICATION_TITLE_BODY_ERROR)
@@ -287,9 +302,11 @@ describe('Apple adapter utils', () => {
287302
notification: {
288303
title: 'Doma.ai',
289304
},
290-
data: {
291-
app : 'condo',
292-
type: 'notification',
305+
dataByToken: {
306+
[PUSH_FAKE_TOKEN_SUCCESS]: {
307+
app: 'condo',
308+
type: 'notification',
309+
},
293310
},
294311
})
295312
).rejects.toThrow(EMPTY_NOTIFICATION_TITLE_BODY_ERROR)

apps/condo/domains/notification/adapters/firebaseAdapter.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class FirebaseAdapter {
7777
/**
7878
* Firebase rejects push if any of data fields is not a string, so we should convert all non-string fields to strings
7979
* @param data
80+
* @param token {string}
8081
*/
8182
static prepareData (data = {}, token) {
8283
const result = { token }
@@ -170,11 +171,11 @@ class FirebaseAdapter {
170171
* Prepares notification for either/both sending to FireBase and/or emulation if FAKE tokens present
171172
* Converts single notification to notifications array (for multiple tokens provided) for batch request
172173
* @param notificationRaw
173-
* @param data
174+
* @param dataByToken
174175
* @param tokens
175176
* @returns {*[][]}
176177
*/
177-
static prepareBatchData (notificationRaw, data, tokens = [], pushTypes = {}, isVoIP = false, appIds = {}) {
178+
static prepareBatchData (notificationRaw, dataByToken = {}, tokens = [], pushTypes = {}, isVoIP = false, appIds = {}) {
178179
const notification = FirebaseAdapter.validateAndPrepareNotification(notificationRaw)
179180
const notifications = []
180181
const fakeNotifications = []
@@ -185,12 +186,14 @@ class FirebaseAdapter {
185186
const isFakeToken = pushToken.startsWith(PUSH_FAKE_TOKEN_SUCCESS) || pushToken.startsWith(PUSH_FAKE_TOKEN_FAIL)
186187
const target = isFakeToken ? fakeNotifications : notifications
187188
const pushType = pushTypes[pushToken] || PUSH_TYPE_DEFAULT
188-
const preparedData = FirebaseAdapter.prepareData(data, pushToken)
189+
const data = dataByToken[pushToken]
190+
if (!data) return
191+
189192
const pushData = pushType === PUSH_TYPE_SILENT_DATA
190193
? {
191194
token: pushToken,
192195
data: {
193-
...preparedData,
196+
...data,
194197
'_title': notification.title,
195198
'_body': notification.body,
196199
},
@@ -199,16 +202,18 @@ class FirebaseAdapter {
199202
}
200203
: {
201204
token: pushToken,
202-
data: preparedData,
205+
data: data,
203206
notification,
204207
...DEFAULT_PUSH_SETTINGS,
205208
...extraPayload,
206209
}
207210

208211
// appId is set for each pushToken, so we can check if the app is disabled
209-
// data.app is also checked for backward compatibility, as it was used in the old implementation
210212
const appId = appIds[pushToken]
211-
if (!APPS_WITH_DISABLED_NOTIFICATIONS.includes(appId) && !APPS_WITH_DISABLED_NOTIFICATIONS.includes(data.app)) target.push(pushData)
213+
if (
214+
!APPS_WITH_DISABLED_NOTIFICATIONS.includes(appId)
215+
&& (!data.app || !APPS_WITH_DISABLED_NOTIFICATIONS.includes(data.app))
216+
) target.push(pushData)
212217

213218
if (!pushContext[pushType]) pushContext[pushType] = pushData
214219
})
@@ -224,18 +229,18 @@ class FirebaseAdapter {
224229
* PUSH_FAKE_TOKEN_SUCCESS provided within tokens
225230
* @param notification
226231
* @param tokens
227-
* @param data
232+
* @param dataByToken
228233
* @param pushTypes
229234
+ * @param appIds - Object mapping pushToken to appId for routing notifications to the correct Firebase app
230235
* @param metaByToken
231236
* @returns {Promise<null|(boolean|T|{state: string, error: *})[]>}
232237
*/
233-
async sendNotification ({ notification, data, tokens, pushTypes, appIds, metaByToken } = {}, isVoIP = false) {
238+
async sendNotification ({ notification, dataByToken, tokens, pushTypes, appIds, metaByToken } = {}, isVoIP = false) {
234239
if (!tokens || isEmpty(tokens)) return [false, { error: 'No pushTokens available.' }]
235240

236241
const [notifications, fakeNotifications, pushContext] = FirebaseAdapter.prepareBatchData(
237-
notification,
238-
data,
242+
notification,
243+
dataByToken,
239244
tokens,
240245
pushTypes,
241246
isVoIP,

0 commit comments

Comments
 (0)