@@ -25,7 +25,7 @@ will contain:
2525
2626``` json
2727{
28- "user" : {}, // Created user informations
28+ "user" : {}, // Created user information
2929 "sender" : {} // User that triggered the creation
3030}
3131```
@@ -37,7 +37,8 @@ It will contain the following payload:
3737
3838``` json
3939{
40- "user" : {}, // Updated user
40+ "oldUser" : {}, // The old user information
41+ "user" : {}, // The new updated user
4142 "sender" : {} // User that triggered the update
4243}
4344```
@@ -50,7 +51,7 @@ for the `leftAt` property to disable account.
5051
5152``` json
5253{
53- "userId " : {}, // Deleted user id
54+ "user " : {}, // The old user information
5455 "sender" : {} // User that triggered the deletion
5556}
5657```
@@ -67,6 +68,16 @@ example integrations bellow:
6768In NodeJS you'll need no any extra library to perform the validation since HMAC SHA1 can be performed from the
6869` crypto ` module of the NodeJS API.
6970
71+ ``` js
72+ const checkSignature = (secret , payload , actualHash ) => {
73+ const body = typeof payload === ' string' ? payload : JSON .stringify (payload);
74+ const expectedHash = ` sha1=${ crypto .createHmac (' sha1' , secret).update (body).digest (' hex' )} ` ;
75+
76+ return expectedHash .length === actualHash .length && timingSafeEqual (new Buffer (expectedHash), new Buffer (actualHash))
77+ };
78+ ```
79+
80+
7081Example using Express:
7182
7283``` js
@@ -76,13 +87,9 @@ import crypto from 'crypto';
7687const secret = ' TopSecretHookPassword@SuperStrong#123456' ;
7788const app = express ();
7889
79- app .use ((req , res , next ) => {
80- // If using body parser be sure to calculate from stringified version
81- // const body = JSON.stringify(req.body);
82-
83- const hash = crypto .createHmac (' sha1' , secret).update (req .body ).digest (' hex' );
8490
85- if (` sha1=${ hash} ` !== req .headers [' x-lvconnect-signature' ]) {
91+ app .use (({ body, headers }, res , next ) => {
92+ if (checkSignature (secret, body, headers[' x-lvconnect-signature' ])) {
8693 next (new Error (' Invalid payload signature' ));
8794 }
8895
@@ -106,11 +113,8 @@ server.auth.scheme('signature', (_, options) => ({
106113 credentials: { event : req .headers [' x-lvconnect-event' ], identifier: req .headers [' x-lvconnect-delivery' ] },
107114 artifacts: { signature: req .headers [' x-lvconnect-signature' ] },
108115 }),
109- payload: async (req , h ) => {
110- const body = JSON .stringify (req .payload );
111- const hash = crypto .createHmac (' sha1' , options .secret ).update (body).digest (' hex' );
112-
113- if (` sha1=${ hash} ` !== req .headers [' x-lvconnect-signature' ]) {
116+ payload: async ({ payload, headers }, h ) => {
117+ if (checkSignature (options .secret , payload, headers[' x-lvconnect-signature' ])) {
114118 throw Boom .forbidden (' Invalid payload signature' );
115119 }
116120
@@ -135,3 +139,24 @@ server.route({
135139
136140server .start ();
137141```
142+
143+ ### Php
144+
145+ ``` php
146+ <?php
147+
148+ use Symfony\Component\HttpFoundation\Request;
149+
150+ class CheckHookSignature
151+ {
152+ public function __invoke(string $secret, Request $request)
153+ {
154+ $payload = $request->getContent();
155+ $actualHash = $request->headers->get('x-lvconnect-signature');
156+
157+ $expectedHash = 'sha1=' . hash_hmac('sha1', $payload, $secret);
158+
159+ return hash_equals($expectedHash, $actualHash);
160+ }
161+ }
162+ ```
0 commit comments