mirror of
https://github.com/gotson/komga.git
synced 2025-12-16 13:33:49 +01:00
fix: webui works with baseUrl
This commit is contained in:
parent
6974f28706
commit
bb183828a1
16 changed files with 156 additions and 37 deletions
22
komga-webui/package-lock.json
generated
22
komga-webui/package-lock.json
generated
|
|
@ -9272,6 +9272,16 @@
|
|||
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
|
||||
"dev": true
|
||||
},
|
||||
"html-webpack-inject-attributes-plugin": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-inject-attributes-plugin/-/html-webpack-inject-attributes-plugin-1.0.2.tgz",
|
||||
"integrity": "sha512-q+SueBjlEkkT9wg8F1uyQjprZRhT5JrEC7paT5oYsCUOOUxwIrk2Wa7VSTKK9DSUila+diHlevSR24s7whYjMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.assign": "^4.2.0",
|
||||
"lodash.foreach": "^4.5.0"
|
||||
}
|
||||
},
|
||||
"html-webpack-plugin": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
|
||||
|
|
@ -11058,12 +11068,24 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
|
||||
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.defaultsdeep": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
|
||||
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.foreach": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
|
||||
"integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.kebabcase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"babel-eslint": "^10.0.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"html-webpack-inject-attributes-plugin": "^1.0.2",
|
||||
"sass": "^1.24.4",
|
||||
"sass-loader": "^8.0.2",
|
||||
"ts-jest": "^23.0.0",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,13 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Komga</title>
|
||||
<link rel="icon" href="/favicon.ico" th:href="@{/favicon.ico}">
|
||||
<script th:inline="javascript">
|
||||
/*<![CDATA[*/
|
||||
window.resourceBaseUrl = /*[(<%="$"%>{"'" + baseUrl + "'"})]*/ '/'
|
||||
/*]]>*/
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,27 @@
|
|||
const baseURL = process.env.VUE_APP_KOMGA_API_URL ? process.env.VUE_APP_KOMGA_API_URL : window.location.origin
|
||||
const fullUrl = process.env.VUE_APP_KOMGA_API_URL
|
||||
? process.env.VUE_APP_KOMGA_API_URL
|
||||
: window.location.origin + window.resourceBaseUrl
|
||||
const baseUrl = process.env.NODE_ENV === 'production' ? window.resourceBaseUrl : '/'
|
||||
|
||||
const urls = {
|
||||
origin: !fullUrl.endsWith('/') ? `${fullUrl}/` : fullUrl,
|
||||
originNoSlash: fullUrl.endsWith('/') ? fullUrl.slice(0, -1) : fullUrl,
|
||||
base: !baseUrl.endsWith('/') ? `${baseUrl}/` : baseUrl,
|
||||
baseNoSlash: baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl
|
||||
} as Urls
|
||||
|
||||
export default urls
|
||||
|
||||
export function bookThumbnailUrl (bookId: number): string {
|
||||
return `${baseURL}/api/v1/books/${bookId}/thumbnail`
|
||||
return `${urls.originNoSlash}/api/v1/books/${bookId}/thumbnail`
|
||||
}
|
||||
|
||||
export function bookFileUrl (bookId: number): string {
|
||||
return `${baseURL}/api/v1/books/${bookId}/file`
|
||||
return `${urls.originNoSlash}/api/v1/books/${bookId}/file`
|
||||
}
|
||||
|
||||
export function bookPageUrl (bookId: number, page: number, convertTo?: string): string {
|
||||
let url = `${baseURL}/api/v1/books/${bookId}/pages/${page}`
|
||||
let url = `${urls.originNoSlash}/api/v1/books/${bookId}/pages/${page}`
|
||||
if (convertTo) {
|
||||
url += `?convert=${convertTo}`
|
||||
}
|
||||
|
|
@ -17,9 +29,9 @@ export function bookPageUrl (bookId: number, page: number, convertTo?: string):
|
|||
}
|
||||
|
||||
export function bookPageThumbnailUrl (bookId: number, page: number): string {
|
||||
return `${baseURL}/api/v1/books/${bookId}/pages/${page}/thumbnail`
|
||||
return `${urls.originNoSlash}/api/v1/books/${bookId}/pages/${page}/thumbnail`
|
||||
}
|
||||
|
||||
export function seriesThumbnailUrl (seriesId: number): string {
|
||||
return `${baseURL}/api/v1/series/${seriesId}/thumbnail`
|
||||
return `${urls.originNoSlash}/api/v1/series/${seriesId}/thumbnail`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import './public-path'
|
||||
import _, { LoDashStatic } from 'lodash'
|
||||
import Vue from 'vue'
|
||||
import VueCookies from 'vue-cookies'
|
||||
|
|
@ -47,3 +48,9 @@ declare module 'vue/types/vue' {
|
|||
$_: LoDashStatic;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
resourceBaseUrl: string
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import urls from '@/functions/urls'
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
|
||||
import _Vue from 'vue'
|
||||
|
||||
export default {
|
||||
install (Vue: typeof _Vue) {
|
||||
Vue.prototype.$http = axios.create({
|
||||
baseURL: process.env.VUE_APP_KOMGA_API_URL ? process.env.VUE_APP_KOMGA_API_URL : window.location.origin,
|
||||
baseURL: urls.origin,
|
||||
withCredentials: true,
|
||||
headers: { 'X-Requested-With': 'XMLHttpRequest' }
|
||||
} as AxiosRequestConfig)
|
||||
|
|
|
|||
2
komga-webui/src/public-path.js
Normal file
2
komga-webui/src/public-path.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// eslint-disable-next-line camelcase
|
||||
__webpack_public_path__ = process.env.NODE_ENV === 'production' ? window.location.origin + window.resourceBaseUrl : '/'
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import urls from '@/functions/urls'
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import store from './store'
|
||||
|
|
@ -13,7 +14,7 @@ const adminGuard = (to: any, from: any, next: any) => {
|
|||
|
||||
const router = new Router({
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
base: urls.base,
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
|
|
|
|||
6
komga-webui/src/types/urls.ts
Normal file
6
komga-webui/src/types/urls.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
interface Urls {
|
||||
origin: string,
|
||||
originNoSlash: string,
|
||||
base: string,
|
||||
baseNoSlash: string
|
||||
}
|
||||
33
komga-webui/vue.config.js
Normal file
33
komga-webui/vue.config.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
const htmlInject = require('html-webpack-inject-attributes-plugin')
|
||||
const _ = require('lodash')
|
||||
|
||||
// vue.config.js
|
||||
module.exports = {
|
||||
publicPath: '/',
|
||||
chainWebpack: (config) => {
|
||||
config.plugins.delete('prefetch') // conflicts with htmlInject
|
||||
config.plugins.delete('preload') // conflicts with htmlInject
|
||||
config.plugin('html')
|
||||
.tap(args => {
|
||||
args[0].attributes = {
|
||||
'th:href': function (tag) {
|
||||
if (_.has(tag, 'attributes.href')) {
|
||||
return `@{${tag.attributes.href}}`
|
||||
}
|
||||
return false
|
||||
},
|
||||
'th:src': function (tag) {
|
||||
if (_.has(tag, 'attributes.src')) {
|
||||
return `@{${tag.attributes.src}}`
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
return args
|
||||
})
|
||||
|
||||
config.plugin('html-inject')
|
||||
.after('html')
|
||||
.use(htmlInject)
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ dependencies {
|
|||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-cache")
|
||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||
|
||||
kapt("org.springframework.boot:spring-boot-configuration-processor")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
package org.gotson.komga.infrastructure.web
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.servlet.ModelAndView
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
|
||||
@Component
|
||||
class SPAErrorViewResolver : ErrorViewResolver {
|
||||
override fun resolveErrorView(request: HttpServletRequest, status: HttpStatus, model: MutableMap<String, Any>): ModelAndView? =
|
||||
when {
|
||||
request.requestURL.toString() == "/error" -> null
|
||||
status == HttpStatus.NOT_FOUND -> ModelAndView("/", HttpStatus.TEMPORARY_REDIRECT)
|
||||
else -> ModelAndView("/error", status)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,42 @@
|
|||
package org.gotson.komga.infrastructure.web
|
||||
|
||||
import org.springframework.boot.web.server.ErrorPage
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.http.CacheControl
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
|
||||
|
||||
@Configuration
|
||||
class StaticResourceConfiguration : WebMvcConfigurer {
|
||||
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
|
||||
registry//.setOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
.addResourceHandler(
|
||||
"/index.html",
|
||||
"/favicon.ico"
|
||||
)
|
||||
.addResourceLocations(
|
||||
"classpath:public/index.html",
|
||||
"classpath:public/favicon.ico"
|
||||
)
|
||||
.setCacheControl(CacheControl.noStore())
|
||||
.addResourceHandler(
|
||||
"/index.html",
|
||||
"/favicon.ico"
|
||||
)
|
||||
.addResourceLocations(
|
||||
"classpath:public/index.html",
|
||||
"classpath:public/favicon.ico"
|
||||
)
|
||||
.setCacheControl(CacheControl.noStore())
|
||||
}
|
||||
|
||||
override fun addViewControllers(registry: ViewControllerRegistry) {
|
||||
registry.addViewController("/notFound")
|
||||
.setStatusCode(HttpStatus.OK)
|
||||
.setViewName("forward:/")
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
class CustomContainer : WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
|
||||
override fun customize(factory: ConfigurableServletWebServerFactory) {
|
||||
factory.addErrorPages(ErrorPage(HttpStatus.NOT_FOUND, "/notFound"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package org.gotson.komga.interfaces.mvc
|
||||
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.ui.Model
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import javax.servlet.ServletContext
|
||||
|
||||
@Controller
|
||||
class IndexController(
|
||||
servletContext: ServletContext
|
||||
) {
|
||||
private val baseUrl: String =
|
||||
if (servletContext.contextPath.isBlank()) "/"
|
||||
else "${servletContext.contextPath}/"
|
||||
|
||||
@GetMapping("/")
|
||||
fun index(model: Model): String {
|
||||
model.addAttribute("baseUrl", baseUrl)
|
||||
return "index"
|
||||
}
|
||||
}
|
||||
|
|
@ -35,3 +35,7 @@ logging:
|
|||
management.metrics.export.influx:
|
||||
# enabled: true
|
||||
uri: http://localhost:8086
|
||||
|
||||
#server:
|
||||
# servlet:
|
||||
# context-path: /komga
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ spring:
|
|||
use_second_level_cache: true
|
||||
use_query_cache: true
|
||||
region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
|
||||
|
||||
thymeleaf:
|
||||
prefix: classpath:/public/
|
||||
server.servlet.session.timeout: 7d
|
||||
|
||||
management:
|
||||
|
|
|
|||
Loading…
Reference in a new issue