sojorn/sojorn_app/lib/config/api_config.dart
Patrick Britton c98c73f724 feat: Add capsule entry reporting system with image proxy for external GIFs
- Add capsule_reports table and admin UI: new /capsule-reports page with list/update handlers
- POST /capsules/:id/entries/:entryId/report: members can report encrypted entries with voluntary decrypted sample
- GET /image-proxy: stream external images (Reddit, GifCities) through server to hide client IPs
- group_chat_tab: add GIF picker, report button, proxy external GIF URLs through ApiConfig.proxyImageUrl()
- api.ts: add list
2026-02-18 09:03:30 -06:00

46 lines
1.5 KiB
Dart

class ApiConfig {
// Not const so we can normalize away accidentally-configured http/8080 URLs.
static final String baseUrl = _computeBaseUrl();
static String _computeBaseUrl() {
String raw = const String.fromEnvironment(
'API_BASE_URL',
defaultValue: 'https://api.sojorn.net/api/v1',
);
// Failsafe: migrate legacy domain if it slips in via environment or cache
if (raw.contains('gosojorn.com')) {
raw = raw.replaceAll('gosojorn.com', 'sojorn.net');
}
// Auto-upgrade any lingering http://api.sojorn.net:8080 (or plain http)
// to the public https endpoint behind nginx.
if (raw.startsWith('http://api.sojorn.net:8080')) {
return raw.replaceFirst(
'http://api.sojorn.net:8080',
'https://api.sojorn.net',
);
}
if (raw.startsWith('http://')) {
return 'https://${raw.substring('http://'.length)}';
}
return raw;
}
/// Wraps external GIF/image URLs (Reddit, GifCities) through the server proxy
/// so the client's IP is never sent to third-party origins.
static String proxyImageUrl(String url) {
return '$baseUrl/image-proxy?url=${Uri.encodeComponent(url)}';
}
/// Returns true if [url] is an external GIF that should be proxied.
static bool needsProxy(String url) {
return url.startsWith('https://i.redd.it/') ||
url.startsWith('https://preview.redd.it/') ||
url.startsWith('https://external-preview.redd.it/') ||
url.startsWith('https://blob.gifcities.org/gifcities/');
}
}