Add the ability to set a proxy for outgoing requests - Closes #252

This commit is contained in:
Bubka 2023-12-13 16:49:35 +01:00
parent 15c31c3341
commit e503826012
9 changed files with 41 additions and 15 deletions

View File

@ -236,6 +236,8 @@ WEBAUTHN_USER_VERIFICATION=preferred
# GITHUB_CLIENT_SECRET= # GITHUB_CLIENT_SECRET=
#### Proxy settings ####
# Use this setting to declare trusted proxied. # Use this setting to declare trusted proxied.
# Supported: # Supported:
# '*': to trust any proxy # '*': to trust any proxy
@ -244,6 +246,13 @@ WEBAUTHN_USER_VERIFICATION=preferred
TRUSTED_PROXIES=null TRUSTED_PROXIES=null
# Proxy for outgoing requests like new releases detection or logo fetching.
# You can provide a proxy URL that contains a scheme, username, and password.
# For example, "http://username:password@192.168.16.1:10".
PROXY_FOR_OUTGOING_REQUESTS=null
# Leave the following configuration vars as is. # Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing. # Unless you like to tinker and know what you're doing.

4
Dockerfile vendored
View File

@ -223,6 +223,10 @@ ENV \
# '*': to trust any proxy # '*': to trust any proxy
# A comma separated IP list: The list of proxies IP to trust # A comma separated IP list: The list of proxies IP to trust
TRUSTED_PROXIES=null \ TRUSTED_PROXIES=null \
# Proxy for outgoing requests like new releases detection or logo fetching.
# You can provide a proxy URL that contains a scheme, username, and password.
# For example, "http://username:password@192.168.16.1:10".
PROXY_FOR_OUTGOING_REQUESTS=null \
# Leave the following configuration vars as is. # Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing. # Unless you like to tinker and know what you're doing.
BROADCAST_DRIVER=log \ BROADCAST_DRIVER=log \

View File

