Skip to content

Commit d831214

Browse files
Merge pull request #14 from own3d/oauth-webhook
Oauth Update validation
2 parents 0ddeef5 + 404fa65 commit d831214

File tree

4 files changed

+145
-1
lines changed

4 files changed

+145
-1
lines changed

config/own3d-id.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
'token_type' => env('OWN3D_ID_TOKEN_TYPE', 'Bearer'),
99
'model' => env('OWN3D_ID_MODEL', \App\Models\User::class),
1010
'model_key' => env('OWN3D_ID_MODEL_KEY', 'own3d_id'),
11+
'webhook_age_tolerance' => intval(env('OWN3D_ID_WEBHOOK_AGE_TOLERANCE', 300)),
1112
];

src/Enums/Platform.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Supported oauth providers.
77
*
88
* @author René Preuß <[email protected]>
9+
* @author Stefan Ensmann <[email protected]>
910
*/
1011
class Platform
1112
{
@@ -17,4 +18,32 @@ class Platform
1718

1819
public const SLACK = 'slack';
1920

20-
}
21+
public const YOUTUBE = 'youtube';
22+
23+
public const FACEBOOK = 'facebook';
24+
25+
public const INSTAGRAM = 'instagram';
26+
27+
public const KICK = 'kick';
28+
29+
public const TIKTOK = 'tiktok';
30+
31+
public const TROVO = 'trovo';
32+
33+
public const TWITTER = 'twitter';
34+
35+
/**
36+
* Returns an array with all supported platforms.
37+
*
38+
* @return string[]
39+
*/
40+
public static function supported() {
41+
return [
42+
self::TWITCH,
43+
self::DISCORD,
44+
self::GOOGLE,
45+
self::SLACK,
46+
self::YOUTUBE,
47+
];
48+
}
49+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Own3d\Id\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Http\Response;
8+
9+
/**
10+
* @author Stefan Ensmann <[email protected]>
11+
*/
12+
class UpdateWebhookValidation extends WebhookValidation
13+
{
14+
private const SUPPORTED_TYPES = [
15+
'account_migration',
16+
'platform_authorization_revoked',
17+
'account_authorization_revoked',
18+
'platform_linked',
19+
'personal_information_updated',
20+
'preferences_updated',
21+
];
22+
23+
/**
24+
* Handle the incoming request.
25+
*
26+
* @param Request $request
27+
* @param Closure $next
28+
*
29+
* @return Response
30+
*/
31+
public function handle($request, $next)
32+
{
33+
if (!in_array($request->input('type', ''), self::SUPPORTED_TYPES)) {
34+
return response()
35+
->json([
36+
'error' => 'Invalid update type',
37+
], 400);
38+
}
39+
40+
return parent::handle($request, $next);
41+
}
42+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Own3d\Id\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Http\Response;
8+
9+
/**
10+
* @author Stefan Ensmann <[email protected]>
11+
*/
12+
class WebhookValidation
13+
{
14+
/**
15+
* Handle the incoming request.
16+
*
17+
* @param Request $request
18+
* @param Closure $next
19+
*
20+
* @return Response
21+
*/
22+
public function handle($request, $next)
23+
{
24+
$xSignature = $request->header('X-Signature', '');
25+
$xTimestamp = intval($request->header('X-Timestamp', 0));
26+
27+
$input = $request->input();
28+
29+
if (!$this->isValidTimestamp($xTimestamp)) {
30+
return response()
31+
->json([
32+
'error' => 'Request expired',
33+
], 400);
34+
}
35+
36+
if (!$this->isValidSignature($input, $xTimestamp, $xSignature)) {
37+
return response()
38+
->json([
39+
'error' => 'Invalid signature',
40+
], 400);
41+
}
42+
43+
return $next($request);
44+
}
45+
46+
/**
47+
* Validates the timestamp of the incoming request.
48+
*
49+
* @param int $timestamp
50+
* @param int $tolerance
51+
*
52+
* @return bool
53+
*/
54+
private function isValidTimestamp($timestamp) {
55+
return abs(time() - $timestamp) <= config('own3d-id.webhook_age_tolerance');
56+
}
57+
58+
/**
59+
* Validates the signature of the incoming request.
60+
*
61+
* @param array $payload
62+
* @param int $timestamp
63+
* @param string $receivedSignature
64+
*
65+
* @return bool
66+
*/
67+
private function isValidSignature($payload, $timestamp, $receivedSignature) {
68+
$data = $timestamp . json_encode($payload);
69+
$calculatedSignature = hash_hmac('sha256', $data, config('own3d-id.client_secret'));
70+
return hash_equals($calculatedSignature, $receivedSignature);
71+
}
72+
}

0 commit comments

Comments
 (0)