From 627a8e34fd8da72d878217baf4d3bd55a878da29 Mon Sep 17 00:00:00 2001 From: mbasadi Date: Tue, 14 May 2024 17:35:25 -0400 Subject: [PATCH] fix: user authorizer --- package.json | 2 +- src/__tests__/notificationapi.test.ts | 14 ++++++++++++++ src/notificationapi.ts | 12 ++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d31433d..5dee606 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notificationapi-node-server-sdk", - "version": "2.0.0", + "version": "2.0.1", "description": "NotificationAPI server-side library for Node.js", "keywords": [ "notificationapi", diff --git a/src/__tests__/notificationapi.test.ts b/src/__tests__/notificationapi.test.ts index 818b763..bbae46a 100644 --- a/src/__tests__/notificationapi.test.ts +++ b/src/__tests__/notificationapi.test.ts @@ -619,6 +619,9 @@ describe('deleteUserPreferences without subNotificationId', () => { const clientSecret = 'testClientSecret'; const userId = 'testUserId'; const notificationId = 'testNotificationId'; + const hashedUserId = `${createHmac('sha256', clientSecret) + .update(userId) + .digest('base64')}`; test('makes API calls to the correct end-point', async () => { axiosMock.onDelete(retractEndPointRegex).reply(200); @@ -629,6 +632,10 @@ describe('deleteUserPreferences without subNotificationId', () => { `https://api.notificationapi.com/${clientId}/users/${userId}/preferences` ); expect(axiosMock.history.delete[0].params).toEqual({ notificationId }); + expect(axiosMock.history.delete[0].headers.Authorization).toEqual( + 'Basic ' + + Buffer.from(`${clientId}:${userId}:${hashedUserId}`).toString('base64') + ); }); }); describe('deleteUserPreferences with subNotificationId', () => { @@ -638,6 +645,9 @@ describe('deleteUserPreferences with subNotificationId', () => { const userId = 'testUserId'; const notificationId = 'testNotificationId'; const subNotificationId = 'testSubNotificationId'; + const hashedUserId = `${createHmac('sha256', clientSecret) + .update(userId) + .digest('base64')}`; test('makes API calls to the correct end-point', async () => { axiosMock.onDelete(retractEndPointRegex).reply(200); @@ -655,6 +665,10 @@ describe('deleteUserPreferences with subNotificationId', () => { notificationId, subNotificationId }); + expect(axiosMock.history.delete[0].headers.Authorization).toEqual( + 'Basic ' + + Buffer.from(`${clientId}:${userId}:${hashedUserId}`).toString('base64') + ); }); }); describe('Identify user', () => { diff --git a/src/notificationapi.ts b/src/notificationapi.ts index 3c4e6e0..d96aa93 100644 --- a/src/notificationapi.ts +++ b/src/notificationapi.ts @@ -14,7 +14,7 @@ const DEFAULT_BASE_URL = 'https://api.notificationapi.com'; class NotificationAPIService { private USER_AGENT = 'notificationapi-node-server-sdk'; - private VERSION = '2.0.0'; + private VERSION = '2.0.1'; clientId: null | string = null; clientSecret: null | string = null; @@ -105,11 +105,19 @@ class NotificationAPIService { /** The subNotificationId is used to specify further subcategories within a notification. Optional */ subNotificationId?: string ): Promise => { + const hashedUserId = `${createHmac('sha256', this.clientSecret as string) + .update(userId) + .digest('base64')}`; + const customAuthorization = + 'Basic ' + + Buffer.from(`${this.clientId}:${userId}:${hashedUserId}`).toString( + 'base64' + ); return this.request( 'DELETE', `users/${userId}/preferences`, null, - undefined, + customAuthorization, subNotificationId ? { notificationId, subNotificationId } : { notificationId }