mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-11 09:13:49 -04:00
Merge pull request #4557 from Vito0912/cors
Allow a whitelist of CORS origins
This commit is contained in:
commit
e510174f12
@ -131,35 +131,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grow py-2">
|
<div class="grow py-2">
|
||||||
<ui-dropdown :label="$strings.LabelSettingsDateFormat" v-model="newServerSettings.dateFormat" :items="dateFormats" small class="max-w-52" @input="(val) => updateSettingsKey('dateFormat', val)" />
|
<ui-dropdown :label="$strings.LabelSettingsDateFormat" v-model="newServerSettings.dateFormat" :items="dateFormats" small class="max-w-72" @input="(val) => updateSettingsKey('dateFormat', val)" />
|
||||||
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ dateExample }}</p>
|
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ dateExample }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grow py-2">
|
<div class="grow py-2">
|
||||||
<ui-dropdown :label="$strings.LabelSettingsTimeFormat" v-model="newServerSettings.timeFormat" :items="timeFormats" small class="max-w-52" @input="(val) => updateSettingsKey('timeFormat', val)" />
|
<ui-dropdown :label="$strings.LabelSettingsTimeFormat" v-model="newServerSettings.timeFormat" :items="timeFormats" small class="max-w-72" @input="(val) => updateSettingsKey('timeFormat', val)" />
|
||||||
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ timeExample }}</p>
|
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ timeExample }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<ui-dropdown :label="$strings.LabelLanguageDefaultServer" ref="langDropdown" v-model="newServerSettings.language" :items="$languageCodeOptions" small class="max-w-52" @input="updateServerLanguage" />
|
<ui-dropdown :label="$strings.LabelLanguageDefaultServer" ref="langDropdown" v-model="newServerSettings.language" :items="$languageCodeOptions" small class="max-w-72" @input="updateServerLanguage" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- old experimental features -->
|
<div class="pt-4">
|
||||||
<!-- <div class="pt-4">
|
<h2 class="font-semibold">{{ $strings.HeaderSettingsSecurity }}</h2>
|
||||||
<h2 class="font-semibold">{{ $strings.HeaderSettingsExperimental }}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center py-2">
|
<div class="py-2">
|
||||||
<ui-toggle-switch labeledBy="settings-experimental-features" v-model="showExperimentalFeatures" />
|
<ui-multi-select v-model="newServerSettings.allowedOrigins" :items="newServerSettings.allowedOrigins" :label="$strings.LabelCorsAllowed" class="max-w-72" @input="updateCorsOrigins" />
|
||||||
<ui-tooltip :text="$strings.LabelSettingsExperimentalFeaturesHelp">
|
</div>
|
||||||
<p class="pl-4">
|
|
||||||
<span id="settings-experimental-features">{{ $strings.LabelSettingsExperimentalFeatures }}</span>
|
|
||||||
<a :aria-label="$strings.LabelSettingsExperimentalFeaturesHelp" href="https://github.com/advplyr/audiobookshelf/discussions/75" target="_blank">
|
|
||||||
<span class="material-symbols icon-text">info</span>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</ui-tooltip>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</app-settings-content>
|
</app-settings-content>
|
||||||
@ -323,6 +314,27 @@ export default {
|
|||||||
updateServerLanguage(val) {
|
updateServerLanguage(val) {
|
||||||
this.updateSettingsKey('language', val)
|
this.updateSettingsKey('language', val)
|
||||||
},
|
},
|
||||||
|
updateCorsOrigins(val) {
|
||||||
|
const validOrigins = []
|
||||||
|
const invalidOrigins = []
|
||||||
|
|
||||||
|
val.forEach((origin) => {
|
||||||
|
const trimmedOrigin = origin.trim().toLowerCase()
|
||||||
|
try {
|
||||||
|
new URL(trimmedOrigin)
|
||||||
|
validOrigins.push(trimmedOrigin)
|
||||||
|
} catch {
|
||||||
|
invalidOrigins.push(trimmedOrigin)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (invalidOrigins.length > 0) {
|
||||||
|
this.$toast.error(this.$strings.ToastInvalidUrls)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.newServerSettings.allowedOrigins = validOrigins
|
||||||
|
this.updateSettingsKey('allowedOrigins', validOrigins)
|
||||||
|
},
|
||||||
updateSettingsKey(key, val) {
|
updateSettingsKey(key, val) {
|
||||||
if (key === 'scannerDisableWatcher') {
|
if (key === 'scannerDisableWatcher') {
|
||||||
this.newServerSettings.scannerDisableWatcher = val
|
this.newServerSettings.scannerDisableWatcher = val
|
||||||
@ -352,6 +364,7 @@ export default {
|
|||||||
initServerSettings() {
|
initServerSettings() {
|
||||||
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
||||||
this.newServerSettings.sortingPrefixes = [...(this.newServerSettings.sortingPrefixes || [])]
|
this.newServerSettings.sortingPrefixes = [...(this.newServerSettings.sortingPrefixes || [])]
|
||||||
|
this.newServerSettings.allowedOrigins = [...(this.newServerSettings.allowedOrigins || [])]
|
||||||
this.scannerEnableWatcher = !this.newServerSettings.scannerDisableWatcher
|
this.scannerEnableWatcher = !this.newServerSettings.scannerDisableWatcher
|
||||||
|
|
||||||
this.homepageUseBookshelfView = this.newServerSettings.homeBookshelfView != this.$constants.BookshelfView.DETAIL
|
this.homepageUseBookshelfView = this.newServerSettings.homeBookshelfView != this.$constants.BookshelfView.DETAIL
|
||||||
|
@ -199,6 +199,7 @@
|
|||||||
"HeaderSettingsExperimental": "Experimental Features",
|
"HeaderSettingsExperimental": "Experimental Features",
|
||||||
"HeaderSettingsGeneral": "General",
|
"HeaderSettingsGeneral": "General",
|
||||||
"HeaderSettingsScanner": "Scanner",
|
"HeaderSettingsScanner": "Scanner",
|
||||||
|
"HeaderSettingsSecurity": "Security",
|
||||||
"HeaderSettingsWebClient": "Web Client",
|
"HeaderSettingsWebClient": "Web Client",
|
||||||
"HeaderSleepTimer": "Sleep Timer",
|
"HeaderSleepTimer": "Sleep Timer",
|
||||||
"HeaderStatsLargestItems": "Largest Items",
|
"HeaderStatsLargestItems": "Largest Items",
|
||||||
@ -293,6 +294,7 @@
|
|||||||
"LabelContinueListening": "Continue Listening",
|
"LabelContinueListening": "Continue Listening",
|
||||||
"LabelContinueReading": "Continue Reading",
|
"LabelContinueReading": "Continue Reading",
|
||||||
"LabelContinueSeries": "Continue Series",
|
"LabelContinueSeries": "Continue Series",
|
||||||
|
"LabelCorsAllowed": "Allowed CORS Origins",
|
||||||
"LabelCover": "Cover",
|
"LabelCover": "Cover",
|
||||||
"LabelCoverImageURL": "Cover Image URL",
|
"LabelCoverImageURL": "Cover Image URL",
|
||||||
"LabelCoverProvider": "Cover Provider",
|
"LabelCoverProvider": "Cover Provider",
|
||||||
@ -1034,6 +1036,7 @@
|
|||||||
"ToastInvalidImageUrl": "Invalid image URL",
|
"ToastInvalidImageUrl": "Invalid image URL",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Invalid max episodes to download",
|
"ToastInvalidMaxEpisodesToDownload": "Invalid max episodes to download",
|
||||||
"ToastInvalidUrl": "Invalid URL",
|
"ToastInvalidUrl": "Invalid URL",
|
||||||
|
"ToastInvalidUrls": "One or more URLs are invalid",
|
||||||
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
||||||
"ToastItemDeletedFailed": "Failed to delete item",
|
"ToastItemDeletedFailed": "Failed to delete item",
|
||||||
"ToastItemDeletedSuccess": "Deleted item",
|
"ToastItemDeletedSuccess": "Deleted item",
|
||||||
|
@ -240,8 +240,8 @@ class Server {
|
|||||||
* Running in development allows cors to allow testing the mobile apps in the browser
|
* Running in development allows cors to allow testing the mobile apps in the browser
|
||||||
* or env variable ALLOW_CORS = '1'
|
* or env variable ALLOW_CORS = '1'
|
||||||
*/
|
*/
|
||||||
if (global.AllowCors || Logger.isDev || req.path.match(/\/api\/items\/([a-z0-9-]{36})\/(ebook|cover)(\/[0-9]+)?/)) {
|
if (global.AllowCors || Logger.isDev || req.path.match(/\/api\/items\/([a-z0-9-]{36})\/(ebook|cover)(\/[0-9]+)?/) || global.ServerSettings.allowedOrigins?.length) {
|
||||||
const allowedOrigins = ['capacitor://localhost', 'http://localhost']
|
const allowedOrigins = ['capacitor://localhost', 'http://localhost', ...(global.ServerSettings.allowedOrigins ? global.ServerSettings.allowedOrigins : [])]
|
||||||
if (global.AllowCors || Logger.isDev || allowedOrigins.some((o) => o === req.get('origin'))) {
|
if (global.AllowCors || Logger.isDev || allowedOrigins.some((o) => o === req.get('origin'))) {
|
||||||
res.header('Access-Control-Allow-Origin', req.get('origin'))
|
res.header('Access-Control-Allow-Origin', req.get('origin'))
|
||||||
res.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
|
res.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
|
||||||
|
@ -53,6 +53,7 @@ class ServerSettings {
|
|||||||
this.dateFormat = 'MM/dd/yyyy'
|
this.dateFormat = 'MM/dd/yyyy'
|
||||||
this.timeFormat = 'HH:mm'
|
this.timeFormat = 'HH:mm'
|
||||||
this.language = 'en-us'
|
this.language = 'en-us'
|
||||||
|
this.allowedOrigins = []
|
||||||
|
|
||||||
this.logLevel = Logger.logLevel
|
this.logLevel = Logger.logLevel
|
||||||
|
|
||||||
@ -120,6 +121,7 @@ class ServerSettings {
|
|||||||
this.dateFormat = settings.dateFormat || 'MM/dd/yyyy'
|
this.dateFormat = settings.dateFormat || 'MM/dd/yyyy'
|
||||||
this.timeFormat = settings.timeFormat || 'HH:mm'
|
this.timeFormat = settings.timeFormat || 'HH:mm'
|
||||||
this.language = settings.language || 'en-us'
|
this.language = settings.language || 'en-us'
|
||||||
|
this.allowedOrigins = settings.allowedOrigins || []
|
||||||
this.logLevel = settings.logLevel || Logger.logLevel
|
this.logLevel = settings.logLevel || Logger.logLevel
|
||||||
this.version = settings.version || null
|
this.version = settings.version || null
|
||||||
this.buildNumber = settings.buildNumber || 0 // Added v2.4.5
|
this.buildNumber = settings.buildNumber || 0 // Added v2.4.5
|
||||||
@ -231,6 +233,7 @@ class ServerSettings {
|
|||||||
dateFormat: this.dateFormat,
|
dateFormat: this.dateFormat,
|
||||||
timeFormat: this.timeFormat,
|
timeFormat: this.timeFormat,
|
||||||
language: this.language,
|
language: this.language,
|
||||||
|
allowedOrigins: this.allowedOrigins,
|
||||||
logLevel: this.logLevel,
|
logLevel: this.logLevel,
|
||||||
version: this.version,
|
version: this.version,
|
||||||
buildNumber: this.buildNumber,
|
buildNumber: this.buildNumber,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user