fix(download): pin frontend link generation to fixed relay config

The runtime kept reading aksrt_download_config after the settings page was
removed, so the frontend still issued download links per the stale option
values instead of the built-in defaults.

- Pin endpoint, per-token uses and TTL to built-in constants and drop all
  option reads plus the is_enabled() master switch
- Remove the now-unreachable direct-download branches from the download
  box template and the paid-card download helper
- Lock the pinned contract in the download contract tests
This commit is contained in:
2026-09-24 18:45:08 +08:00
parent 800baca0ca
commit d49fd9f6a4
4 changed files with 51 additions and 130 deletions
+13 -56
View File
@@ -12,11 +12,12 @@ class Download {
const TOKEN_LEN = 48;
const QUERY_VAR = 'aksrt_dl_token';
// Hardened fallbacks used when the aksrt_download_config option is
// missing or contains values the admin validation would reject.
const FALLBACK_ENDPOINT = 'download';
const FALLBACK_MAX_USES = 1;
const FALLBACK_TTL_MINUTES = 10;
// Fixed relay configuration. The admin download-config settings page was
// removed, so these constants are the single source of truth for the
// site-routed download system (endpoint, per-token uses, TTL).
const ENDPOINT = 'download';
const MAX_USES = 1;
const TTL_MINUTES = 10;
private static $instance = null;
@@ -69,51 +70,17 @@ class Download {
}
/**
* Master switch for the site-routed download system (aksrt_download_config
* "enabled", default true). When off, download buttons render the raw
* source URLs directly and every token route/endpoint below stays dormant.
*/
public function is_enabled(): bool {
$cfg = get_option('aksrt_download_config', []);
if (!is_array($cfg)) {
return true;
}
return !isset($cfg['enabled']) || !empty($cfg['enabled']);
}
/**
* Effective download settings (aksrt_download_config), clamped so a
* corrupted option can never break routing or accounting.
* Effective download settings for the fixed relay configuration.
*/
private function config(): array {
$cfg = get_option('aksrt_download_config', []);
if (!is_array($cfg)) {
$cfg = [];
}
$alias = trim((string) ($cfg['url_alias'] ?? self::FALLBACK_ENDPOINT));
if ($alias === '' || strlen($alias) > 48 || !preg_match('/^[A-Za-z0-9_-]+$/', $alias)) {
$alias = self::FALLBACK_ENDPOINT;
}
$max_uses = isset($cfg['default_max_uses']) ? (int) $cfg['default_max_uses'] : self::FALLBACK_MAX_USES;
$max_uses = min(100, max(1, $max_uses));
$ttl_minutes = isset($cfg['ttl_minutes']) ? (int) $cfg['ttl_minutes'] : self::FALLBACK_TTL_MINUTES;
$ttl_minutes = min(1440, max(1, $ttl_minutes));
return [
'endpoint' => $alias,
'max_uses' => $max_uses,
'ttl' => $ttl_minutes * MINUTE_IN_SECONDS,
'endpoint' => self::ENDPOINT,
'max_uses' => self::MAX_USES,
'ttl' => self::TTL_MINUTES * MINUTE_IN_SECONDS,
];
}
public function register_rewrite(): void {
if (!$this->is_enabled()) {
return;
}
add_rewrite_rule(
'^' . preg_quote($this->config()['endpoint'], '/') . '/([A-Za-z0-9]{1,64})/?$',
'index.php?' . self::QUERY_VAR . '=$matches[1]',
@@ -122,12 +89,11 @@ class Download {
}
/**
* Re-flush rewrite rules whenever the configured alias or the master
* switch changes, using the same version-marker approach as Auth\Router.
* Re-flush rewrite rules on theme version changes, using the same
* version-marker approach as Auth\Router.
*/
public function maybe_flush_rewrite(): void {
$endpoint = $this->is_enabled() ? $this->config()['endpoint'] : 'off';
$version = AKSRT_VERSION . ':download-endpoint:' . $endpoint;
$version = AKSRT_VERSION . ':download-endpoint:' . self::ENDPOINT;
if ((string) get_option('aksrt_dl_rewrite_version') !== $version) {
flush_rewrite_rules(false);
update_option('aksrt_dl_rewrite_version', $version);
@@ -140,10 +106,6 @@ class Download {
}
public function register_routes(): void {
if (!$this->is_enabled()) {
return;
}
register_rest_route('aksrt/v1', '/download/request', [
'methods' => 'POST',
'callback' => [$this, 'rest_request'],
@@ -257,11 +219,6 @@ class Download {
$this->fail_410();
}
// Master switch off: the token system is retired, links are dead ends.
if (!$this->is_enabled()) {
$this->fail_410();
}
global $wpdb;
$table = \AKSRT\Core\DBMigrator::table('dl_token');
if (!$table) $this->fail_410();