mirror of
git://f0xx.org/ac/ac-deploy
synced 2026-07-29 05:19:12 +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:
28
sim/cluster0/lab-seeds/backend/scripts/ensure_auth_email_bearer.php
Executable file
28
sim/cluster0/lab-seeds/backend/scripts/ensure_auth_email_bearer.php
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env php83
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/** Ensure system bearer for auth-email outbound short links. Prints bearer_id on stdout. */
|
||||
require __DIR__ . '/../src/bootstrap.php';
|
||||
|
||||
if (!UrlShortenerDatabase::enabled() || !UrlShortenerDatabase::ping()) {
|
||||
fwrite(STDERR, "url_shortener unavailable\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
foreach (ShortLinksRepository::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')) {
|
||||
echo (int) ($b['id'] ?? 0), "\n";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
$mint = ShortLinksRepository::mintBearer('auth-email-system', true, false, 5000);
|
||||
if (empty($mint['ok'])) {
|
||||
fwrite(STDERR, 'mint failed: ' . ($mint['error'] ?? '?') . "\n");
|
||||
exit(1);
|
||||
}
|
||||
echo (int) $mint['bearer_id'], "\n";
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user