1
0
mirror of git://f0xx.org/ac/ac-deploy synced 2026-07-29 07:37:47 +03:00

cluster0: auth-email bearer + shorten verify URLs in outbound mail

ShortLinksRepository::shortenForOutbound; ensure-auth-email-bearer.sh;
verify-mail-lab sends shortened s.f0xx.org link in verify email body.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Anton Afanasyeu
2026-06-23 18:37:24 +02:00
parent 3d66edb405
commit aa55e03fbd
8 changed files with 111 additions and 6 deletions

View File

@@ -18,7 +18,10 @@ final class AuthMailer {
public static function sendVerifyEmail(string $to, string $verifyUrl): bool {
$subject = 'Verify your Android Cast account';
$body = "Open this link to verify your email (valid 24h):\n\n" . $verifyUrl . "\n";
$link = class_exists('ShortLinksRepository', false)
? ShortLinksRepository::shortenForOutbound($verifyUrl, 86400)
: $verifyUrl;
$body = "Open this link to verify your email (valid 24h):\n\n" . $link . "\n";
return self::send($to, $subject, $body);
}

View File

@@ -478,4 +478,44 @@ final class ShortLinksRepository {
);
$stmt->execute([$event, $bearerId, $slug, $ip, $detail]);
}
/** Outbound mail/SMS — shorten our URLs; fall back to long URL on failure. */
public static function shortenForOutbound(string $longUrl, int $ttlSeconds = 86400): string {
$longUrl = trim($longUrl);
if ($longUrl === '' || !UrlShortenerDatabase::enabled() || !UrlShortenerDatabase::ping()) {
return $longUrl;
}
$bearerId = self::resolveOutboundBearerId();
if ($bearerId <= 0) {
return $longUrl;
}
$mint = self::createLink($bearerId, $longUrl, $ttlSeconds);
if (empty($mint['ok']) || empty($mint['short_url'])) {
error_log('ShortLinksRepository: outbound shorten failed');
return $longUrl;
}
return (string) $mint['short_url'];
}
private static function resolveOutboundBearerId(): int {
$cfgId = (int) cfg('url_shortener.auth_bearer_id', 0);
if ($cfgId > 0 && self::findBearerById($cfgId) !== null) {
return $cfgId;
}
foreach (self::listBearers() as $b) {
if (!empty($b['revoked_at'])) {
continue;
}
$label = strtolower((string) ($b['label'] ?? ''));
if (str_contains($label, 'auth-email') || str_contains($label, 'auth_email')) {
return (int) ($b['id'] ?? 0);
}
}
foreach (self::listBearers() as $b) {
if (empty($b['revoked_at']) && !empty($b['can_temporary'])) {
return (int) ($b['id'] ?? 0);
}
}
return 0;
}
}