Switch to only defining CSRF token on pages that use API calls.

This commit is contained in:
Buster "Silver Eagle" Neece 2021-08-28 18:09:24 -05:00
parent 75c1bce473
commit 9bbae3d6b6
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
6 changed files with 46 additions and 37 deletions

View File

@ -43,7 +43,7 @@ return [
],
'vue-base' => [
'order' => 4,
'order' => 5,
'files' => [
'js' => [
[
@ -53,25 +53,13 @@ return [
],
'inline' => [
'js' => [
function (Request $request) {
$csrfJson = 'null';
$csrf = $request->getAttribute(ServerRequest::ATTR_SESSION_CSRF);
if ($csrf instanceof Csrf) {
$csrfToken = $csrf->generate(ApiAuth::API_CSRF_NAMESPACE);
$csrfJson = json_encode($csrfToken, JSON_THROW_ON_ERROR);
}
return <<<JS
VueBase.default(App.locale, ${csrfJson});
JS;
},
'VueBase.default()',
],
],
],
'bootstrap-vue' => [
'order' => 3,
'order' => 4,
'files' => [
'js' => [
[
@ -87,7 +75,7 @@ return [
],
'vue-component-common' => [
'order' => 3,
'order' => 4,
'require' => ['vue', 'vue-base'],
'files' => [
'js' => [
@ -181,9 +169,10 @@ return [
'locale' => $locale,
'locale_short' => $localeShort,
'locale_with_dashes' => $localeWithDashes,
'api_csrf' => null,
];
return 'let App = ' . json_encode($app) . ';';
return 'let App = ' . json_encode($app, JSON_THROW_ON_ERROR) . ';';
},
<<<'JS'
let currentTheme = document.documentElement.getAttribute('data-theme');
@ -213,6 +202,24 @@ return [
],
],
// Require this if using any non-GET API calls.
'uses-api' => [
'order' => 3,
'inline' => [
'js' => [
function (Request $request) {
$csrfJson = 'null';
$csrf = $request->getAttribute(ServerRequest::ATTR_SESSION_CSRF);
if ($csrf instanceof Csrf) {
$csrfToken = $csrf->generate(ApiAuth::API_CSRF_NAMESPACE);
$csrfJson = json_encode($csrfToken, JSON_THROW_ON_ERROR);
}
return "App.api_csrf = ${csrfJson};";
},
],
],
],
/*
* Asset collections
*/
@ -469,7 +476,7 @@ return [
'Vue_Dashboard' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'chartjs'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'chartjs'],
// Auto-managed by Assets
],
@ -487,13 +494,13 @@ return [
'Vue_AdminBranding' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'fancybox', 'codemirror'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'codemirror'],
// Auto-managed by Assets
],
'Vue_AdminStorageLocations' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'],
// Auto-managed by Assets
],
@ -538,61 +545,61 @@ return [
'Vue_StationsMedia' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'fancybox'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox'],
// Auto-managed by Assets
],
'Vue_StationsMounts' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'],
// Auto-managed by Assets
],
'Vue_StationsPlaylists' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment_timezone'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment_timezone'],
// Auto-managed by Assets
],
'Vue_StationsPodcasts' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
// Auto-managed by Assets
],
'Vue_StationsPodcastEpisodes' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
// Auto-managed by Assets
],
'Vue_StationsProfile' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment', 'fancybox'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment', 'fancybox'],
// Auto-managed by Assets
],
'Vue_StationsQueue' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets
],
'Vue_StationsRemotes' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'],
// Auto-managed by Assets
],
'Vue_StationsStreamers' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets
],
'Vue_StationsReportsOverview' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'chartjs'],
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'chartjs'],
// Auto-managed by Assets
],
];

View File

@ -68,7 +68,7 @@ export default {
singleFile: !this.allowMultiple,
headers: {
'Accept': 'application/json',
'X-API-CSRF': this.axios.defaults.headers.common['X-API-CSRF']
'X-API-CSRF': App.api_csrf
},
withCredentials: true,
allowDuplicateUploads: true,

View File

@ -15,10 +15,14 @@ export default function (lang, csrf) {
silent: true
});
Vue.config.language = lang;
if (typeof App.locale !== 'undefined') {
Vue.config.language = App.locale;
}
// Configure auto-CSRF on requests
axios.defaults.headers.common['X-API-CSRF'] = csrf;
if (typeof App.api_csrf !== 'undefined') {
axios.defaults.headers.common['X-API-CSRF'] = App.api_csrf;
}
Vue.use(VueAxios, axios);
}

View File

@ -127,7 +127,6 @@ class View extends Engine
'auth' => $request->getAttribute(ServerRequest::ATTR_AUTH),
'acl' => $request->getAttribute(ServerRequest::ATTR_ACL),
'customization' => $request->getAttribute(ServerRequest::ATTR_CUSTOMIZATION),
'csrf' => $request->getAttribute(ServerRequest::ATTR_SESSION_CSRF),
'flash' => $request->getAttribute(ServerRequest::ATTR_SESSION_FLASH),
'user' => $request->getAttribute(ServerRequest::ATTR_USER),
]

View File

@ -25,9 +25,7 @@ $(function () {
$.ajax({
type: 'POST',
headers: {
"X-API-CSRF": <?=$this->escapeJs(
$csrf->generate(\App\Middleware\Auth\ApiAuth::API_CSRF_NAMESPACE)
) ?>
"X-API-CSRF": App.api_csrf
},
url: btn.attr('href'),
success: function (data) {

View File

@ -7,6 +7,7 @@
$assets
->load('moment')
->load('moment_timezone')
->load('uses-api')
->addInlineJs($this->fetch('stations/sidebar.js', ['station' => $station]), 95);
?>