@ -691,7 +691,9 @@ class TwoFAccount extends Model implements Sortable
$newFilename = self::getUniqueFilename($path_parts['extension']); $newFilename = self::getUniqueFilename($path_parts['extension']);
try { try {
$response = Http::retry(3, 100)->get($url); $response = Http::withOptions([
'proxy' => config('2fauth.config.outgoingProxy'),
])->retry(3, 100)->get($url);
if ($response->successful()) { if ($response->successful()) {
Storage::disk('imagesLink')->put($newFilename, $response->body()); Storage::disk('imagesLink')->put($newFilename, $response->body());

View File

@ -92,7 +92,9 @@ class LogoService
protected function cacheTfaDirectorySource() : void protected function cacheTfaDirectorySource() : void
{ {
try { try {
$response = Http::retry(3, 100)->get(self::TFA_URL); $response = Http::withOptions([
'proxy' => config('2fauth.config.outgoingProxy'),
])->retry(3, 100)->get(self::TFA_URL);
$coll = collect(json_decode(htmlspecialchars_decode($response->body()), true)) /* @phpstan-ignore-line */ $coll = collect(json_decode(htmlspecialchars_decode($response->body()), true)) /* @phpstan-ignore-line */
->mapWithKeys(function ($item, $key) { ->mapWithKeys(function ($item, $key) {
@ -117,8 +119,9 @@ class LogoService
protected function fetchLogo(string $logoFile) : void protected function fetchLogo(string $logoFile) : void
{ {
try { try {
$response = Http::retry(3, 100) $response = Http::withOptions([
->get('https://raw.githubusercontent.com/2factorauth/twofactorauth/master/img/' . $logoFile[0] . '/' . $logoFile); 'proxy' => config('2fauth.config.outgoingProxy'),
])->retry(3, 100)->get('https://raw.githubusercontent.com/2factorauth/twofactorauth/master/img/' . $logoFile[0] . '/' . $logoFile);
if ($response->successful()) { if ($response->successful()) {
Storage::disk('logos')->put($logoFile, $response->body()) Storage::disk('logos')->put($logoFile, $response->body())

View File

@ -22,9 +22,9 @@ class ReleaseRadarService
/** /**
* Run a manual release scan * Run a manual release scan
* *
* @return false|string False if no new release, the new release number otherwise * @return string|null|false False if no new release, null if check failed, the new release number otherwise
*/ */
public static function manualScan() : false|string public static function manualScan() : string|null|false
{ {
return self::newRelease(); return self::newRelease();
} }
@ -32,13 +32,15 @@ class ReleaseRadarService
/** /**
* Run a release scan * Run a release scan
* *
* @return false|string False if no new release, the new release number otherwise * @return string|null|false False if no new release, null if check failed, the new release number otherwise
*/ */
protected static function newRelease() : false|string protected static function newRelease() : string|null|false
{ {
Log::info('Release scan started'); Log::info('Release scan started');
$latestRelease = self::getLatestReleaseData();
if ($latestReleaseData = json_decode(self::getLatestReleaseData())) { if ($latestRelease) {
$latestReleaseData = json_decode($latestRelease);
$githubVersion = Helpers::cleanVersionNumber($latestReleaseData->tag_name); $githubVersion = Helpers::cleanVersionNumber($latestReleaseData->tag_name);
$installedVersion = Helpers::cleanVersionNumber(config('2fauth.version')); $installedVersion = Helpers::cleanVersionNumber(config('2fauth.version'));
@ -55,7 +57,7 @@ class ReleaseRadarService
} }
} }
return false; return $latestRelease ? false : null;
} }
/** /**
@ -66,8 +68,9 @@ class ReleaseRadarService
$url = config('2fauth.latestReleaseUrl'); $url = config('2fauth.latestReleaseUrl');
try { try {
$response = Http::retry(3, 100) $response = Http::withOptions([
->get($url); 'proxy' => config('2fauth.config.outgoingProxy'),
])->retry(3, 100)->get($url);
if ($response->successful()) { if ($response->successful()) {
Settings::set('lastRadarScan', time()); Settings::set('lastRadarScan', time());

View File

@ -25,6 +25,7 @@ return [
'isDemoApp' => env('IS_DEMO_APP', false), 'isDemoApp' => env('IS_DEMO_APP', false),
'isTestingApp' => env('IS_TESTING_APP', false), 'isTestingApp' => env('IS_TESTING_APP', false),
'trustedProxies' => env('TRUSTED_PROXIES', null), 'trustedProxies' => env('TRUSTED_PROXIES', null),
'outgoingProxy' => env('PROXY_FOR_OUTGOING_REQUESTS', ''),
'proxyLogoutUrl' => env('PROXY_LOGOUT_URL', null), 'proxyLogoutUrl' => env('PROXY_LOGOUT_URL', null),
'appSubdirectory' => env('APP_SUBDIRECTORY', ''), 'appSubdirectory' => env('APP_SUBDIRECTORY', ''),
], ],

View File

@ -121,6 +121,10 @@ services:
# '*': to trust any proxy # '*': to trust any proxy
# A comma separated IP list: The list of proxies IP to trust # A comma separated IP list: The list of proxies IP to trust
- TRUSTED_PROXIES=null - TRUSTED_PROXIES=null
# Proxy for outgoing requests like new releases detection or logo fetching.
# You can provide a proxy URL that contains a scheme, username, and password.
# For example, "http://username:password@192.168.16.1:10".
- PROXY_FOR_OUTGOING_REQUESTS=null
# Leave the following configuration vars as is. # Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing. # Unless you like to tinker and know what you're doing.
- BROADCAST_DRIVER=log - BROADCAST_DRIVER=log

View File

@ -13,7 +13,7 @@
await systemService.getLastRelease({returnError: true}) await systemService.getLastRelease({returnError: true})
.then(response => { .then(response => {
appSettings.latestRelease = response.data.newRelease appSettings.latestRelease = response.data.newRelease
isUpToDate.value = response.data.newRelease === false isUpToDate.value = response.data.newRelease === null ? null : response.data.newRelease === false
}) })
.catch(() => { .catch(() => {
isUpToDate.value = null isUpToDate.value = null

View File

@ -71,7 +71,7 @@ class ReleaseRadarServiceTest extends FeatureTestCase
// We do not fake the http request so an exception will be thrown // We do not fake the http request so an exception will be thrown
Http::preventStrayRequests(); Http::preventStrayRequests();
$this->assertFalse(ReleaseRadarService::manualScan()); $this->assertNull(ReleaseRadarService::manualScan());
} }
/** /**
@ -86,7 +86,7 @@ class ReleaseRadarServiceTest extends FeatureTestCase
$url => Http::response(null, 400), $url => Http::response(null, 400),
]); ]);
$this->assertFalse(ReleaseRadarService::manualScan()); $this->assertNull(ReleaseRadarService::manualScan());
} }
/** /**