feat: proxy authenfication added

This commit is contained in:
alex-sviridov 2025-09-29 12:17:59 +02:00
parent 03da194953
commit 4875125ae9
6 changed files with 315 additions and 2 deletions

View file

@ -122,6 +122,32 @@
</div>
</transition>
</div>
<div class="w-full border border-white/10 rounded-xl p-4 my-4 bg-primary/25">
<div class="flex items-center">
<ui-checkbox v-model="enableProxyAuth" checkbox-bg="bg" />
<p class="text-lg pl-4">{{ $strings.HeaderProxyAuthentication }}</p>
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
<a href="https://www.audiobookshelf.org/guides/reverse_proxy_authentication" target="_blank" class="inline-flex">
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
</a>
</ui-tooltip>
</div>
<transition name="slide">
<div v-if="enableProxyAuth" class="flex flex-wrap pt-4">
<ui-text-input-with-label ref="proxyHeaderName" v-model="newAuthSettings.authProxyHeaderName" :disabled="savingSettings" :label="$strings.LabelProxyHeaderName" :placeholder="'X-Remote-User'" class="mb-2" />
<p class="text-sm text-gray-300 mb-4">
{{ $strings.LabelProxyHeaderNameDescription }}
</p>
<ui-text-input-with-label ref="proxyLogoutURL" v-model="newAuthSettings.authProxyLogoutURL" :disabled="savingSettings" :label="$strings.LabelProxyLogoutUrl" :placeholder="'https://proxy.example.com/logout'" class="mb-2" />
<p class="text-sm text-gray-300 mb-4">
{{ $strings.LabelProxyLogoutUrlDescription }}
</p>
</div>
</transition>
</div>
<div class="w-full flex items-center justify-between p-4">
<p v-if="enableOpenIDAuth" class="text-sm text-warning">{{ $strings.MessageAuthenticationOIDCChangesRestart }}</p>
<ui-btn color="bg-success" :padding-x="8" small class="text-base" :loading="savingSettings" @click="saveSettings">{{ $strings.ButtonSave }}</ui-btn>
@ -154,6 +180,7 @@ export default {
return {
enableLocalAuth: false,
enableOpenIDAuth: false,
enableProxyAuth: false,
showCustomLoginMessage: false,
savingSettings: false,
openIdSigningAlgorithmsSupportedByIssuer: [],
@ -323,7 +350,7 @@ export default {
return isValid
},
async saveSettings() {
if (!this.enableLocalAuth && !this.enableOpenIDAuth) {
if (!this.enableLocalAuth && !this.enableOpenIDAuth && !this.enableProxyAuth) {
this.$toast.error('Must have at least one authentication method enabled')
return
}
@ -332,6 +359,11 @@ export default {
return
}
if (this.enableProxyAuth && !this.newAuthSettings.authProxyHeaderName?.trim()) {
this.$toast.error('Authentication Header Name is required for proxy authentication')
return
}
if (!this.showCustomLoginMessage || !this.newAuthSettings.authLoginCustomMessage?.trim()) {
this.newAuthSettings.authLoginCustomMessage = null
}
@ -339,6 +371,7 @@ export default {
this.newAuthSettings.authActiveAuthMethods = []
if (this.enableLocalAuth) this.newAuthSettings.authActiveAuthMethods.push('local')
if (this.enableOpenIDAuth) this.newAuthSettings.authActiveAuthMethods.push('openid')
if (this.enableProxyAuth) this.newAuthSettings.authActiveAuthMethods.push('proxy')
this.savingSettings = true
this.$axios
@ -366,6 +399,7 @@ export default {
}
this.enableLocalAuth = this.authMethods.includes('local')
this.enableOpenIDAuth = this.authMethods.includes('openid')
this.enableProxyAuth = this.authMethods.includes('proxy')
this.showCustomLoginMessage = !!this.authSettings.authLoginCustomMessage
}
},

View file

@ -222,6 +222,32 @@ export default {
}
this.processing = false
},
async attemptProxyAuth() {
this.error = null
this.processing = true
try {
const authRes = await this.$axios.$post('/auth/proxy').catch((error) => {
console.error('Proxy auth failed', error.response)
if (error.response?.data?.message) {
this.error = error.response.data.message
}
return false
})
if (authRes?.error) {
this.error = authRes.error
} else if (authRes) {
this.setUser(authRes)
return
}
} catch (error) {
console.error('Proxy auth error', error)
this.error = 'Proxy authentication failed'
}
this.processing = false
},
checkAuth() {
const token = localStorage.getItem('token')
if (!token) return false
@ -307,6 +333,11 @@ export default {
} else {
this.login_openid = false
}
if (authMethods.includes('proxy')) {
// Auto-attempt proxy authentication
this.attemptProxyAuth()
}
}
},
async mounted() {

View file

@ -175,6 +175,7 @@
"HeaderOpenListeningSessions": "Open Listening Sessions",
"HeaderOpenRSSFeed": "Open RSS Feed",
"HeaderOtherFiles": "Other Files",
"HeaderProxyAuthentication": "Proxy Authentication",
"HeaderPasswordAuthentication": "Password Authentication",
"HeaderPermissions": "Permissions",
"HeaderPlayerQueue": "Player Queue",
@ -531,6 +532,10 @@
"LabelProgress": "Progress",
"LabelProvider": "Provider",
"LabelProviderAuthorizationValue": "Authorization Header Value",
"LabelProxyHeaderName": "Authentication Header Name",
"LabelProxyHeaderNameDescription": "The name of the header that your proxy uses to pass the authenticated username to Audiobookshelf.",
"LabelProxyLogoutUrl": "Custom Logout URL",
"LabelProxyLogoutUrlDescription": "The URL users will be redirected to when they click the logout button. This should log the user out of your authenfication proxy.",
"LabelPubDate": "Pub Date",
"LabelPublishYear": "Publish Year",
"LabelPublishedDate": "Published {0}",