@@ -126,25 +126,34 @@ async function deleteRemoteClientsIfTokenIsInvalid ({ adapter, result, isVoIP })
126126
127127function prepareDataByToken ( { adapter, tokens, data, appIds } ) {
128128 /** @type {Record<string, { success: boolean, encryptedData?: Record<string, unknown> | null }> } */
129- const encryptedDataByAppId = { }
129+ const encryptionStatsInfo = { }
130130 const dataByToken = { }
131- for ( const token of tokens ) {
132- const dataForToken = adapter . constructor . prepareData ( data , token )
131+
132+ const tokensWhichNeedEncryption = tokens . filter ( token => ! ! PUSH_ADAPTER_SETTINGS . encryption ?. [ appIds [ token ] ] )
133+ const tokensWhichDoNotNeedEncryption = tokens . filter ( token => ! PUSH_ADAPTER_SETTINGS . encryption ?. [ appIds [ token ] ] )
134+
135+ // prepare data for simple tokens
136+ tokensWhichDoNotNeedEncryption . forEach ( token => {
137+ // NOTE(YEgorLu): Class.staticMethod() === new Class().constructor.staticMethod()
138+ dataByToken [ token ] = adapter . constructor . prepareData ( data , token )
139+ } )
140+
141+ // encrypt data for needed tokens if possible
142+ tokensWhichNeedEncryption . forEach ( token => {
133143 const appId = appIds [ token ]
134- const encryptionVersion = PUSH_ADAPTER_SETTINGS . encryption ?. [ appId ]
135- if ( ! encryptionVersion ) {
136- dataByToken [ token ] = dataForToken
137- continue
138- }
139- const encryptedData = encryptPushData ( encryptionVersion , dataForToken , { appId } )
140- if ( encryptedData ) {
141- encryptedDataByAppId [ appId ] = { success : true , encryptedData }
142- dataByToken [ token ] = encryptedData
144+ const preparedDataForToken = adapter . constructor . prepareData ( data , token )
145+ const encryptionVersion = PUSH_ADAPTER_SETTINGS . encryption [ appId ]
146+ const encryptedDataForToken = encryptPushData ( encryptionVersion , preparedDataForToken , { appId } )
147+
148+ if ( encryptedDataForToken ) {
149+ encryptionStatsInfo [ appId ] = { success : true , appId : appIds [ token ] , encryptedData : encryptedDataForToken }
150+ dataByToken [ token ] = encryptedDataForToken
143151 } else {
144- encryptedDataByAppId [ appId ] = { success : false }
152+ encryptionStatsInfo [ appId ] = { success : false , appId : appIds [ token ] , encryptedData : null }
145153 }
146- }
147- return { dataByToken, encryptedDataByAppId }
154+ } )
155+
156+ return { dataByToken, encryptionStatsInfo }
148157}
149158
150159/**
@@ -171,7 +180,7 @@ async function send ({ notification, data, user, remoteClient } = {}, isVoIP = f
171180 )
172181 )
173182
174- const encryptedDataByAppId = { }
183+ const encryptionStatsInfo = { }
175184 let container = { }
176185 let _isOk = false
177186
@@ -184,32 +193,42 @@ async function send ({ notification, data, user, remoteClient } = {}, isVoIP = f
184193 let tokens = tokensByTransport [ transport ]
185194 if ( isEmpty ( tokens ) ) return null
186195 const adapter = ADAPTERS [ transport ]
187- // NOTE(YEgorLu): Class.staticMethod() === new Class().constructor.staticMethod()
188- const { dataByToken, encryptedDataByAppId : encryptedDataByAppIdForCurrenyTransport } = prepareDataByToken ( { adapter, tokens, data, appIds } )
189- Object . keys ( encryptedDataByAppIdForCurrenyTransport ) . forEach ( ( appId ) => encryptedDataByAppId [ appId ] = encryptedDataByAppIdForCurrenyTransport [ appId ] )
190- const tokensWithNoData = tokens . filter ( token => ! dataByToken [ token ] )
191- tokensWithNoData . forEach ( tokenWithNoData => {
192- [ appIds , pushTypes , metaByToken ] . forEach ( mapByToken => {
193- delete mapByToken [ tokenWithNoData ]
194- } )
196+
197+ const { dataByToken, encryptionStatsInfo : encryptionStatsInfoForCurrentTransport } = prepareDataByToken ( { adapter, tokens, data, appIds } )
198+ Object . keys ( encryptionStatsInfoForCurrentTransport ) . forEach ( ( token ) => {
199+ encryptionStatsInfo [ token ] = encryptionStatsInfoForCurrentTransport [ token ]
195200 } )
201+ const tokensWithNoData = tokens . filter ( token => ! dataByToken [ token ] )
196202 tokens = tokens . filter ( token => ! ! dataByToken [ token ] ) // if encryption failed, do not send it
197203
204+ const tokensWithNoDataResponses = tokensWithNoData . map ( token => ( {
205+ success : false ,
206+ pushToken : token ,
207+ appId : appIds [ token ] ,
208+ pushType : pushTypes [ token ] ,
209+ error : 'empty data for token' ,
210+ } ) )
211+
198212 if ( tokens . length === 0 ) {
199- return [ false , { successCount : 0 , failureCount : tokensWithNoData . length , responses : [ ] } , transport ]
213+ return [ false , { successCount : 0 , failureCount : tokensWithNoData . length , responses : tokensWithNoDataResponses } , transport ]
200214 }
201215
202216 const payload = { tokens, pushTypes, appIds, notification, dataByToken, metaByToken }
203217 const [ isOk , result ] = await adapter . sendNotification ( payload , isVoIP )
204218
219+ result . failureCount ??= 0
220+ result . failureCount += tokensWithNoData . length
221+ result . responses ??= [ ]
222+ result . responses . push ( ...tokensWithNoDataResponses )
223+
205224 await deleteRemoteClientsIfTokenIsInvalid ( { adapter, result, isVoIP } )
206225
207226 /** @type {[boolean, object, string] } */
208227 const sendNotificationResult = [ isOk , result , transport ]
209228 return sendNotificationResult
210229 } ) )
211230
212- logger . info ( { msg : 'encrypted data ' , entity : 'Message' , entityId : data . notificationId , data : { encryptedDataByAppId } } )
231+ logger . info ( { msg : 'encryptionStatsInfo ' , entity : 'Message' , entityId : data . notificationId , data : { encryptionStatsInfo } } )
213232
214233 for ( const p of promises ) {
215234 if ( p . status !== 'fulfilled' ) continue
0 commit comments