@artilingo/artiframe-cli 2.0.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +660 -660
  2. package/README.md +64 -118
  3. package/bin/artiframe.js +0 -0
  4. package/bin/artiframe.php +0 -0
  5. package/core-stubs/app/ApiAuthControl.php +76 -0
  6. package/core-stubs/app/ApiControl.php +81 -35
  7. package/core-stubs/app/AuthControl.php +39 -0
  8. package/core-stubs/app/Database.php +36 -35
  9. package/core-stubs/app/DotEnv.php +19 -1
  10. package/core-stubs/app/ViewControl.php +47 -1
  11. package/core-stubs/bin/SQLMethod.php +261 -0
  12. package/core-stubs/bin/SystemMethod.php +115 -74
  13. package/core-stubs/bin/ViewMethod.php +19 -5
  14. package/core-stubs/docs/de.html +4325 -4347
  15. package/core-stubs/docs/en.html +4325 -4347
  16. package/core-stubs/docs/es.html +4325 -4347
  17. package/core-stubs/docs/fr.html +4325 -4347
  18. package/core-stubs/docs/tr.html +117 -46
  19. package/core-stubs/public/403.php +52 -0
  20. package/core-stubs/public/assets/css/components/header.css +174 -0
  21. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  22. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  23. package/core-stubs/public/assets/css/root/app.css +975 -38
  24. package/core-stubs/public/assets/css/root/root.css +64 -0
  25. package/core-stubs/public/assets/js/components/header.js +380 -0
  26. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  27. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  28. package/core-stubs/public/assets/js/root/app.js +1870 -0
  29. package/core-stubs/public/includes/footer.php +4 -5
  30. package/core-stubs/public/includes/head-auth.php +65 -0
  31. package/core-stubs/public/includes/head.php +56 -17
  32. package/core-stubs/public/includes/header.php +135 -1
  33. package/core-stubs/public/includes/mobilenav.php +75 -3
  34. package/core-stubs/public/includes/sidebar.php +186 -1
  35. package/core-stubs/public/includes/theme-modal.php +1 -0
  36. package/db-studio/debug.log +3 -0
  37. package/db-studio/index.html +1755 -0
  38. package/db-studio/launcher.html +102 -0
  39. package/db-studio/launcher.js +180 -0
  40. package/db-studio/logo.svg +22 -0
  41. package/db-studio/main.js +568 -0
  42. package/db-studio/package-lock.json +1034 -0
  43. package/db-studio/package.json +16 -0
  44. package/db-studio/preload.js +29 -0
  45. package/devops-studio/api-inspector.js +222 -0
  46. package/devops-studio/index.html +1892 -0
  47. package/devops-studio/logo.svg +22 -0
  48. package/devops-studio/main.js +67 -0
  49. package/devops-studio/make-wizard.js +635 -0
  50. package/devops-studio/package-lock.json +871 -0
  51. package/devops-studio/package.json +12 -0
  52. package/package.json +5 -2
  53. package/scripts/postinstall.js +44 -8
  54. package/server-studio/.json-404-guard +1 -0
  55. package/server-studio/index.html +283 -0
  56. package/server-studio/logo.svg +22 -0
  57. package/server-studio/main.js +133 -0
  58. package/server-studio/package-lock.json +1179 -0
  59. package/server-studio/package.json +15 -0
  60. package/server-studio/router.php +99 -0
  61. package/src/App.php +29 -0
  62. package/src/Commands/AddCommand.php +26 -9
  63. package/src/Commands/DbExportCommand.php +131 -0
  64. package/src/Commands/DbStartCommand.php +46 -0
  65. package/src/Commands/DevopsCommand.php +35 -0
  66. package/src/Commands/GoCommand.php +48 -48
  67. package/src/Commands/ListCommand.php +68 -68
  68. package/src/Commands/MakeApiCommand.php +6 -1
  69. package/src/Commands/MakeViewCommand.php +25 -2
  70. package/src/Commands/NewProjectCommand.php +16 -11
  71. package/src/Commands/OptimizeCommand.php +61 -0
  72. package/src/Commands/RemoveCommand.php +35 -7
  73. package/src/Commands/ServeCommand.php +46 -91
  74. package/src/Commands/ShowCommand.php +24 -24
  75. package/src/Commands/UpgradeCommand.php +39 -10
  76. package/stubs/make/api-switch-case.stub +1 -1
  77. package/stubs/make/auth-api-standart.stub +20 -0
  78. package/stubs/make/auth-api-switch-case.stub +38 -0
  79. package/stubs/make/auth-view.stub +26 -0
  80. package/stubs/make/class.stub +10 -2
  81. package/stubs/make/view.stub +3 -0
  82. package/stubs/service/image.stub +334 -334
  83. package/stubs/service/iyzico.stub +637 -637
  84. package/stubs/service/jwt.stub +312 -312
  85. package/stubs/service/phpmailer.stub +143 -143
  86. package/stubs/service/pusher.stub +232 -232
  87. package/stubs/service/qrcode.stub +169 -169
  88. package/stubs/service/redis.stub +361 -361
  89. package/stubs/service/s3.stub +377 -377
  90. package/stubs/service/stripe.stub +526 -526
  91. package/stubs/service/twilio.stub +361 -361
