|
|
@@ -226,25 +226,37 @@ function stage_icon_for(string $title): string {
|
|
|
return 'bi-flag';
|
|
|
}
|
|
|
|
|
|
-// --- Require signed token from Contracts Admin link ---
|
|
|
-$clientid = $_GET['clientid'] ?? '';
|
|
|
-$token = $_GET['token'] ?? '';
|
|
|
-
|
|
|
-if (!preg_match('/^[A-Za-z0-9_-]+$/', $clientid)) {
|
|
|
- http_response_code(400);
|
|
|
- exit('Bad link (clientid).');
|
|
|
-}
|
|
|
-if ($token === '') {
|
|
|
- http_response_code(403);
|
|
|
- exit('Missing token.');
|
|
|
-}
|
|
|
+// Admin bypass: valid HTTP Basic Auth skips the client token check
|
|
|
+$_au = $cfg['admin_user'] ?? '';
|
|
|
+$_ap = $cfg['admin_pass'] ?? '';
|
|
|
+$isAdmin = $_au !== '' && $_ap !== ''
|
|
|
+ && isset($_SERVER['PHP_AUTH_USER'])
|
|
|
+ && $_SERVER['PHP_AUTH_USER'] === $_au
|
|
|
+ && ($_SERVER['PHP_AUTH_PW'] ?? '') === $_ap;
|
|
|
+
|
|
|
+if (!$isAdmin) {
|
|
|
+ // --- Require signed token from Contracts Admin link ---
|
|
|
+ $clientid = $_GET['clientid'] ?? '';
|
|
|
+ $token = $_GET['token'] ?? '';
|
|
|
+
|
|
|
+ if (!preg_match('/^[A-Za-z0-9_-]+$/', $clientid)) {
|
|
|
+ http_response_code(400);
|
|
|
+ exit('Bad link (clientid).');
|
|
|
+ }
|
|
|
+ if ($token === '') {
|
|
|
+ header('WWW-Authenticate: Basic realm="Modulos Contracts Admin"');
|
|
|
+ http_response_code(403);
|
|
|
+ exit('Missing token.');
|
|
|
+ }
|
|
|
|
|
|
-// Build expected token from the .md front matter secret
|
|
|
-$expected = progress_expected_token($clientid, $app_id);
|
|
|
-if (!$expected || !hash_equals($expected, $token)) {
|
|
|
- http_response_code(403);
|
|
|
- exit('Invalid or expired link.');
|
|
|
+ // Build expected token from the .md front matter secret
|
|
|
+ $expected = progress_expected_token($clientid, $app_id);
|
|
|
+ if (!$expected || !hash_equals($expected, $token)) {
|
|
|
+ http_response_code(403);
|
|
|
+ exit('Invalid or expired link.');
|
|
|
+ }
|
|
|
}
|
|
|
+unset($_au, $_ap);
|
|
|
|
|
|
?>
|
|
|
<!doctype html>
|