mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-13 02:45:02 +02:00
Update ereaders to handle refreshing, epubjs to use custom request method, separate accessToken in store
This commit is contained in:
parent
25fe4dee3a
commit
d3402e30c2
9 changed files with 67 additions and 46 deletions
|
@ -311,7 +311,7 @@ export default {
|
|||
|
||||
if (data.user.id === this.user.id && data.user.accessToken !== this.user.accessToken) {
|
||||
console.log('Current user access token was updated')
|
||||
this.$store.commit('user/setUserToken', data.user.accessToken)
|
||||
this.$store.commit('user/setAccessToken', data.user.accessToken)
|
||||
}
|
||||
|
||||
this.$toast.success(this.$strings.ToastAccountUpdateSuccess)
|
||||
|
|
|
@ -104,9 +104,6 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
libraryItemId() {
|
||||
return this.libraryItem?.id
|
||||
},
|
||||
|
@ -234,10 +231,7 @@ export default {
|
|||
async extract() {
|
||||
this.loading = true
|
||||
var buff = await this.$axios.$get(this.ebookUrl, {
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.userToken}`
|
||||
}
|
||||
responseType: 'blob'
|
||||
})
|
||||
const archive = await Archive.open(buff)
|
||||
const originalFilesObject = await archive.getFilesObject()
|
||||
|
|
|
@ -57,9 +57,6 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
/** @returns {string} */
|
||||
libraryItemId() {
|
||||
return this.libraryItem?.id
|
||||
|
|
|
@ -26,9 +26,6 @@ export default {
|
|||
return {}
|
||||
},
|
||||
computed: {
|
||||
userToken() {
|
||||
return this.$store.getters['user/getToken']
|
||||
},
|
||||
libraryItemId() {
|
||||
return this.libraryItem?.id
|
||||
},
|
||||
|
@ -96,11 +93,8 @@ export default {
|
|||
},
|
||||
async initMobi() {
|
||||
// Fetch mobi file as blob
|
||||
var buff = await this.$axios.$get(this.ebookUrl, {
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.userToken}`
|
||||
}
|
||||
const buff = await this.$axios.$get(this.ebookUrl, {
|
||||
responseType: 'blob'
|
||||
})
|
||||
var reader = new FileReader()
|
||||
reader.onload = async (event) => {
|
||||
|
|
|
@ -55,7 +55,8 @@ export default {
|
|||
loadedRatio: 0,
|
||||
page: 1,
|
||||
numPages: 0,
|
||||
pdfDocInitParams: null
|
||||
pdfDocInitParams: null,
|
||||
isRefreshing: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -152,7 +153,34 @@ export default {
|
|||
this.page++
|
||||
this.updateProgress()
|
||||
},
|
||||
error(err) {
|
||||
async refreshToken() {
|
||||
if (this.isRefreshing) return
|
||||
this.isRefreshing = true
|
||||
const newAccessToken = await this.$store.dispatch('user/refreshToken').catch((error) => {
|
||||
console.error('Failed to refresh token', error)
|
||||
return null
|
||||
})
|
||||
if (!newAccessToken) {
|
||||
// Redirect to login on failed refresh
|
||||
this.$router.push('/login')
|
||||
return
|
||||
}
|
||||
|
||||
// Force Vue to re-render the PDF component by creating a new object
|
||||
this.pdfDocInitParams = {
|
||||
url: this.ebookUrl,
|
||||
httpHeaders: {
|
||||
Authorization: `Bearer ${newAccessToken}`
|
||||
}
|
||||
}
|
||||
this.isRefreshing = false
|
||||
},
|
||||
async error(err) {
|
||||
if (err && err.status === 401) {
|
||||
console.log('Received 401 error, refreshing token')
|
||||
await this.refreshToken()
|
||||
return
|
||||
}
|
||||
console.error(err)
|
||||
},
|
||||
resize() {
|
||||
|
|
|
@ -189,7 +189,7 @@ export default {
|
|||
|
||||
this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId)
|
||||
this.$store.commit('user/setUser', user)
|
||||
this.$store.commit('user/setUserToken', user.accessToken)
|
||||
this.$store.commit('user/setAccessToken', user.accessToken)
|
||||
|
||||
this.$store.dispatch('user/loadUserSettings')
|
||||
},
|
||||
|
|
|
@ -45,7 +45,7 @@ export default function ({ $axios, store, $root, app }) {
|
|||
if (originalRequest.url === '/auth/refresh' || originalRequest.url === '/login') {
|
||||
// Refresh failed or login failed, redirect to login
|
||||
store.commit('user/setUser', null)
|
||||
store.commit('user/setUserToken', null)
|
||||
store.commit('user/setAccessToken', null)
|
||||
app.router.push('/login')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
@ -72,23 +72,13 @@ export default function ({ $axios, store, $root, app }) {
|
|||
|
||||
try {
|
||||
// Attempt to refresh the token
|
||||
const response = await $axios.$post('/auth/refresh')
|
||||
const newAccessToken = response.user.accessToken
|
||||
|
||||
// Updates store if successful, otherwise clears store and throw error
|
||||
const newAccessToken = await store.dispatch('user/refreshToken')
|
||||
if (!newAccessToken) {
|
||||
console.error('No new access token received')
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// Update the token in store and localStorage
|
||||
store.commit('user/setUser', response.user)
|
||||
store.commit('user/setUserToken', newAccessToken)
|
||||
|
||||
// Emit event used to re-authenticate socket in default.vue since $root is not available here
|
||||
if (app.$eventBus) {
|
||||
app.$eventBus.$emit('token_refreshed', newAccessToken)
|
||||
}
|
||||
|
||||
// Update the original request with new token
|
||||
if (!originalRequest.headers) {
|
||||
originalRequest.headers = {}
|
||||
|
@ -106,9 +96,7 @@ export default function ({ $axios, store, $root, app }) {
|
|||
// Process queued requests with error
|
||||
processQueue(refreshError, null)
|
||||
|
||||
// Clear user data and redirect to login
|
||||
store.commit('user/setUser', null)
|
||||
store.commit('user/setUserToken', null)
|
||||
// Redirect to login
|
||||
app.router.push('/login')
|
||||
|
||||
return Promise.reject(refreshError)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export const state = () => ({
|
||||
user: null,
|
||||
accessToken: null,
|
||||
settings: {
|
||||
orderBy: 'media.metadata.title',
|
||||
orderDesc: false,
|
||||
|
@ -25,7 +26,7 @@ export const getters = {
|
|||
getIsRoot: (state) => state.user && state.user.type === 'root',
|
||||
getIsAdminOrUp: (state) => state.user && (state.user.type === 'admin' || state.user.type === 'root'),
|
||||
getToken: (state) => {
|
||||
return state.user?.accessToken || null
|
||||
return state.accessToken || null
|
||||
},
|
||||
getUserMediaProgress:
|
||||
(state) =>
|
||||
|
@ -145,6 +146,27 @@ export const actions = {
|
|||
} catch (error) {
|
||||
console.error('Failed to load userSettings from local storage', error)
|
||||
}
|
||||
},
|
||||
refreshToken({ state, commit }) {
|
||||
return this.$axios
|
||||
.$post('/auth/refresh')
|
||||
.then(async (response) => {
|
||||
const newAccessToken = response.user.accessToken
|
||||
commit('setUser', response.user)
|
||||
commit('setAccessToken', newAccessToken)
|
||||
// Emit event used to re-authenticate socket in default.vue since $root is not available here
|
||||
if (this.$eventBus) {
|
||||
this.$eventBus.$emit('token_refreshed', newAccessToken)
|
||||
}
|
||||
return newAccessToken
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to refresh token', error)
|
||||
commit('setUser', null)
|
||||
commit('setAccessToken', null)
|
||||
// Calling function handles redirect to login
|
||||
throw error
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,14 +174,12 @@ export const mutations = {
|
|||
setUser(state, user) {
|
||||
state.user = user
|
||||
},
|
||||
setUserToken(state, token) {
|
||||
setAccessToken(state, token) {
|
||||
if (!token) {
|
||||
localStorage.removeItem('token')
|
||||
if (state.user) {
|
||||
state.user.accessToken = null
|
||||
}
|
||||
} else if (state.user) {
|
||||
state.user.accessToken = token
|
||||
state.accessToken = null
|
||||
} else {
|
||||
state.accessToken = token
|
||||
localStorage.setItem('token', token)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -23,7 +23,7 @@ class RateLimiterFactory {
|
|||
windowMs = parseInt(process.env.RATE_LIMIT_AUTH_WINDOW)
|
||||
}
|
||||
|
||||
let max = 20 // 20 attempts default
|
||||
let max = 40 // 40 attempts default
|
||||
if (parseInt(process.env.RATE_LIMIT_AUTH_MAX) > 0) {
|
||||
max = parseInt(process.env.RATE_LIMIT_AUTH_MAX)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue