Skip to content

Commit

Permalink
Add a Clear cache feature - Closes #316
Browse files Browse the repository at this point in the history
  • Loading branch information
Bubka committed Mar 7, 2024
1 parent fb029f7 commit edd810c
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 22 deletions.
37 changes: 36 additions & 1 deletion app/Http/Controllers/SystemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Services\ReleaseRadarService;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

Expand Down Expand Up @@ -62,7 +63,7 @@ public function latestRelease(Request $request, ReleaseRadarService $releaseRada
}

/**
* Send a test email.
* Send a test email
*
* @return \Illuminate\Http\JsonResponse
*/
Expand All @@ -76,4 +77,38 @@ public function testEmail(Request $request)

return response()->json(['message' => 'Ok']);
}

/**
* Clears all app caches and rebuild them
*
* @return \Illuminate\Http\JsonResponse
*/
public function optimize(Request $request)
{
$configCode = Artisan::call('config:cache');
$routeCode = Artisan::call('route:cache');
$eventCode = Artisan::call('event:cache');
$viewCode = Artisan::call('view:cache');

return response()->json([
'config-exit-code' => $configCode,
'route-exit-code' => $routeCode,
'event-exit-code' => $eventCode,
'view-exit-code' => $viewCode,
], 200);
}

/**
* Clears application cache
*
* @return \Illuminate\Http\JsonResponse
*/
public function clear(Request $request)
{
$exitCode = Artisan::call('optimize:clear');

return response()->json(['exit-code' => $exitCode], 200);
}


}
24 changes: 20 additions & 4 deletions resources/js/services/systemService.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,39 @@ export default {
* @returns Promise
*/
getSystemInfos(config = {}) {
return webClient.get('infos', { ...config })
return webClient.get('system/infos', { ...config })
},

/**
*
* @returns Promise
*/
getLastRelease(config = {}) {
return webClient.get('latestRelease', { ...config })
return webClient.get('system/latestRelease', { ...config })
},

/**
*
* @returns Promise
*/
sendTestEmail(config = {}) {
return webClient.post('testEmail', { ...config })
}
return webClient.post('system/test-email', { ...config })
},

/**
*
* @returns Promise
*/
clearCache(config = {}) {
return webClient.get('system/clear-cache', { ...config })
},

/**
*
* @returns Promise
*/
optimize(config = {}) {
return webClient.get('system/optimize', { ...config })
},

}
37 changes: 36 additions & 1 deletion resources/js/views/admin/AppSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
const infos = ref()
const listInfos = ref(null)
const isSendingTestEmail = ref(false)
const isClearingCache = ref(false)
const fieldErrors = ref({
restrictList: null,
restrictRule: null,
Expand Down Expand Up @@ -91,6 +92,20 @@
})
}
/**
* clears app cache
*/
function clearCache() {
isClearingCache.value = true;
systemService.clearCache().then(response => {
useNotifyStore().success({ type: 'is-success', text: trans('admin.cache_cleared') })
})
.finally(() => {
isClearingCache.value = false;
})
}
onBeforeRouteLeave((to) => {
if (! to.name.startsWith('admin.')) {
notify.clear()
Expand Down Expand Up @@ -134,6 +149,7 @@
<!-- Check for update -->
<FormCheckbox v-model="_settings.checkForUpdate" @update:model-value="val => saveSetting('checkForUpdate', val)" fieldName="checkForUpdate" label="commons.check_for_update" help="commons.check_for_update_help" />
<VersionChecker />
<!-- email config test -->
<div class="field">
<!-- <h5 class="title is-5">{{ $t('settings.security') }}</h5> -->
<label class="label" v-html="$t('admin.forms.test_email.label')" />
Expand All @@ -149,7 +165,8 @@
<span>{{ $t('commons.send') }}</span>
</button>
</div>
</div>
</div>

<h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.security') }}</h4>
<!-- protect db -->
<FormCheckbox v-model="_settings.useEncryption" @update:model-value="val => saveSetting('useEncryption', val)" fieldName="useEncryption" label="admin.forms.use_encryption.label" help="admin.forms.use_encryption.help" />
Expand All @@ -165,7 +182,25 @@
<!-- disable SSO registration -->
<FormCheckbox v-model="_settings.enableSso" @update:model-value="val => saveSetting('enableSso', val)" fieldName="enableSso" label="admin.forms.enable_sso.label" help="admin.forms.enable_sso.help" />
</form>

<h4 class="title is-4 pt-5 has-text-grey-light">{{ $t('commons.environment') }}</h4>
<!-- cache management -->
<div class="field">
<!-- <h5 class="title is-5">{{ $t('settings.security') }}</h5> -->
<label class="label" v-html="$t('admin.forms.cache_management.label')" />
<p class="help" v-html="$t('admin.forms.cache_management.help')" />
</div>
<div class="field mb-5 is-grouped">
<p class="control">
<button type="button" :class="isClearingCache ? 'is-loading' : ''" class="button is-link is-rounded is-small" @click="clearCache">
{{ $t('commons.clear') }}
</button>
</p>
</div>
<!-- env vars -->
<div class="field">
<label class="label" v-html="$t('admin.variables')" />
</div>
<div v-if="infos" class="about-debug box is-family-monospace is-size-7">
<CopyButton id="btnCopyEnvVars" :token="listInfos?.innerText" />
<ul ref="listInfos" id="listInfos">
Expand Down
7 changes: 7 additions & 0 deletions resources/lang/en/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
'user_role_updated' => 'User role updated',
'pats_succesfully_revoked' => 'User\'s PATs successfully revoked',
'security_devices_succesfully_revoked' => 'User\'s security devices successfully revoked',
'variables' => 'Variables',
'cache_cleared' => 'Cache cleared',
'cache_optimized' => 'Cache optimized',
'check_now' => 'Check now',
'view_on_github' => 'View on Github',
'x_is_available' => ':version is available',
Expand Down Expand Up @@ -99,6 +102,10 @@
'label' => 'Email configuration test',
'help' => 'Send a test email to control your instance\'s email configuration. It is important to have a working configuration, otherwise users will not be able to request a reset password.',
'email_will_be_send_to_x' => 'The email will be send to <span class="is-family-code has-text-info">:email</span>',
],
'cache_management' => [
'label' => 'Cache management',
'help' => 'Sometimes cache needs to be cleared, for instance after a change to environment variables or an update. You can do it from here.',
]
],

Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/commons.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@
'information' => 'Information',
'permissions' => 'Permissions',
'send' => 'Send',
'optimize' => 'Optimize',
];
17 changes: 9 additions & 8 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,21 @@
Route::delete('webauthn/credentials/{credential}', [WebAuthnManageController::class, 'delete'])->name('webauthn.credentials.delete');
});

