PluginProbe
Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity / trunk
Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity vtrunk
3.3.8 trunk 1.0 1.1.0 1.10.0 1.11.0 1.11.1 1.12.0 1.13.0 1.14.0 1.15.0 1.16.0 1.17.0 1.17.1 1.18.0 1.19.0 1.2.0 1.20.0 1.20.1 1.3.0 1.3.1 1.4.0 1.5.0 1.6.0 1.6.1 All 66 releases
logtivity / Core / Services / Logtivity_Rest_Endpoints.php

Logtivity_Rest_Endpoints.php in Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity trunk, at Core/Services/Logtivity_Rest_Endpoints.php

186 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @package Logtivity
5 * @contact logtivity.io, hello@logtivity.io
6 * @copyright 2025-2026 Logtivity. All rights reserved
7 * @license https://www.gnu.org/licenses/gpl.html GNU/GPL
8 *
9 * This file is part of Logtivity.
10 *
11 * Logtivity is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * Logtivity is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with Logtivity. If not, see <https://www.gnu.org/licenses/>.
23 */
24
25 class Logtivity_Rest_Endpoints
26 {
27 /**
28 * @var Logtivity_JsonWebToken
29 */
30 protected Logtivity_JsonWebToken $token;
31
32 public function __construct()
33 {
34 require_once __DIR__ . '/Logtivity_JsonWebToken.php';
35
36 $this->token = new Logtivity_JsonWebToken();
37
38 add_action('rest_api_init', function () {
39 register_rest_route(
40 'logtivity/v1',
41 '/options',
42 [
43 'methods' => 'GET',
44 'permission_callback' => function (WP_REST_Request $request) {
45 return $this->verifyAuthorization($request->get_header('Authorization'));
46 },
47 'callback' => function () {
48 try {
49 $options = new Logtivity_Options();
50
51 $response = $options->getOptions();
52
53 $lastCheckinOption = 'logtivity_last_settings_check_in_at';
54
55 $response[$lastCheckinOption] = get_option($lastCheckinOption);
56 $response[$lastCheckinOption] = $response[$lastCheckinOption]['date'] ?? null;
57 $response['logtivity_checkin_delay'] = $options->checkinDelay;
58 $response['version'] = $this->getLogtivityVersion();
59
60 return $response;
61
62 } catch (Throwable $error) {
63 return new WP_Error(
64 'logtivity_error',
65 $error->getMessage(),
66 [
67 'status' => $error->getCode(),
68 'line' => $error->getLine(),
69 'file' => $error->getFile(),
70 ]
71 );
72 }
73 },
74 ]);
75 });
76 }
77
78 /**
79 * @return self
80 */
81 public static function init(): self
82 {
83 return new static();
84 }
85
86 /**
87 * @param ?string $authHeader
88 *
89 * @return true|WP_Error
90 */
91 protected function verifyAuthorization(?string $authHeader)
92 {
93 if ($apikey = (new Logtivity_Options())->getApiKey()) {
94 try {
95 if ($authHeader == false) {
96 throw new Exception('No authorization provided');
97 }
98
99 $keys = explode(' ', $authHeader);
100 if (count($keys) == 2 && $keys[0] == 'Bearer') {
101 $payload = $this->parseToken($keys[1], $apikey);
102
103 $issuer = $payload->iss ?? '';
104 if ($this->compareDomains($issuer, logtivity_get_app_url()) == false) {
105 throw new Exception(
106 sprintf(
107 'Request Source: %s',
108 $issuer ? 'invalid' : 'unidentified'
109 )
110 );
111 }
112
113 $audience = $payload->aud ?? '';
114 if ($this->compareDomains($audience, site_url()) == false) {
115 throw new Exception(
116 sprintf(
117 'Target Site: %s',
118 $audience ? 'incorrect' : 'unidentified'
119 )
120 );
121 }
122
123 } else {
124 throw new Exception('Malformed header');
125 }
126
127 return true;
128
129 } catch (Throwable $e) {
130 return new WP_Error('invalid_token', $e->getMessage(), ['status' => 401]);
131 }
132 }
133
134 return new WP_Error('missing_api_key', 'The API Key has not been set on this site', ['status' => 401]);
135 }
136
137 /**
138 * @param string $token
139 * @param string $secret
140 *
141 * @return ?object
142 * @throws Exception
143 */
144 protected function parseToken(string $token, string $secret): object
145 {
146 if (empty($this->token)) {
147 require_once __DIR__ . '/Logtivity_JsonWebToken.php';
148 $this->token = new Logtivity_JsonWebToken();
149 }
150
151 return $this->token->parse($token, $secret);
152 }
153
154 /**
155 * @param string $urlLeft
156 * @param string $urlRight
157 *
158 * @return bool
159 */
160 protected function compareDomains(string $urlLeft, string $urlRight): bool
161 {
162 if (
163 preg_match('#^(?:https?://)?(\S*?)/?$#', $urlLeft, $left)
164 && preg_match('#^(?:https?://)?(\S*?)/?$#', $urlRight, $right)
165 ) {
166 return $left[1] == $right[1];
167 }
168
169 return false;
170 }
171
172 /**
173 * @return string
174 */
175 protected function getLogtivityVersion(): string
176 {
177 $path = WP_PLUGIN_DIR . '/logtivity/logtivity.php';
178 if (is_file($path)) {
179 $pluginData = get_plugin_data($path);
180 $version = $pluginData['Version'] ?? 'Unknown';
181 }
182
183 return $version ?? 'Logtivity not available';
184 }
185 }
186