@@ -1,312 +1,312 @@
1
- <?php
2
-
3
- namespace Src\Auth;
4
-
5
- use Firebase\JWT\JWT;
6
- use Firebase\JWT\Key;
7
- use Firebase\JWT\ExpiredException;
8
- use Firebase\JWT\SignatureInvalidException;
9
- use Firebase\JWT\BeforeValidException;
10
-
11
- /**
12
- * JWT Authentication Service
13
- *
14
- * Provides a clean wrapper around firebase/php-jwt for token generation,
15
- * verification, refresh, and HTTP middleware integration.
16
- *
17
- * Required environment variables:
18
- * JWT_SECRET_KEY — Secret key used for signing and verifying tokens
19
- * JWT_ALGORITHM — Signing algorithm (e.g. HS256, HS384, HS512)
20
- * JWT_EXPIRY — Default token lifetime in seconds (e.g. 3600)
21
- *
22
- * @package Auth
23
- */
24
- class JwtAuth
25
- {
26
- /**
27
- * Secret key for signing tokens.
28
- *
29
- * @var string
30
- */
31
- private string $secretKey;
32
-
33
- /**
34
- * Signing algorithm (HS256, HS384, HS512, etc.).
35
- *
36
- * @var string
37
- */
38
- private string $algorithm;
39
-
40
- /**
41
- * Default token expiry in seconds.
42
- *
43
- * @var int
44
- */
45
- private int $expiry;
46
-
47
- /**
48
- * Create a new JwtAuth instance.
49
- *
50
- * Loads the secret key, algorithm, and default expiry from $_ENV.
51
- */
52
- public function __construct()
53
- {
54
- $this->secretKey = $_ENV['JWT_SECRET_KEY'];
55
- $this->algorithm = $_ENV['JWT_ALGORITHM'] ?? 'HS256';
56
- $this->expiry = (int) ($_ENV['JWT_EXPIRY'] ?? 3600);
57
- }
58
-
59
- /**
60
- * Generate a signed JWT token.
61
- *
62
- * Merges the given payload with standard claims (iat, exp) and encodes it.
63
- *
64
- * @param array $payload Custom claims to include in the token
65
- * @param int|null $expiry Token lifetime in seconds (null = use default from $_ENV)
66
- * @return string Encoded JWT token string
67
- */
68
- public function generate(array $payload, int $expiry = null): string
69
- {
70
- $now = time();
71
- $expiresIn = $expiry ?? $this->expiry;
72
-
73
- $tokenPayload = array_merge($payload, [
74
- 'iat' => $now,
75
- 'exp' => $now + $expiresIn,
76
- ]);
77
-
78
- return JWT::encode($tokenPayload, $this->secretKey, $this->algorithm);
79
- }
80
-
81
- /**
82
- * Verify and decode a JWT token.
83
- *
84
- * Returns a standardised response array with the decoded payload on success
85
- * or an error message on failure.
86
- *
87
- * @param string $token The JWT token to verify
88
- * @return array {
89
- * @type string $status 'success' or 'error'
90
- * @type string $message Human-readable result description
91
- * @type array $data Decoded payload (on success only)
92
- * }
93
- */
94
- public function verify(string $token): array
95
- {
96
- try {
97
- $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
98
- $payload = (array) $decoded;
99
-
100
- return [
101
- 'status' => 'success',
102
- 'message' => 'Token is valid.',
103
- 'data' => $payload,
104
- ];
105
- } catch (ExpiredException $e) {
106
- return [
107
- 'status' => 'error',
108
- 'message' => 'Token has expired.',
109
- 'data' => [],
110
- ];
111
- } catch (SignatureInvalidException $e) {
112
- return [
113
- 'status' => 'error',
114
- 'message' => 'Invalid token signature.',
115
- 'data' => [],
116
- ];
117
- } catch (BeforeValidException $e) {
118
- return [
119
- 'status' => 'error',
120
- 'message' => 'Token is not yet valid.',
121
- 'data' => [],
122
- ];
123
- } catch (\Exception $e) {
124
- return [
125
- 'status' => 'error',
126
- 'message' => 'Token verification failed: ' . $e->getMessage(),
127
- 'data' => [],
128
- ];
129
- }
130
- }
131
-
132
- /**
133
- * Extract the payload from a token without throwing exceptions.
134
- *
135
- * Useful when you need to inspect claims even if the token might be invalid.
136
- * Returns null on any failure instead of throwing.
137
- *
138
- * @param string $token The JWT token to decode
139
- * @return array|null Decoded payload or null on failure
140
- */
141
- public function payload(string $token): ?array
142
- {
143
- try {
144
- $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
145
- return (array) $decoded;
146
- } catch (\Exception $e) {
147
- return null;
148
- }
149
- }
150
-
151
- /**
152
- * Refresh a token by generating a new one with the same payload.
153
- *
154
- * Strips the old iat/exp claims and re-signs with a fresh expiry.
155
- * Returns null if the original token cannot be decoded.
156
- *
157
- * @param string $token The current JWT token to refresh
158
- * @param int|null $expiry New expiry duration in seconds (null = use default)
159
- * @return string|null New JWT token or null on failure
160
- */
161
- public function refresh(string $token, int $expiry = null): ?string
162
- {
163
- try {
164
- $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
165
- $payload = (array) $decoded;
166
-
167
- // Remove old timing claims so generate() sets fresh ones
168
- unset($payload['iat'], $payload['exp'], $payload['nbf']);
169
-
170
- return $this->generate($payload, $expiry);
171
- } catch (\Exception $e) {
172
- return null;
173
- }
174
- }
175
-
176
- /**
177
- * Check whether a token has expired.
178
- *
179
- * Attempts to decode the token and catches ExpiredException specifically.
180
- * Returns true if expired, false if still valid or on other errors.
181
- *
182
- * @param string $token The JWT token to check
183
- * @return bool True if the token is expired
184
- */
185
- public function isExpired(string $token): bool
186
- {
187
- try {
188
- JWT::decode($token, new Key($this->secretKey, $this->algorithm));
189
- return false;
190
- } catch (ExpiredException $e) {
191
- return true;
192
- } catch (\Exception $e) {
193
- // Token is invalid for another reason, not strictly "expired"
194
- return false;
195
- }
196
- }
197
-
198
- /**
199
- * Extract the user_id claim from a token.
200
- *
201
- * A convenience shortcut for the most common payload lookup.
202
- *
203
- * @param string $token The JWT token
204
- * @return mixed The user_id value or null if not present / token invalid
205
- */
206
- public function getUserId(string $token): mixed
207
- {
208
- $payload = $this->payload($token);
209
-
210
- if ($payload === null) {
211
- return null;
212
- }
213
-
214
- return $payload['user_id'] ?? null;
215
- }
216
-
217
- /**
218
- * Generate a long-lived refresh token.
219
- *
220
- * Identical to generate() but with a longer default expiry (7 days).
221
- * Adds a 'token_type' => 'refresh' claim to distinguish from access tokens.
222
- *
223
- * @param array $payload Custom claims to include
224
- * @param int $expiry Lifetime in seconds (default: 604800 = 7 days)
225
- * @return string Encoded refresh token
226
- */
227
- public function generateRefreshToken(array $payload, int $expiry = 604800): string
228
- {
229
- $payload['token_type'] = 'refresh';
230
-
231
- return $this->generate($payload, $expiry);
232
- }
233
-
234
- /**
235
- * HTTP middleware that validates the Authorization header.
236
- *
237
- * Reads the Bearer token from the Authorization header, verifies it, and
238
- * sets $_REQUEST['jwt_user'] with the decoded payload on success.
239
- * On failure, sends a 401 JSON response via apiResponse() and exits.
240
- *
241
- * Usage:
242
- * JwtAuth::middleware();
243
- * // If execution reaches here, $_REQUEST['jwt_user'] is available
244
- *
245
- * @return void
246
- */
247
- public static function middleware(): void
248
- {
249
- $instance = new self();
250
-
251
- // Extract Bearer token from Authorization header
252
- $authHeader = $_SERVER['HTTP_AUTHORIZATION']
253
- ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
254
- ?? '';
255
-
256
- if (empty($authHeader)) {
257
- if (function_exists('apiResponse')) {
258
- apiResponse(401, 'Authorization header is missing.');
259
- } else {
260
- http_response_code(401);
261
- header('Content-Type: application/json');
262
- echo json_encode([
263
- 'status' => 'error',
264
- 'code' => 401,
265
- 'message' => 'Authorization header is missing.',
266
- ]);
267
- }
268
- exit;
269
- }
270
-
271
- // Strip "Bearer " prefix
272
- $token = '';
273
- if (preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) {
274
- $token = $matches[1];
275
- }
276
-
277
- if (empty($token)) {
278
- if (function_exists('apiResponse')) {
279
- apiResponse(401, 'Bearer token is missing.');
280
- } else {
281
- http_response_code(401);
282
- header('Content-Type: application/json');
283
- echo json_encode([
284
- 'status' => 'error',
285
- 'code' => 401,
286
- 'message' => 'Bearer token is missing.',
287
- ]);
288
- }
289
- exit;
290
- }
291
-
292
- $result = $instance->verify($token);
293
-
294
- if ($result['status'] !== 'success') {
295
- if (function_exists('apiResponse')) {
296
- apiResponse(401, $result['message']);
297
- } else {
298
- http_response_code(401);
299
- header('Content-Type: application/json');
300
- echo json_encode([
301
- 'status' => 'error',
302
- 'code' => 401,
303
- 'message' => $result['message'],
304
- ]);
305
- }
306
- exit;
307
- }
308
-
309
- // Attach decoded user payload to the request superglobal
310
- $_REQUEST['jwt_user'] = $result['data'];
311
- }
312
- }
1
+ <?php
2
+
3
+ namespace Src\Auth;
4
+
5
+ use Firebase\JWT\JWT;
6
+ use Firebase\JWT\Key;
7
+ use Firebase\JWT\ExpiredException;
8
+ use Firebase\JWT\SignatureInvalidException;
9
+ use Firebase\JWT\BeforeValidException;
10
+
11
+ /**
12
+ * JWT Authentication Service
13
+ *
14
+ * Provides a clean wrapper around firebase/php-jwt for token generation,
15
+ * verification, refresh, and HTTP middleware integration.
16
+ *
17
+ * Required environment variables:
18
+ * JWT_SECRET_KEY — Secret key used for signing and verifying tokens
19
+ * JWT_ALGORITHM — Signing algorithm (e.g. HS256, HS384, HS512)
20
+ * JWT_EXPIRY — Default token lifetime in seconds (e.g. 3600)
21
+ *
22
+ * @package Auth
23
+ */
24
+ class JwtAuth
25
+ {
26
+ /**
27
+ * Secret key for signing tokens.
28
+ *
29
+ * @var string
30
+ */
31
+ private string $secretKey;
32
+
33
+ /**
34
+ * Signing algorithm (HS256, HS384, HS512, etc.).
35
+ *
36
+ * @var string
37
+ */
38
+ private string $algorithm;
39
+
40
+ /**
41
+ * Default token expiry in seconds.
42
+ *
43
+ * @var int
44
+ */
45
+ private int $expiry;
46
+
47
+ /**
48
+ * Create a new JwtAuth instance.
49
+ *
50
+ * Loads the secret key, algorithm, and default expiry from $_ENV.
51
+ */
52
+ public function __construct()
53
+ {
54
+ $this->secretKey = $_ENV['JWT_SECRET_KEY'];
55
+ $this->algorithm = $_ENV['JWT_ALGORITHM'] ?? 'HS256';
56
+ $this->expiry = (int) ($_ENV['JWT_EXPIRY'] ?? 3600);
57
+ }
58
+
59
+ /**
60
+ * Generate a signed JWT token.
61
+ *
62
+ * Merges the given payload with standard claims (iat, exp) and encodes it.
63
+ *
64
+ * @param array $payload Custom claims to include in the token
65
+ * @param int|null $expiry Token lifetime in seconds (null = use default from $_ENV)
66
+ * @return string Encoded JWT token string
67
+ */
68
+ public function generate(array $payload, int $expiry = null): string
69
+ {
70
+ $now = time();
71
+ $expiresIn = $expiry ?? $this->expiry;
72
+
73
+ $tokenPayload = array_merge($payload, [
74
+ 'iat' => $now,
75
+ 'exp' => $now + $expiresIn,
76
+ ]);
77
+
78
+ return JWT::encode($tokenPayload, $this->secretKey, $this->algorithm);
79
+ }
80
+
81
+ /**
82
+ * Verify and decode a JWT token.
83
+ *
84
+ * Returns a standardised response array with the decoded payload on success
85
+ * or an error message on failure.
86
+ *
87
+ * @param string $token The JWT token to verify
88
+ * @return array {
89
+ * @type string $status 'success' or 'error'
90
+ * @type string $message Human-readable result description
91
+ * @type array $data Decoded payload (on success only)
92
+ * }
93
+ */
94
+ public function verify(string $token): array
95
+ {
96
+ try {
97
+ $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
98
+ $payload = (array) $decoded;
99
+
100
+ return [
101
+ 'status' => 'success',
102
+ 'message' => 'Token is valid.',
103
+ 'data' => $payload,
104
+ ];
105
+ } catch (ExpiredException $e) {
106
+ return [
107
+ 'status' => 'error',
108
+ 'message' => 'Token has expired.',
109
+ 'data' => [],
110
+ ];
111
+ } catch (SignatureInvalidException $e) {
112
+ return [
113
+ 'status' => 'error',
114
+ 'message' => 'Invalid token signature.',
115
+ 'data' => [],
116
+ ];
117
+ } catch (BeforeValidException $e) {
118
+ return [
119
+ 'status' => 'error',
120
+ 'message' => 'Token is not yet valid.',
121
+ 'data' => [],
122
+ ];
123
+ } catch (\Exception $e) {
124
+ return [
125
+ 'status' => 'error',
126
+ 'message' => 'Token verification failed: ' . $e->getMessage(),
127
+ 'data' => [],
128
+ ];
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Extract the payload from a token without throwing exceptions.
134
+ *
135
+ * Useful when you need to inspect claims even if the token might be invalid.
136
+ * Returns null on any failure instead of throwing.
137
+ *
138
+ * @param string $token The JWT token to decode
139
+ * @return array|null Decoded payload or null on failure
140
+ */
141
+ public function payload(string $token): ?array
142
+ {
143
+ try {
144
+ $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
145
+ return (array) $decoded;
146
+ } catch (\Exception $e) {
147
+ return null;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Refresh a token by generating a new one with the same payload.
153
+ *
154
+ * Strips the old iat/exp claims and re-signs with a fresh expiry.
155
+ * Returns null if the original token cannot be decoded.
156
+ *
157
+ * @param string $token The current JWT token to refresh
158
+ * @param int|null $expiry New expiry duration in seconds (null = use default)
159
+ * @return string|null New JWT token or null on failure
160
+ */
161
+ public function refresh(string $token, int $expiry = null): ?string
162
+ {
163
+ try {
164
+ $decoded = JWT::decode($token, new Key($this->secretKey, $this->algorithm));
165
+ $payload = (array) $decoded;
166
+
167
+ // Remove old timing claims so generate() sets fresh ones
168
+ unset($payload['iat'], $payload['exp'], $payload['nbf']);
169
+
170
+ return $this->generate($payload, $expiry);
171
+ } catch (\Exception $e) {
172
+ return null;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Check whether a token has expired.
178
+ *
179
+ * Attempts to decode the token and catches ExpiredException specifically.
180
+ * Returns true if expired, false if still valid or on other errors.
181
+ *
182
+ * @param string $token The JWT token to check
183
+ * @return bool True if the token is expired
184
+ */
185
+ public function isExpired(string $token): bool
186
+ {
187
+ try {
188
+ JWT::decode($token, new Key($this->secretKey, $this->algorithm));
189
+ return false;
190
+ } catch (ExpiredException $e) {
191
+ return true;
192
+ } catch (\Exception $e) {
193
+ // Token is invalid for another reason, not strictly "expired"
194
+ return false;
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Extract the user_id claim from a token.
200
+ *
201
+ * A convenience shortcut for the most common payload lookup.
202
+ *
203
+ * @param string $token The JWT token
204
+ * @return mixed The user_id value or null if not present / token invalid
205
+ */
206
+ public function getUserId(string $token): mixed
207
+ {
208
+ $payload = $this->payload($token);
209
+
210
+ if ($payload === null) {
211
+ return null;
212
+ }
213
+
214
+ return $payload['user_id'] ?? null;
215
+ }
216
+
217
+ /**
218
+ * Generate a long-lived refresh token.
219
+ *
220
+ * Identical to generate() but with a longer default expiry (7 days).
221
+ * Adds a 'token_type' => 'refresh' claim to distinguish from access tokens.
222
+ *
223
+ * @param array $payload Custom claims to include
224
+ * @param int $expiry Lifetime in seconds (default: 604800 = 7 days)
225
+ * @return string Encoded refresh token
226
+ */
227
+ public function generateRefreshToken(array $payload, int $expiry = 604800): string
228
+ {
229
+ $payload['token_type'] = 'refresh';
230
+
231
+ return $this->generate($payload, $expiry);
232
+ }
233
+
234
+ /**
235
+ * HTTP middleware that validates the Authorization header.
236
+ *
237
+ * Reads the Bearer token from the Authorization header, verifies it, and
238
+ * sets $_REQUEST['jwt_user'] with the decoded payload on success.
239
+ * On failure, sends a 401 JSON response via apiResponse() and exits.
240
+ *
241
+ * Usage:
242
+ * JwtAuth::middleware();
243
+ * // If execution reaches here, $_REQUEST['jwt_user'] is available
244
+ *
245
+ * @return void
246
+ */
247
+ public static function middleware(): void
248
+ {
249
+ $instance = new self();
250
+
251
+ // Extract Bearer token from Authorization header
252
+ $authHeader = $_SERVER['HTTP_AUTHORIZATION']
253
+ ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']
254
+ ?? '';
255
+
256
+ if (empty($authHeader)) {
257
+ if (function_exists('apiResponse')) {
258
+ apiResponse(401, 'Authorization header is missing.');
259
+ } else {
260
+ http_response_code(401);
261
+ header('Content-Type: application/json');
262
+ echo json_encode([
263
+ 'status' => 'error',
264
+ 'code' => 401,
265
+ 'message' => 'Authorization header is missing.',
266
+ ]);
267
+ }
268
+ exit;
269
+ }
270
+
271
+ // Strip "Bearer " prefix
272
+ $token = '';
273
+ if (preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) {
274
+ $token = $matches[1];
275
+ }
276
+
277
+ if (empty($token)) {
278
+ if (function_exists('apiResponse')) {
279
+ apiResponse(401, 'Bearer token is missing.');
280
+ } else {
281
+ http_response_code(401);
282
+ header('Content-Type: application/json');
283
+ echo json_encode([
284
+ 'status' => 'error',
285
+ 'code' => 401,
286
+ 'message' => 'Bearer token is missing.',
287
+ ]);
288
+ }
289
+ exit;
290
+ }
291
+
292
+ $result = $instance->verify($token);
293
+
294
+ if ($result['status'] !== 'success') {
295
+ if (function_exists('apiResponse')) {
296
+ apiResponse(401, $result['message']);
297
+ } else {
298
+ http_response_code(401);
299
+ header('Content-Type: application/json');
300
+ echo json_encode([
301
+ 'status' => 'error',
302
+ 'code' => 401,
303
+ 'message' => $result['message'],
304
+ ]);
305
+ }
306
+ exit;
307
+ }
308
+
309
+ // Attach decoded user payload to the request superglobal
310
+ $_REQUEST['jwt_user'] = $result['data'];
311
+ }
312
+ }