diff --git a/client/assets/fonts.css b/client/assets/fonts.css
index 46e007aa..f3c586e3 100644
--- a/client/assets/fonts.css
+++ b/client/assets/fonts.css
@@ -2,14 +2,14 @@
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
- src: url(/fonts/MaterialIcons.woff2) format('woff2');
+ src: url(~static/fonts/MaterialIcons.woff2) format('woff2');
}
@font-face {
font-family: 'Material Icons Outlined';
font-style: normal;
font-weight: 400;
- src: url(/fonts/MaterialIconsOutlined.woff2) format('woff2');
+ src: url(~static/fonts/MaterialIconsOutlined.woff2) format('woff2');
}
.material-icons {
@@ -54,7 +54,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/GentiumBookBasic.woff2) format('woff2');
+ src: url(~static/fonts/GentiumBookBasic.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@@ -64,7 +64,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/GentiumBookBasic.woff2) format('woff2');
+ src: url(~static/fonts/GentiumBookBasic.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -74,7 +74,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@@ -84,7 +84,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@@ -94,7 +94,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+1F00-1FFF;
}
@@ -104,7 +104,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0370-03FF;
}
@@ -114,7 +114,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
@@ -124,7 +124,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@@ -134,7 +134,7 @@
font-style: normal;
font-weight: 300;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -144,7 +144,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('ttf');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('ttf');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@@ -154,7 +154,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@@ -164,7 +164,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+1F00-1FFF;
}
@@ -174,7 +174,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+0370-03FF;
}
@@ -184,7 +184,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
@@ -194,7 +194,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@@ -204,7 +204,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -214,7 +214,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@@ -224,7 +224,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@@ -234,7 +234,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+1F00-1FFF;
}
@@ -244,7 +244,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0370-03FF;
}
@@ -254,7 +254,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
@@ -264,7 +264,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@@ -274,7 +274,7 @@
font-style: normal;
font-weight: 600;
font-display: swap;
- src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
+ src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@@ -284,7 +284,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@@ -294,7 +294,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@@ -304,7 +304,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+1F00-1FFF;
}
@@ -314,7 +314,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+0370-03FF;
}
@@ -324,7 +324,7 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@@ -334,6 +334,6 @@
font-style: normal;
font-weight: 400;
font-display: swap;
- src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
+ src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
\ No newline at end of file
diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue
index 842d559f..8f30c5d9 100644
--- a/client/components/app/Appbar.vue
+++ b/client/components/app/Appbar.vue
@@ -3,7 +3,7 @@
-
+
@@ -216,7 +216,7 @@ export default {
},
batchAutoMatchClick() {
this.$store.commit('globals/setShowBatchQuickMatchModal', true)
- },
+ }
},
mounted() {
this.$eventBus.$on('bookshelf-total-entities', this.setBookshelfTotalEntities)
diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue
index a368707d..c18c3117 100644
--- a/client/components/cards/LazyBookCard.vue
+++ b/client/components/cards/LazyBookCard.vue
@@ -182,7 +182,7 @@ export default {
return this.mediaType === 'podcast'
},
placeholderUrl() {
- return '/book_placeholder.jpg'
+ return `${this.$config.routerBasePath}/book_placeholder.jpg`
},
bookCoverSrc() {
return this.store.getters['globals/getLibraryItemCoverSrc'](this._libraryItem, this.placeholderUrl)
diff --git a/client/components/covers/AuthorImage.vue b/client/components/covers/AuthorImage.vue
index 58363e87..c3cafaea 100644
--- a/client/components/covers/AuthorImage.vue
+++ b/client/components/covers/AuthorImage.vue
@@ -58,7 +58,7 @@ export default {
if (!this.imagePath) return null
if (process.env.NODE_ENV !== 'production') {
// Testing
- return `http://localhost:3333/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
+ return `http://localhost:3333${this.$config.routerBasePath}/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
}
return `/api/authors/${this.authorId}/image?token=${this.userToken}&ts=${this.updatedAt}`
}
diff --git a/client/components/covers/BookCover.vue b/client/components/covers/BookCover.vue
index 838611ea..0d421955 100644
--- a/client/components/covers/BookCover.vue
+++ b/client/components/covers/BookCover.vue
@@ -94,7 +94,7 @@ export default {
return this.author
},
placeholderUrl() {
- return '/book_placeholder.jpg'
+ return `${this.$config.routerBasePath}/book_placeholder.jpg`
},
fullCoverUrl() {
if (!this.libraryItem) return null
diff --git a/client/components/covers/HoverBookCover.vue b/client/components/covers/HoverBookCover.vue
deleted file mode 100644
index 7171061e..00000000
--- a/client/components/covers/HoverBookCover.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/client/components/modals/player/QueueItemRow.vue b/client/components/modals/player/QueueItemRow.vue
index f9378dc7..fcb2c788 100644
--- a/client/components/modals/player/QueueItemRow.vue
+++ b/client/components/modals/player/QueueItemRow.vue
@@ -55,7 +55,7 @@ export default {
return this.item.coverPath
},
coverUrl() {
- if (!this.coverPath) return '/book_placeholder.jpg'
+ if (!this.coverPath) return `${this.$config.routerBasePath}/book_placeholder.jpg`
return this.$store.getters['globals/getLibraryItemCoverSrcById'](this.libraryItemId)
},
bookCoverAspectRatio() {
diff --git a/client/components/modals/rssfeed/ViewModal.vue b/client/components/modals/rssfeed/ViewModal.vue
index aa018e82..95234114 100644
--- a/client/components/modals/rssfeed/ViewModal.vue
+++ b/client/components/modals/rssfeed/ViewModal.vue
@@ -117,7 +117,7 @@ export default {
serverAddress: window.origin,
slug: this.newFeedSlug
}
- if (this.$isDev) payload.serverAddress = 'http://localhost:3333'
+ if (this.$isDev) payload.serverAddress = `http://localhost:3333${this.$config.routerBasePath}`
console.log('Payload', payload)
this.$axios
diff --git a/client/components/tables/LibraryFilesTable.vue b/client/components/tables/LibraryFilesTable.vue
index 00d0ed0b..05998f85 100644
--- a/client/components/tables/LibraryFilesTable.vue
+++ b/client/components/tables/LibraryFilesTable.vue
@@ -34,7 +34,7 @@
- download
+ download
|
diff --git a/client/components/tables/TracksTable.vue b/client/components/tables/TracksTable.vue
index 89f366fd..d0f93ff4 100644
--- a/client/components/tables/TracksTable.vue
+++ b/client/components/tables/TracksTable.vue
@@ -38,7 +38,7 @@
{{ $secondsToTimestamp(track.duration) }}
- download
+ download
|
diff --git a/client/nuxt.config.js b/client/nuxt.config.js
index c5f9436f..ede30503 100644
--- a/client/nuxt.config.js
+++ b/client/nuxt.config.js
@@ -6,13 +6,14 @@ module.exports = {
target: 'static',
dev: process.env.NODE_ENV !== 'production',
env: {
- serverUrl: process.env.NODE_ENV === 'production' ? '' : 'http://localhost:3333',
+ serverUrl: process.env.NODE_ENV === 'production' ? process.env.ROUTER_BASE_PATH : 'http://localhost:3333',
chromecastReceiver: 'FD1F76C5'
},
telemetry: false,
publicRuntimeConfig: {
- version: pkg.version
+ version: pkg.version,
+ routerBasePath: process.env.ROUTER_BASE_PATH || ''
},
// Global page headers: https://go.nuxtjs.dev/config-head
@@ -28,15 +29,17 @@ module.exports = {
],
script: [
{
- src: '/libs/sortable.js'
+ src: (process.env.ROUTER_BASE_PATH || '') + '/libs/sortable.js'
}
],
link: [
- { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
+ { rel: 'icon', type: 'image/x-icon', href: (process.env.ROUTER_BASE_PATH || '') + '/favicon.ico' }
]
},
- router: {},
+ router: {
+ base: process.env.ROUTER_BASE_PATH || ''
+ },
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
@@ -73,8 +76,7 @@ module.exports = {
proxy: {
'/dev/': { target: 'http://localhost:3333', pathRewrite: { '^/dev/': '' } },
'/ebook/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' : '/' },
- '/s/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' : '/' },
- '/metadata/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' : '/' }
+ '/s/': { target: process.env.NODE_ENV !== 'production' ? 'http://localhost:3333' + process.env : '/' },
},
io: {
@@ -89,7 +91,7 @@ module.exports = {
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
- baseURL: process.env.serverUrl || ''
+ baseURL: process.env.ROUTER_BASE_PATH || ''
},
// nuxt/pwa https://pwa.nuxtjs.org
@@ -109,15 +111,15 @@ module.exports = {
background_color: '#373838',
icons: [
{
- src: '/icon.svg',
+ src: (process.env.ROUTER_BASE_PATH || '') + '/icon.svg',
sizes: "64x64"
},
{
- src: '/icon.svg',
+ src: (process.env.ROUTER_BASE_PATH || '') + '/icon.svg',
sizes: "192x192"
},
{
- src: '/icon.svg',
+ src: (process.env.ROUTER_BASE_PATH || '') + '/icon.svg',
sizes: "512x512"
}
]
diff --git a/client/pages/audiobook/_id/chapters.vue b/client/pages/audiobook/_id/chapters.vue
index f97c83f9..f3067e2b 100644
--- a/client/pages/audiobook/_id/chapters.vue
+++ b/client/pages/audiobook/_id/chapters.vue
@@ -304,7 +304,7 @@ export default {
const audioEl = this.audioEl || document.createElement('audio')
var src = audioTrack.contentUrl + `?token=${this.userToken}`
if (this.$isDev) {
- src = `http://localhost:3333${src}`
+ src = `http://localhost:3333${this.$config.routerBasePath}${src}`
}
console.log('src', src)
diff --git a/client/plugins/axios.js b/client/plugins/axios.js
index 88468b2a..e839e382 100644
--- a/client/plugins/axios.js
+++ b/client/plugins/axios.js
@@ -1,4 +1,4 @@
-export default function ({ $axios, store }) {
+export default function ({ $axios, store, $config }) {
$axios.onRequest(config => {
if (!config.url) {
console.error('Axios request invalid config', config)
diff --git a/client/plugins/init.client.js b/client/plugins/init.client.js
index 75841d64..a208f387 100644
--- a/client/plugins/init.client.js
+++ b/client/plugins/init.client.js
@@ -143,8 +143,10 @@ export {
encode,
decode
}
-export default ({ app }, inject) => {
+export default ({ app, store }, inject) => {
app.$decode = decode
app.$encode = encode
inject('isDev', process.env.NODE_ENV !== 'production')
+
+ store.commit('setRouterBasePath', app.$config.routerBasePath)
}
\ No newline at end of file
diff --git a/client/store/globals.js b/client/store/globals.js
index 8b1c3d5e..96970629 100644
--- a/client/store/globals.js
+++ b/client/store/globals.js
@@ -32,7 +32,8 @@ export const state = () => ({
})
export const getters = {
- getLibraryItemCoverSrc: (state, getters, rootState, rootGetters) => (libraryItem, placeholder = '/book_placeholder.jpg') => {
+ getLibraryItemCoverSrc: (state, getters, rootState, rootGetters) => (libraryItem, placeholder = null) => {
+ if (!placeholder) placeholder = `${rootState.routerBasePath}/book_placeholder.jpg`
if (!libraryItem) return placeholder
var media = libraryItem.media
if (!media || !media.coverPath || media.coverPath === placeholder) return placeholder
@@ -45,18 +46,19 @@ export const getters = {
const libraryItemId = libraryItem.libraryItemId || libraryItem.id // Workaround for /users/:id page showing media progress covers
if (process.env.NODE_ENV !== 'production') { // Testing
- return `http://localhost:3333/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}`
+ return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}`
}
- return `/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}`
+ return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}&ts=${lastUpdate}`
},
- getLibraryItemCoverSrcById: (state, getters, rootState, rootGetters) => (libraryItemId, placeholder = '/book_placeholder.jpg') => {
+ getLibraryItemCoverSrcById: (state, getters, rootState, rootGetters) => (libraryItemId, placeholder = null) => {
+ if (!placeholder) placeholder = `${rootState.routerBasePath}/book_placeholder.jpg`
if (!libraryItemId) return placeholder
var userToken = rootGetters['user/getToken']
if (process.env.NODE_ENV !== 'production') { // Testing
- return `http://localhost:3333/api/items/${libraryItemId}/cover?token=${userToken}`
+ return `http://localhost:3333${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}`
}
- return `/api/items/${libraryItemId}/cover?token=${userToken}`
+ return `${rootState.routerBasePath}/api/items/${libraryItemId}/cover?token=${userToken}`
}
}
diff --git a/client/store/index.js b/client/store/index.js
index 96e3129a..f55d6077 100644
--- a/client/store/index.js
+++ b/client/store/index.js
@@ -25,7 +25,8 @@ export const state = () => ({
bookshelfBookIds: [],
openModal: null,
innerModalOpen: false,
- lastBookshelfScrollData: {}
+ lastBookshelfScrollData: {},
+ routerBasePath: '/'
})
export const getters = {
@@ -119,6 +120,9 @@ export const actions = {
}
export const mutations = {
+ setRouterBasePath(state, rbp) {
+ state.routerBasePath = rbp
+ },
setSource(state, source) {
state.Source = source
},
diff --git a/index.js b/index.js
index c15a9e0b..19a24d82 100644
--- a/index.js
+++ b/index.js
@@ -11,6 +11,7 @@ if (isDev) {
process.env.FFMPEG_PATH = devEnv.FFmpegPath
process.env.FFPROBE_PATH = devEnv.FFProbePath
process.env.SOURCE = 'local'
+ process.env.ROUTER_BASE_PATH = devEnv.RouterBasePath || ''
}
const PORT = process.env.PORT || 80
@@ -20,8 +21,9 @@ const METADATA_PATH = process.env.METADATA_PATH || '/metadata'
const UID = process.env.AUDIOBOOKSHELF_UID || 99
const GID = process.env.AUDIOBOOKSHELF_GID || 100
const SOURCE = process.env.SOURCE || 'docker'
+const ROUTER_BASE_PATH = process.env.ROUTER_BASE_PATH || ''
console.log('Config', CONFIG_PATH, METADATA_PATH)
-const Server = new server(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH)
+const Server = new server(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH)
Server.start()
diff --git a/prod.js b/prod.js
index de7a6417..57417033 100644
--- a/prod.js
+++ b/prod.js
@@ -26,8 +26,9 @@ const METADATA_PATH = inputMetadata || process.env.METADATA_PATH || Path.resolve
const UID = 99
const GID = 100
const SOURCE = options.source || 'debian'
+const ROUTER_BASE_PATH = process.env.ROUTER_BASE_PATH || ''
console.log(process.env.NODE_ENV, 'Config', CONFIG_PATH, METADATA_PATH)
-const Server = new server(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH)
+const Server = new server(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH)
Server.start()
diff --git a/server/Server.js b/server/Server.js
index 44038d55..71213960 100644
--- a/server/Server.js
+++ b/server/Server.js
@@ -36,7 +36,7 @@ const RssFeedManager = require('./managers/RssFeedManager')
const CronManager = require('./managers/CronManager')
class Server {
- constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH) {
+ constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH) {
this.Port = PORT
this.Host = HOST
global.Source = SOURCE
@@ -44,6 +44,7 @@ class Server {
global.Gid = isNaN(GID) ? 0 : Number(GID)
global.ConfigPath = Path.normalize(CONFIG_PATH)
global.MetadataPath = Path.normalize(METADATA_PATH)
+ global.RouterBasePath = ROUTER_BASE_PATH
// Fix backslash if not on Windows
if (process.platform !== 'win32') {
@@ -170,29 +171,32 @@ class Server {
await this.init()
const app = express()
+ const router = express.Router()
+ app.use(global.RouterBasePath, router)
+
this.server = http.createServer(app)
- app.use(this.auth.cors)
- app.use(fileUpload())
- app.use(express.urlencoded({ extended: true, limit: "5mb" }));
- app.use(express.json({ limit: "5mb" }))
+ router.use(this.auth.cors)
+ router.use(fileUpload())
+ router.use(express.urlencoded({ extended: true, limit: "5mb" }));
+ router.use(express.json({ limit: "5mb" }))
// Static path to generated nuxt
const distPath = Path.join(global.appRoot, '/client/dist')
- app.use(express.static(distPath))
+ router.use(express.static(distPath))
// Metadata folder static path
- app.use('/metadata', this.authMiddleware.bind(this), express.static(global.MetadataPath))
+ router.use('/metadata', this.authMiddleware.bind(this), express.static(global.MetadataPath))
// Static folder
- app.use(express.static(Path.join(global.appRoot, 'static')))
+ router.use(express.static(Path.join(global.appRoot, 'static')))
- app.use('/api', this.authMiddleware.bind(this), this.apiRouter.router)
- app.use('/hls', this.authMiddleware.bind(this), this.hlsRouter.router)
- app.use('/s', this.authMiddleware.bind(this), this.staticRouter.router)
+ router.use('/api', this.authMiddleware.bind(this), this.apiRouter.router)
+ router.use('/hls', this.authMiddleware.bind(this), this.hlsRouter.router)
+ router.use('/s', this.authMiddleware.bind(this), this.staticRouter.router)
// EBook static file routes
- app.get('/ebook/:library/:folder/*', (req, res) => {
+ router.get('/ebook/:library/:folder/*', (req, res) => {
var library = this.db.libraries.find(lib => lib.id === req.params.library)
if (!library) return res.sendStatus(404)
var folder = library.folders.find(fol => fol.id === req.params.folder)
@@ -204,14 +208,14 @@ class Server {
})
// RSS Feed temp route
- app.get('/feed/:id', (req, res) => {
+ router.get('/feed/:id', (req, res) => {
Logger.info(`[Server] Requesting rss feed ${req.params.id}`)
this.rssFeedManager.getFeed(req, res)
})
- app.get('/feed/:id/cover', (req, res) => {
+ router.get('/feed/:id/cover', (req, res) => {
this.rssFeedManager.getFeedCover(req, res)
})
- app.get('/feed/:id/item/:episodeId/*', (req, res) => {
+ router.get('/feed/:id/item/:episodeId/*', (req, res) => {
Logger.debug(`[Server] Requesting rss feed episode ${req.params.id}/${req.params.episodeId}`)
this.rssFeedManager.getFeedItem(req, res)
})
@@ -234,18 +238,18 @@ class Server {
'/config/users/:id/sessions',
'/collection/:id'
]
- dyanimicRoutes.forEach((route) => app.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
+ dyanimicRoutes.forEach((route) => router.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
- app.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res, this.rssFeedManager.feedsArray))
- app.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
- app.post('/init', (req, res) => {
+ router.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res, this.rssFeedManager.feedsArray))
+ router.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
+ router.post('/init', (req, res) => {
if (this.db.hasRootUser) {
Logger.error(`[Server] attempt to init server when server already has a root user`)
return res.sendStatus(500)
}
this.initializeServer(req, res)
})
- app.get('/status', (req, res) => {
+ router.get('/status', (req, res) => {
// status check for client to see if server has been initialized
// server has been initialized if a root user exists
const payload = {
@@ -257,7 +261,7 @@ class Server {
}
res.json(payload)
})
- app.get('/ping', (req, res) => {
+ router.get('/ping', (req, res) => {
Logger.info('Received ping')
res.json({ success: true })
})
diff --git a/server/objects/files/AudioTrack.js b/server/objects/files/AudioTrack.js
index 4fa6ff8d..dc7b75b6 100644
--- a/server/objects/files/AudioTrack.js
+++ b/server/objects/files/AudioTrack.js
@@ -29,7 +29,7 @@ class AudioTrack {
this.startOffset = startOffset
this.duration = audioFile.duration
this.title = audioFile.metadata.filename || ''
- this.contentUrl = Path.join(`/s/item/${itemId}`, encodeUriPath(audioFile.metadata.relPath))
+ this.contentUrl = Path.join(`${global.RouterBasePath}/s/item/${itemId}`, encodeUriPath(audioFile.metadata.relPath))
this.mimeType = audioFile.mimeType
this.metadata = audioFile.metadata.clone()
}
diff --git a/server/objects/files/VideoTrack.js b/server/objects/files/VideoTrack.js
index f9241ad7..7c4128f5 100644
--- a/server/objects/files/VideoTrack.js
+++ b/server/objects/files/VideoTrack.js
@@ -26,7 +26,7 @@ class VideoTrack {
this.index = videoFile.index
this.duration = videoFile.duration
this.title = videoFile.metadata.filename || ''
- this.contentUrl = Path.join(`/s/item/${itemId}`, encodeUriPath(videoFile.metadata.relPath))
+ this.contentUrl = Path.join(`${global.RouterBasePath}/s/item/${itemId}`, encodeUriPath(videoFile.metadata.relPath))
this.mimeType = videoFile.mimeType
this.metadata = videoFile.metadata.clone()
}