mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Add:Server setting to allow iframe & update UI to differentiate web client settings #3684
This commit is contained in:
parent
726adbb3bf
commit
57906540fe
@ -42,11 +42,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center py-2 mb-2">
|
|
||||||
<ui-toggle-switch labeledBy="settings-chromecast-support" v-model="newServerSettings.chromecastEnabled" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('chromecastEnabled', val)" />
|
|
||||||
<p class="pl-4" id="settings-chromecast-support">{{ $strings.LabelSettingsChromecastSupport }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="pt-4">
|
<div class="pt-4">
|
||||||
<h2 class="font-semibold">{{ $strings.HeaderSettingsScanner }}</h2>
|
<h2 class="font-semibold">{{ $strings.HeaderSettingsScanner }}</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -94,6 +89,20 @@
|
|||||||
</p>
|
</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="pt-4">
|
||||||
|
<h2 class="font-semibold">{{ $strings.HeaderSettingsWebClient }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center py-2">
|
||||||
|
<ui-toggle-switch labeledBy="settings-chromecast-support" v-model="newServerSettings.chromecastEnabled" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('chromecastEnabled', val)" />
|
||||||
|
<p class="pl-4" id="settings-chromecast-support">{{ $strings.LabelSettingsChromecastSupport }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center py-2 mb-2">
|
||||||
|
<ui-toggle-switch labeledBy="settings-allow-iframe" v-model="newServerSettings.allowIframe" :disabled="updatingServerSettings" @input="(val) => updateSettingsKey('allowIframe', val)" />
|
||||||
|
<p class="pl-4" id="settings-allow-iframe">{{ $strings.LabelSettingsAllowIframe }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
@ -324,21 +333,21 @@ export default {
|
|||||||
},
|
},
|
||||||
updateServerSettings(payload) {
|
updateServerSettings(payload) {
|
||||||
this.updatingServerSettings = true
|
this.updatingServerSettings = true
|
||||||
this.$store
|
this.$store.dispatch('updateServerSettings', payload).then((response) => {
|
||||||
.dispatch('updateServerSettings', payload)
|
this.updatingServerSettings = false
|
||||||
.then(() => {
|
|
||||||
this.updatingServerSettings = false
|
|
||||||
|
|
||||||
if (payload.language) {
|
if (response.error) {
|
||||||
// Updating language after save allows for re-rendering
|
console.error('Failed to update server settins', response.error)
|
||||||
this.$setLanguageCode(payload.language)
|
this.$toast.error(response.error)
|
||||||
}
|
this.initServerSettings()
|
||||||
})
|
return
|
||||||
.catch((error) => {
|
}
|
||||||
console.error('Failed to update server settings', error)
|
|
||||||
this.updatingServerSettings = false
|
if (payload.language) {
|
||||||
this.$toast.error(this.$strings.ToastFailedToUpdate)
|
// Updating language after save allows for re-rendering
|
||||||
})
|
this.$setLanguageCode(payload.language)
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
initServerSettings() {
|
initServerSettings() {
|
||||||
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
||||||
|
@ -72,16 +72,17 @@ export const actions = {
|
|||||||
return this.$axios
|
return this.$axios
|
||||||
.$patch('/api/settings', updatePayload)
|
.$patch('/api/settings', updatePayload)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result.success) {
|
if (result.serverSettings) {
|
||||||
commit('setServerSettings', result.serverSettings)
|
commit('setServerSettings', result.serverSettings)
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to update server settings', error)
|
console.error('Failed to update server settings', error)
|
||||||
return false
|
const errorMsg = error.response?.data || 'Unknown error'
|
||||||
|
return {
|
||||||
|
error: errorMsg
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
checkForUpdate({ commit }) {
|
checkForUpdate({ commit }) {
|
||||||
|
@ -190,6 +190,7 @@
|
|||||||
"HeaderSettingsExperimental": "Experimental Features",
|
"HeaderSettingsExperimental": "Experimental Features",
|
||||||
"HeaderSettingsGeneral": "General",
|
"HeaderSettingsGeneral": "General",
|
||||||
"HeaderSettingsScanner": "Scanner",
|
"HeaderSettingsScanner": "Scanner",
|
||||||
|
"HeaderSettingsWebClient": "Web Client",
|
||||||
"HeaderSleepTimer": "Sleep Timer",
|
"HeaderSleepTimer": "Sleep Timer",
|
||||||
"HeaderStatsLargestItems": "Largest Items",
|
"HeaderStatsLargestItems": "Largest Items",
|
||||||
"HeaderStatsLongestItems": "Longest Items (hrs)",
|
"HeaderStatsLongestItems": "Longest Items (hrs)",
|
||||||
@ -542,6 +543,7 @@
|
|||||||
"LabelServerYearReview": "Server Year in Review ({0})",
|
"LabelServerYearReview": "Server Year in Review ({0})",
|
||||||
"LabelSetEbookAsPrimary": "Set as primary",
|
"LabelSetEbookAsPrimary": "Set as primary",
|
||||||
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
"LabelSetEbookAsSupplementary": "Set as supplementary",
|
||||||
|
"LabelSettingsAllowIframe": "Allow embedding in an iframe",
|
||||||
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
"LabelSettingsAudiobooksOnly": "Audiobooks only",
|
||||||
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
"LabelSettingsAudiobooksOnlyHelp": "Enabling this setting will ignore ebook files unless they are inside an audiobook folder in which case they will be set as supplementary ebooks",
|
||||||
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
||||||
|
@ -53,7 +53,6 @@ class Server {
|
|||||||
global.RouterBasePath = ROUTER_BASE_PATH
|
global.RouterBasePath = ROUTER_BASE_PATH
|
||||||
global.XAccel = process.env.USE_X_ACCEL
|
global.XAccel = process.env.USE_X_ACCEL
|
||||||
global.AllowCors = process.env.ALLOW_CORS === '1'
|
global.AllowCors = process.env.ALLOW_CORS === '1'
|
||||||
global.AllowIframe = process.env.ALLOW_IFRAME === '1'
|
|
||||||
global.DisableSsrfRequestFilter = process.env.DISABLE_SSRF_REQUEST_FILTER === '1'
|
global.DisableSsrfRequestFilter = process.env.DISABLE_SSRF_REQUEST_FILTER === '1'
|
||||||
|
|
||||||
if (!fs.pathExistsSync(global.ConfigPath)) {
|
if (!fs.pathExistsSync(global.ConfigPath)) {
|
||||||
@ -195,7 +194,7 @@ class Server {
|
|||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
if (!global.AllowIframe) {
|
if (!global.ServerSettings.allowIframe) {
|
||||||
// Prevent clickjacking by disallowing iframes
|
// Prevent clickjacking by disallowing iframes
|
||||||
res.setHeader('Content-Security-Policy', "frame-ancestors 'self'")
|
res.setHeader('Content-Security-Policy', "frame-ancestors 'self'")
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,10 @@ class MiscController {
|
|||||||
if (!isObject(settingsUpdate)) {
|
if (!isObject(settingsUpdate)) {
|
||||||
return res.status(400).send('Invalid settings update object')
|
return res.status(400).send('Invalid settings update object')
|
||||||
}
|
}
|
||||||
|
if (settingsUpdate.allowIframe == false && process.env.ALLOW_IFRAME === '1') {
|
||||||
|
Logger.warn('Cannot disable iframe when ALLOW_IFRAME is enabled in environment')
|
||||||
|
return res.status(400).send('Cannot disable iframe when ALLOW_IFRAME is enabled in environment')
|
||||||
|
}
|
||||||
|
|
||||||
const madeUpdates = Database.serverSettings.update(settingsUpdate)
|
const madeUpdates = Database.serverSettings.update(settingsUpdate)
|
||||||
if (madeUpdates) {
|
if (madeUpdates) {
|
||||||
@ -137,7 +141,6 @@ class MiscController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.json({
|
return res.json({
|
||||||
success: true,
|
|
||||||
serverSettings: Database.serverSettings.toJSONForBrowser()
|
serverSettings: Database.serverSettings.toJSONForBrowser()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ class ServerSettings {
|
|||||||
// Security/Rate limits
|
// Security/Rate limits
|
||||||
this.rateLimitLoginRequests = 10
|
this.rateLimitLoginRequests = 10
|
||||||
this.rateLimitLoginWindow = 10 * 60 * 1000 // 10 Minutes
|
this.rateLimitLoginWindow = 10 * 60 * 1000 // 10 Minutes
|
||||||
|
this.allowIframe = false
|
||||||
|
|
||||||
// Backups
|
// Backups
|
||||||
this.backupPath = Path.join(global.MetadataPath, 'backups')
|
this.backupPath = Path.join(global.MetadataPath, 'backups')
|
||||||
@ -99,6 +100,7 @@ class ServerSettings {
|
|||||||
|
|
||||||
this.rateLimitLoginRequests = !isNaN(settings.rateLimitLoginRequests) ? Number(settings.rateLimitLoginRequests) : 10
|
this.rateLimitLoginRequests = !isNaN(settings.rateLimitLoginRequests) ? Number(settings.rateLimitLoginRequests) : 10
|
||||||
this.rateLimitLoginWindow = !isNaN(settings.rateLimitLoginWindow) ? Number(settings.rateLimitLoginWindow) : 10 * 60 * 1000 // 10 Minutes
|
this.rateLimitLoginWindow = !isNaN(settings.rateLimitLoginWindow) ? Number(settings.rateLimitLoginWindow) : 10 * 60 * 1000 // 10 Minutes
|
||||||
|
this.allowIframe = !!settings.allowIframe
|
||||||
|
|
||||||
this.backupPath = settings.backupPath || Path.join(global.MetadataPath, 'backups')
|
this.backupPath = settings.backupPath || Path.join(global.MetadataPath, 'backups')
|
||||||
this.backupSchedule = settings.backupSchedule || false
|
this.backupSchedule = settings.backupSchedule || false
|
||||||
@ -190,6 +192,11 @@ class ServerSettings {
|
|||||||
Logger.info(`[ServerSettings] Using backup path from environment variable ${process.env.BACKUP_PATH}`)
|
Logger.info(`[ServerSettings] Using backup path from environment variable ${process.env.BACKUP_PATH}`)
|
||||||
this.backupPath = process.env.BACKUP_PATH
|
this.backupPath = process.env.BACKUP_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.ALLOW_IFRAME === '1' && !this.allowIframe) {
|
||||||
|
Logger.info(`[ServerSettings] Using allowIframe from environment variable`)
|
||||||
|
this.allowIframe = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
@ -207,6 +214,7 @@ class ServerSettings {
|
|||||||
metadataFileFormat: this.metadataFileFormat,
|
metadataFileFormat: this.metadataFileFormat,
|
||||||
rateLimitLoginRequests: this.rateLimitLoginRequests,
|
rateLimitLoginRequests: this.rateLimitLoginRequests,
|
||||||
rateLimitLoginWindow: this.rateLimitLoginWindow,
|
rateLimitLoginWindow: this.rateLimitLoginWindow,
|
||||||
|
allowIframe: this.allowIframe,
|
||||||
backupPath: this.backupPath,
|
backupPath: this.backupPath,
|
||||||
backupSchedule: this.backupSchedule,
|
backupSchedule: this.backupSchedule,
|
||||||
backupsToKeep: this.backupsToKeep,
|
backupsToKeep: this.backupsToKeep,
|
||||||
|
Loading…
Reference in New Issue
Block a user