Route::get('refresh-csrf', function () {
return csrf_token();
});


/**
* Routes protected by an authentication guard and restricted to administrators
*/
Route::group(['middleware' => ['behind-auth', 'admin']], function () {
Route::get('infos', [SystemController::class, 'infos'])->name('system.infos');
Route::post('testEmail', [SystemController::class, 'testEmail'])->name('system.testEmail');
Route::get('system/infos', [SystemController::class, 'infos'])->name('system.infos');
Route::post('system/test-email', [SystemController::class, 'testEmail'])->name('system.testEmail');
});

Route::get('latestRelease', [SystemController::class, 'latestRelease'])->name('system.latestRelease');
Route::get('system/optimize', [SystemController::class, 'optimize'])->name('system.optimize');
Route::get('system/clear-cache', [SystemController::class, 'clear'])->name('system.clear');
Route::get('system/latestRelease', [SystemController::class, 'latestRelease'])->name('system.latestRelease');

Route::get('refresh-csrf', function () {
return csrf_token();
});

/**
* Route for the main landing view
Expand Down
36 changes: 28 additions & 8 deletions tests/Feature/Http/SystemControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function setUp() : void
*/
public function test_infos_returns_unauthorized()
{
$response = $this->json('GET', '/infos')
$response = $this->json('GET', '/system/infos')
->assertUnauthorized();
}

Expand All @@ -47,7 +47,7 @@ public function test_infos_returns_unauthorized()
public function test_infos_returns_forbidden()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/infos')
->json('GET', '/system/infos')
->assertForbidden();
}

Expand All @@ -57,7 +57,7 @@ public function test_infos_returns_forbidden()
public function test_infos_returns_only_base_collection()
{
$response = $this->actingAs($this->admin, 'api-guard')
->json('GET', '/infos')
->json('GET', '/system/infos')
->assertOk()
->assertJsonStructure([
'common' => [
Expand Down Expand Up @@ -88,7 +88,7 @@ public function test_infos_returns_only_base_collection()
public function test_infos_returns_proxy_collection_when_signed_in_behind_proxy()
{
$response = $this->actingAs($this->admin, 'reverse-proxy-guard')
->json('GET', '/infos')
->json('GET', '/system/infos')
->assertOk()
->assertJsonStructure([
'common' => [
Expand All @@ -109,7 +109,7 @@ public function test_latestrelease_runs_manual_scan()
->once()
->andReturn('new_release');

$response = $this->json('GET', '/latestRelease')
$response = $this->json('GET', '/system/latestRelease')
->assertOk()
->assertJson([
'newRelease' => 'new_release',
Expand All @@ -124,7 +124,7 @@ public function test_testEmail_sends_a_notification()
Notification::fake();

$response = $this->actingAs($this->admin, 'web-guard')
->json('POST', '/testEmail', []);
->json('POST', '/system/test-email', []);

$response->assertStatus(200);

Expand All @@ -136,7 +136,7 @@ public function test_testEmail_sends_a_notification()
*/
public function test_testEmail_returns_unauthorized()
{
$response = $this->json('GET', '/infos')
$response = $this->json('GET', '/system/infos')
->assertUnauthorized();
}

Expand All @@ -146,7 +146,27 @@ public function test_testEmail_returns_unauthorized()
public function test_testEmail_returns_forbidden()
{
$response = $this->actingAs($this->user, 'api-guard')
->json('GET', '/infos')
->json('GET', '/system/infos')
->assertForbidden();
}

/**
* @test
*/
public function test_clearCache_returns_success()
{
$response = $this->json('GET', '/system/clear-cache');

$response->assertStatus(200);
}

/**
* @test
*/
public function test_optimize_returns_success()
{
$response = $this->json('GET', '/system/optimize');

$response->assertStatus(200);
}
}

0 comments on commit edd810c

Please sign in to comment.