PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / backend / src / Services / Integrations / MiddlewareSignatureService.php

MiddlewareSignatureService.php in The Innovative Form Builder – IvyForms 1.5, at backend/src/Services/Integrations/MiddlewareSignatureService.php

88 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IvyForms\Services\Integrations;
4
5 /**
6 * Verifies RSA-SHA256 signatures from ivyforms-middleware (Amelia-compatible).
7 */
8 class MiddlewareSignatureService
9 {
10 // private const MIDDLEWARE_PUBLIC_KEY = <<<'PEM'
11 // -----BEGIN PUBLIC KEY-----
12 // MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuBviz1x8ocjJnoGmum6E
13 // vBG1jz5Hnr/FNA9lYnoYVCP3P/gFm77AFP+vfl+jCLyWzB22uD8uoea/stUmP9U9
14 // 0bqVT5jMZorb4BoesPD8fG+iz8WzdfotRo/xatlhyZkE+9nE45BWHwZulf0ff1P8
15 // IKi6FLtXukqngJ+m63fJ0GelAH8KuMj6gzM1O+SSojGO+HBCdwlCcrxBal5M2x3Z
16 // dSKBh3U+qdCtnRSahkAO3DU7O2d9U+HZWBaKUJcb0LB1pM9mUlb3oFIaxQjLNdIk
17 // krr9L9okRlHeB1MqxfraexHRMmcrq1jawAerFIwSQrcZHGiQalbi3PKYZFEJgxqX
18 // WQIDAQAB
19 // -----END PUBLIC KEY-----
20 // PEM;
21
22 private const MIDDLEWARE_PUBLIC_KEY = <<<'PEM'
23 -----BEGIN PUBLIC KEY-----
24 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAriCZqL/Ob/3QtdBs1ZPJ
25 QhlHOX6/21VfqSESflh1CNcMlzpX+Qgf8htcwBJfeQur1fJ1G60x1IEjZy7lvgDS
26 s+UN2HDBIKX5tImBNafBg6WwJW7Wf0GcEyniQTqMEvJfQ3YOWJpfC4MfPlztyT/4
27 2nfB1tbl0RPPvfNPO4+3vjjSARUsoJqZ+H9M1urEPr75TuyuTxB8UdQaqWxWBnoY
28 lPOfojDPlg18eWuqKeJfOvy0QcrcJBWcgLFLqrPRUXD/V04lVtOmzS4Vftafs3Ob
29 qY3vxOh4BMuMzqtlcGZ4bB79yC6L91rBR7+Bq+HVkJsEExmcX1uWXoNJ/G+Ser1i
30 UwIDAQAB
31 -----END PUBLIC KEY-----
32 PEM;
33
34 /**
35 * @param array<string, mixed> $params Token delivery POST body from middleware.
36 */
37 public function buildTokenDeliverySignatureString(array $params): string
38 {
39 return '/square/authorization/token&access_token=' . (string) ($params['access_token'] ?? '')
40 . '&expires_at=' . (string) ($params['expires_at'] ?? '')
41 . '&refresh_token=' . (string) ($params['refresh_token'] ?? '')
42 . '&merchant_id=' . (string) ($params['merchant_id'] ?? '');
43 }
44
45 /**
46 * @param array<string, mixed> $params
47 */
48 public function verifyTokenDeliverySignature(array $params): bool
49 {
50 $signature = isset($params['signature']) ? (string) $params['signature'] : '';
51
52 return $this->verifySignature($this->buildTokenDeliverySignatureString($params), $signature);
53 }
54
55 /**
56 * @param mixed $data Webhook payload data (encoded the same way middleware signs it).
57 */
58 public function verifyWebhookDataSignature($data, ?string $signature): bool
59 {
60 $encoded = json_encode($data);
61
62 if (!is_string($encoded)) {
63 return false;
64 }
65
66 return $this->verifySignature($encoded, $signature ?? '');
67 }
68
69 public function verifySignature(string $stringToVerify, string $signature): bool
70 {
71 if ($stringToVerify === '' || $signature === '') {
72 return false;
73 }
74
75 $publicKey = openssl_pkey_get_public(self::MIDDLEWARE_PUBLIC_KEY);
76 if ($publicKey === false) {
77 return false;
78 }
79
80 $decodedSignature = base64_decode($signature, true);
81 if ($decodedSignature === false) {
82 return false;
83 }
84
85 return openssl_verify($stringToVerify, $decodedSignature, $publicKey, OPENSSL_ALGO_SHA256) === 1;
86 }
87 }
88