diff --git a/client/package.json b/client/package.json index e01db4c..5f9d2d9 100644 --- a/client/package.json +++ b/client/package.json @@ -8,6 +8,7 @@ "start": "parcel", "build": "parcel build" }, + "publicUrl": "/app", "browserslist": "> 0.5%, last 2 versions, not dead", "dependencies": { "jwt-decode": "^4.0.0", diff --git a/client/src/App.tsx b/client/src/App.tsx index 6655bfc..7fee07b 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -39,95 +39,98 @@ import { Chat } from "./Chat"; import { ChatEdit } from "./ChatEdit"; import { Haters } from "./Haters"; -const router = createBrowserRouter([ - { - path: "/", - loader: async () => { - if (getToken() == null) { - return redirect("/login"); - } else { - return redirect("/home"); - } +const router = createBrowserRouter( + [ + { + path: "/", + loader: async () => { + if (getToken() == null) { + return redirect("/login"); + } else { + return redirect("/home"); + } + }, }, - }, - { - path: "/home", - loader: homeLoader, - action: homeAction, - element: , - children: [ - { path: "feed", element: , loader: feedLoader }, - // { path: "messages", element: }, - { - path: "messages/chats", - element: , - loader: chatListLoader, - }, - { - path: "messages/chats/new", - element: , - loader: newChatLoader, - action: newChatAction, - }, - { - path: "messages/chat/:id", - element: , - loader: chatLoader, - action: chatAction, - }, - { - path: "messages/chat/:id/edit", - element: , - loader: editChatLoader, - action: editChatAction, - }, - { - path: "users", - element: , - loader: userListLoader, - action: userListAction, - }, - { - path: "profile", - loader: profileLoader, - action: profileSelfAction, - element: , - }, - { - path: "profile/:username", - loader: profileLoader, - // action: profileSelfAction, - element: , - }, - { - path: "haters", - element: , - }, - ], - }, - { - path: "/login", - element: , - loader: async () => { - if (getToken()) { - return redirect("/"); - } - return null; + { + path: "/home", + loader: homeLoader, + action: homeAction, + element: , + children: [ + { path: "feed", element: , loader: feedLoader }, + // { path: "messages", element: }, + { + path: "messages/chats", + element: , + loader: chatListLoader, + }, + { + path: "messages/chats/new", + element: , + loader: newChatLoader, + action: newChatAction, + }, + { + path: "messages/chat/:id", + element: , + loader: chatLoader, + action: chatAction, + }, + { + path: "messages/chat/:id/edit", + element: , + loader: editChatLoader, + action: editChatAction, + }, + { + path: "users", + element: , + loader: userListLoader, + action: userListAction, + }, + { + path: "profile", + loader: profileLoader, + action: profileSelfAction, + element: , + }, + { + path: "profile/:username", + loader: profileLoader, + // action: profileSelfAction, + element: , + }, + { + path: "haters", + element: , + }, + ], }, - action: loginAction, - }, - { - path: "/signup", - element: , - loader: async () => { - if (getToken()) { - return redirect("/"); - } - return null; + { + path: "/login", + element: , + loader: async () => { + if (getToken()) { + return redirect("/"); + } + return null; + }, + action: loginAction, }, - action: signupAction, - }, -]); + { + path: "/signup", + element: , + loader: async () => { + if (getToken()) { + return redirect("/"); + } + return null; + }, + action: signupAction, + }, + ], + { basename: "/app" }, +); export function App() { return ( diff --git a/client/src/api/utils.ts b/client/src/api/utils.ts index 6fa2adb..4244db9 100644 --- a/client/src/api/utils.ts +++ b/client/src/api/utils.ts @@ -3,7 +3,14 @@ import { jwtDecode } from "jwt-decode"; import { isError } from "./dto"; -const apiRoot: string = "http://localhost:8080"; +declare const process: { + env: { + NODE_ENV: string; + }; +}; + +const apiRoot: string = + process.env.NODE_ENV == "production" ? "/" : "http://localhost:8080"; let token: string | null; diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/WebConfig.java b/server/src/main/java/com/usatiuk/tjv/y/server/WebConfig.java new file mode 100644 index 0000000..3cfc3f2 --- /dev/null +++ b/server/src/main/java/com/usatiuk/tjv/y/server/WebConfig.java @@ -0,0 +1,50 @@ +package com.usatiuk.tjv.y.server; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.http.CacheControl; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.ResourceResolver; +import org.springframework.web.servlet.resource.ResourceResolverChain; + +import java.time.Duration; +import java.util.List; + +@Configuration +@EnableWebMvc +public class WebConfig implements WebMvcConfigurer { + static class AppResourceResolver implements ResourceResolver { + @Override + public Resource resolveResource(HttpServletRequest request, String requestPath, List locations, ResourceResolverChain chain) { + ClassPathResource res = new ClassPathResource("/app/" + requestPath); + if (res.exists()) return res; + ClassPathResource indexRes = new ClassPathResource("/app/index.html"); + if (indexRes.exists()) return indexRes; + return null; + } + + @Override + public String resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + return null; + } + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addRedirectViewController("/app/", "/app/index.html"); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/app/**") + .setCacheControl(CacheControl.maxAge(Duration.ofDays(365))) + .resourceChain(true) + .addResolver(new AppResourceResolver()); + + } +} \ No newline at end of file diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java b/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java index 89c90d9..1ca6184 100644 --- a/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java +++ b/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java @@ -59,6 +59,7 @@ public class WebSecurityConfig { .authorizeHttpRequests((authorize) -> authorize .requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll() .requestMatchers(mvc.pattern(HttpMethod.POST, "/token")).permitAll() + .requestMatchers(mvc.pattern("/app/**")).permitAll() .requestMatchers(mvc.pattern("/swagger-ui*/**")).permitAll() .requestMatchers(mvc.pattern("/v3/**")).permitAll() .requestMatchers(mvc.pattern("/error")).permitAll()