diff --git a/client/components/app/ConfigSideNav.vue b/client/components/app/ConfigSideNav.vue index f84906c16..cb676f714 100644 --- a/client/components/app/ConfigSideNav.vue +++ b/client/components/app/ConfigSideNav.vue @@ -76,6 +76,11 @@ export default { id: 'config-stats', title: 'Your Stats', path: '/config/stats' + }, + { + id: 'config-sso', + title: 'SSO', + path: '/config/sso' } ] }, diff --git a/client/pages/config/sso.vue b/client/pages/config/sso.vue new file mode 100644 index 000000000..a3562e66b --- /dev/null +++ b/client/pages/config/sso.vue @@ -0,0 +1,129 @@ + + + \ No newline at end of file diff --git a/client/store/index.js b/client/store/index.js index 443aabad0..fd720de01 100644 --- a/client/store/index.js +++ b/client/store/index.js @@ -32,6 +32,10 @@ export const getters = { if (!state.serverSettings) return null return state.serverSettings[key] }, + getSSOSetting: state => key => { + if (!state.SSOSettings) return null + return state.getSSOSettings[key] + }, getBookCoverAspectRatio: state => { if (!state.serverSettings || !state.serverSettings.coverAspectRatio) return 1.6 return state.serverSettings.coverAspectRatio === 0 ? 1.6 : 1 @@ -59,6 +63,22 @@ export const actions = { return false }) }, + updateSSOSettings({ commit }, payload) { + var updatePayload = { + ...payload + } + return this.$axios.$patch('/api/SSOSettings', updatePayload).then((result) => { + if (result.success) { + commit('setSSOSettings', result.SSOSettings) + return true + } else { + return false + } + }).catch((error) => { + console.error('Failed to update server settings', error) + return false + }) + }, checkForUpdate({ commit }) { return checkForUpdate() .then((res) => { @@ -104,7 +124,11 @@ export const mutations = { }, setServerSettings(state, settings) { if (!settings) return - state.serverSettings = settings + state.SSOSettings = settings + }, + setSSOSettings(state, settings) { + if (!settings) return + state.SSOSettings = settings }, setStreamAudiobook(state, audiobook) { state.playOnLoad = true diff --git a/client/store/sso.js b/client/store/sso.js new file mode 100644 index 000000000..c9ee4d230 --- /dev/null +++ b/client/store/sso.js @@ -0,0 +1,115 @@ + +import Vue from 'vue' + +const defaultSSOSettings = { + oidc: { + issuer: "", + authorizationURL: "", + tokenURL: "", + userInfoURL: "", + clientID: "", + clientSecret: "", + callbackURL: "/oidc/callback", + scope: "openid email profile" + }, + user: { + createNewUser: false, + isActive: true, + settings: { + mobileOrderBy: 'recent', + mobileOrderDesc: true, + mobileFilterBy: 'all', + orderBy: 'book.title', + orderDesc: false, + filterBy: 'all', + playbackRate: 1, + bookshelfCoverSize: 120, + collapseSeries: false + }, + permissions: { + download: false, + update: false, + delete: false, + upload: false, + accessAllLibraries: false + } + } +} + +export const state = () => defaultSSOSettings + +export const getters = { + getSSOIssuer: (state) => state.oidc.issuer, + getSSOAuthorizationURL: (state) => state.oidc.authorizationURL, + getSSOTokenURL: (state) => state.oidc.tokenURL, + getSSOUserInfoURL: (state) => state.oidc.userInfoURL, + getSSOClientID: (state) => state.oidc.clientID, + getSSOClientSecret: (state) => state.oidc.clientSecret, + getSSOCallbackURL: (state) => state.oidc.callbackURL, + getSSOScope: (state) => state.oidc.scope, + + getUserCreateNewUser: (state) => state.user.createNewUser, + getUserIsActive: (state) => state.user.isActive, + getUserPermissionDownload: (state) => state.user.permissions.download, + getUserPermissionUpdate: (state) => state.user.permissions.update, + getUserPermissionDelete: (state) => state.user.permissions.delete, + getUserPermissionUpload: (state) => state.user.permissions.upload, + getUserPermissionAccessAllLibraries: (state) => state.user.permissions.accessAllLibraries, +} + +export const actions = { + updateUserSettings({ commit }, payload) { + var updatePayload = { + ...payload + } + // Immediately update + commit('setSSOSettings', updatePayload) + return this.$axios.$patch('/api/sso/settings', updatePayload).then((result) => { + if (result.success) { + commit('setSSOSettings', result.settings) + return true + } else { + return false + } + }).catch((error) => { + console.error('Failed to update sso settings', error) + return false + }) + }, + loadSSOSettings({ state, commit }) { + return defaultSSOSettings + if (state.collectionsLoaded) { + console.log('Collections already loaded') + return state.collections + } + + return this.$axios.$get('/api/collections').then((collections) => { + commit('setCollections', collections) + return collections + }).catch((error) => { + console.error('Failed to get collections', error) + return [] + }) + } +} + +export const mutations = { + setSSOSettings(state, settings) { + if (!settings) return + + for (const key in settings) { + if (state.oidc[key] !== settings[key]) { + state.oidc[key] = settings[key] + } + } + }, + setUserPermissions(state, permissions) { + if (!permissions) return + + for (const key in permissions) { + if (state.user.permissions[key] !== permissions[key]) { + state.user.permissions[key] = permissions[key] + } + } + }, +} \ No newline at end of file