Export redirection index.html files in case someone refreshes browser

This commit is contained in:
Aurora Lahtela 2022-12-05 17:10:51 +02:00
parent b659dda928
commit f7176b3d47
7 changed files with 136 additions and 6 deletions

View File

@ -26,6 +26,8 @@ import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver; import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException; import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.Database;
@ -50,6 +52,7 @@ import java.util.Optional;
public class NetworkPageExporter extends FileExporter { public class NetworkPageExporter extends FileExporter {
private final PlanFiles files; private final PlanFiles files;
private final PlanConfig config;
private final DBSystem dbSystem; private final DBSystem dbSystem;
private final PageFactory pageFactory; private final PageFactory pageFactory;
private final RootJSONResolver jsonHandler; private final RootJSONResolver jsonHandler;
@ -58,12 +61,14 @@ public class NetworkPageExporter extends FileExporter {
@Inject @Inject
public NetworkPageExporter( public NetworkPageExporter(
PlanFiles files, PlanFiles files,
PlanConfig config,
DBSystem dbSystem, DBSystem dbSystem,
PageFactory pageFactory, PageFactory pageFactory,
RootJSONResolver jsonHandler, RootJSONResolver jsonHandler,
Theme theme Theme theme
) { ) {
this.files = files; this.files = files;
this.config = config;
this.dbSystem = dbSystem; this.dbSystem = dbSystem;
this.pageFactory = pageFactory; this.pageFactory = pageFactory;
this.jsonHandler = jsonHandler; this.jsonHandler = jsonHandler;
@ -87,9 +92,12 @@ public class NetworkPageExporter extends FileExporter {
exportRequiredResources(exportPaths, toDirectory); exportRequiredResources(exportPaths, toDirectory);
exportJSON(exportPaths, toDirectory, server); exportJSON(exportPaths, toDirectory, server);
exportHtml(exportPaths, toDirectory); exportHtml(exportPaths, toDirectory);
exportReactRedirects(toDirectory);
} }
private void exportHtml(ExportPaths exportPaths, Path toDirectory) throws IOException { private void exportHtml(ExportPaths exportPaths, Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
Path to = toDirectory Path to = toDirectory
.resolve("network") .resolve("network")
.resolve("index.html"); .resolve("index.html");
@ -110,6 +118,25 @@ public class NetworkPageExporter extends FileExporter {
export(to, exportPaths.resolveExportPaths(html)); export(to, exportPaths.resolveExportPaths(html));
} }
private void exportReactRedirects(Path toDirectory) throws IOException {
if (config.isFalse(PluginSettings.FRONTEND_BETA)) return;
Resource redirect = files.getResourceFromJar("web/export-redirect.html");
exportReactRedirect(toDirectory, redirect, "network");
exportReactRedirect(toDirectory, redirect, "network/overview");
exportReactRedirect(toDirectory, redirect, "network/serversOverview");
exportReactRedirect(toDirectory, redirect, "network/sessions");
exportReactRedirect(toDirectory, redirect, "network/playerbase");
exportReactRedirect(toDirectory, redirect, "network/join-addresses");
exportReactRedirect(toDirectory, redirect, "network/players");
exportReactRedirect(toDirectory, redirect, "network/geolocations");
exportReactRedirect(toDirectory, redirect, "network/plugins-overview");
}
private void exportReactRedirect(Path toDirectory, Resource redirectHtml, String path) throws IOException {
export(toDirectory.resolve(path).resolve("index.html"), redirectHtml.asString());
}
/** /**
* Perform export for a network page json payload. * Perform export for a network page json payload.
* *
@ -179,6 +206,8 @@ public class NetworkPageExporter extends FileExporter {
} }
private void exportRequiredResources(ExportPaths exportPaths, Path toDirectory) throws IOException { private void exportRequiredResources(ExportPaths exportPaths, Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
exportResources(exportPaths, toDirectory, exportResources(exportPaths, toDirectory,
"./img/Flaticon_circle.png", "./img/Flaticon_circle.png",
"./css/sb-admin-2.css", "./css/sb-admin-2.css",

View File

@ -25,6 +25,8 @@ import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resource.WebResource; import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver; import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException; import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.Database;
@ -50,6 +52,7 @@ import java.util.UUID;
public class PlayerPageExporter extends FileExporter { public class PlayerPageExporter extends FileExporter {
private final PlanFiles files; private final PlanFiles files;
private final PlanConfig config;
private final DBSystem dbSystem; private final DBSystem dbSystem;
private final PageFactory pageFactory; private final PageFactory pageFactory;
private final RootJSONResolver jsonHandler; private final RootJSONResolver jsonHandler;
@ -58,12 +61,14 @@ public class PlayerPageExporter extends FileExporter {
@Inject @Inject
public PlayerPageExporter( public PlayerPageExporter(
PlanFiles files, PlanFiles files,
PlanConfig config,
DBSystem dbSystem, DBSystem dbSystem,
PageFactory pageFactory, PageFactory pageFactory,
RootJSONResolver jsonHandler, RootJSONResolver jsonHandler,
Theme theme Theme theme
) { ) {
this.files = files; this.files = files;
this.config = config;
this.dbSystem = dbSystem; this.dbSystem = dbSystem;
this.pageFactory = pageFactory; this.pageFactory = pageFactory;
this.jsonHandler = jsonHandler; this.jsonHandler = jsonHandler;
@ -94,10 +99,13 @@ public class PlayerPageExporter extends FileExporter {
Path playerDirectory = toDirectory.resolve("player/" + toFileName(playerUUID.toString())); Path playerDirectory = toDirectory.resolve("player/" + toFileName(playerUUID.toString()));
exportJSON(exportPaths, playerDirectory, playerUUID); exportJSON(exportPaths, playerDirectory, playerUUID);
exportHtml(exportPaths, playerDirectory, playerUUID); exportHtml(exportPaths, playerDirectory, playerUUID);
exportReactRedirects(toDirectory, playerUUID);
exportPaths.clear(); exportPaths.clear();
} }
private void exportHtml(ExportPaths exportPaths, Path playerDirectory, UUID playerUUID) throws IOException { private void exportHtml(ExportPaths exportPaths, Path playerDirectory, UUID playerUUID) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
Path to = playerDirectory.resolve("index.html"); Path to = playerDirectory.resolve("index.html");
try { try {
@ -108,6 +116,22 @@ public class PlayerPageExporter extends FileExporter {
} }
} }
private void exportReactRedirects(Path toDirectory, UUID playerUUID) throws IOException {
if (config.isFalse(PluginSettings.FRONTEND_BETA)) return;
Resource redirect = files.getResourceFromJar("web/export-redirect.html");
String player = "player/";
exportReactRedirect(toDirectory, redirect, player + playerUUID);
exportReactRedirect(toDirectory, redirect, player + playerUUID + "/overview");
exportReactRedirect(toDirectory, redirect, player + playerUUID + "/sessions");
exportReactRedirect(toDirectory, redirect, player + playerUUID + "/pvppve");
exportReactRedirect(toDirectory, redirect, player + playerUUID + "/servers");
}
private void exportReactRedirect(Path toDirectory, Resource redirectHtml, String path) throws IOException {
export(toDirectory.resolve(path).resolve("index.html"), redirectHtml.asString());
}
private void exportJSON(ExportPaths exportPaths, Path toDirectory, UUID playerUUID) throws IOException { private void exportJSON(ExportPaths exportPaths, Path toDirectory, UUID playerUUID) throws IOException {
exportJSON(exportPaths, toDirectory, "player?player=" + playerUUID); exportJSON(exportPaths, toDirectory, "player?player=" + playerUUID);
} }
@ -136,6 +160,8 @@ public class PlayerPageExporter extends FileExporter {
} }
private void exportRequiredResources(ExportPaths exportPaths, Path toDirectory) throws IOException { private void exportRequiredResources(ExportPaths exportPaths, Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
// Style // Style
exportResources(exportPaths, toDirectory, exportResources(exportPaths, toDirectory,
"../img/Flaticon_circle.png", "../img/Flaticon_circle.png",

View File

@ -26,6 +26,8 @@ import com.djrapitops.plan.delivery.web.resource.WebResource;
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver; import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
import com.djrapitops.plan.exceptions.connection.WebException; import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.Database;
@ -49,6 +51,7 @@ import java.util.Optional;
public class PlayersPageExporter extends FileExporter { public class PlayersPageExporter extends FileExporter {
private final PlanFiles files; private final PlanFiles files;
private final PlanConfig config;
private final DBSystem dbSystem; private final DBSystem dbSystem;
private final PageFactory pageFactory; private final PageFactory pageFactory;
private final RootJSONResolver jsonHandler; private final RootJSONResolver jsonHandler;
@ -60,13 +63,14 @@ public class PlayersPageExporter extends FileExporter {
@Inject @Inject
public PlayersPageExporter( public PlayersPageExporter(
PlanFiles files, PlanFiles files,
DBSystem dbSystem, PlanConfig config, DBSystem dbSystem,
PageFactory pageFactory, PageFactory pageFactory,
RootJSONResolver jsonHandler, RootJSONResolver jsonHandler,
Theme theme, Theme theme,
ServerInfo serverInfo ServerInfo serverInfo
) { ) {
this.files = files; this.files = files;
this.config = config;
this.dbSystem = dbSystem; this.dbSystem = dbSystem;
this.pageFactory = pageFactory; this.pageFactory = pageFactory;
this.jsonHandler = jsonHandler; this.jsonHandler = jsonHandler;
@ -84,10 +88,13 @@ public class PlayersPageExporter extends FileExporter {
exportRequiredResources(toDirectory); exportRequiredResources(toDirectory);
exportJSON(toDirectory); exportJSON(toDirectory);
exportHtml(toDirectory); exportHtml(toDirectory);
exportReactRedirects(toDirectory);
exportPaths.clear(); exportPaths.clear();
} }
private void exportHtml(Path toDirectory) throws IOException { private void exportHtml(Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
Path to = toDirectory Path to = toDirectory
.resolve("players") .resolve("players")
.resolve("index.html"); .resolve("index.html");
@ -108,6 +115,17 @@ public class PlayersPageExporter extends FileExporter {
export(to, exportPaths.resolveExportPaths(html)); export(to, exportPaths.resolveExportPaths(html));
} }
private void exportReactRedirects(Path toDirectory) throws IOException {
if (config.isFalse(PluginSettings.FRONTEND_BETA)) return;
Resource redirect = files.getResourceFromJar("web/export-redirect.html");
exportReactRedirect(toDirectory, redirect, "players");
}
private void exportReactRedirect(Path toDirectory, Resource redirectHtml, String path) throws IOException {
export(toDirectory.resolve(path).resolve("index.html"), redirectHtml.asString());
}
private void exportJSON(Path toDirectory) throws IOException { private void exportJSON(Path toDirectory) throws IOException {
Response response = getJSONResponse("players") Response response = getJSONResponse("players")
.orElseThrow(() -> new NotFoundException("players page was not properly exported: not found")); .orElseThrow(() -> new NotFoundException("players page was not properly exported: not found"));
@ -135,6 +153,8 @@ public class PlayersPageExporter extends FileExporter {
} }
private void exportRequiredResources(Path toDirectory) throws IOException { private void exportRequiredResources(Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
// Style // Style
exportResources(toDirectory, exportResources(toDirectory,
"img/Flaticon_circle.png", "img/Flaticon_circle.png",

View File

@ -28,6 +28,8 @@ import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.identification.ServerUUID; import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.theme.Theme; import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.Database;
@ -52,6 +54,7 @@ import java.util.Optional;
public class ServerPageExporter extends FileExporter { public class ServerPageExporter extends FileExporter {
private final PlanFiles files; private final PlanFiles files;
private final PlanConfig config;
private final PageFactory pageFactory; private final PageFactory pageFactory;
private final DBSystem dbSystem; private final DBSystem dbSystem;
private final RootJSONResolver jsonHandler; private final RootJSONResolver jsonHandler;
@ -63,6 +66,7 @@ public class ServerPageExporter extends FileExporter {
@Inject @Inject
public ServerPageExporter( public ServerPageExporter(
PlanFiles files, PlanFiles files,
PlanConfig config,
PageFactory pageFactory, PageFactory pageFactory,
DBSystem dbSystem, DBSystem dbSystem,
RootJSONResolver jsonHandler, RootJSONResolver jsonHandler,
@ -70,6 +74,7 @@ public class ServerPageExporter extends FileExporter {
ServerInfo serverInfo // To know if current server is a Proxy ServerInfo serverInfo // To know if current server is a Proxy
) { ) {
this.files = files; this.files = files;
this.config = config;
this.pageFactory = pageFactory; this.pageFactory = pageFactory;
this.dbSystem = dbSystem; this.dbSystem = dbSystem;
this.jsonHandler = jsonHandler; this.jsonHandler = jsonHandler;
@ -95,10 +100,13 @@ public class ServerPageExporter extends FileExporter {
exportRequiredResources(toDirectory); exportRequiredResources(toDirectory);
exportJSON(toDirectory, server); exportJSON(toDirectory, server);
exportHtml(toDirectory, server); exportHtml(toDirectory, server);
exportReactRedirects(toDirectory, server.getUuid());
exportPaths.clear(); exportPaths.clear();
} }
private void exportHtml(Path toDirectory, Server server) throws IOException { private void exportHtml(Path toDirectory, Server server) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
ServerUUID serverUUID = server.getUuid(); ServerUUID serverUUID = server.getUuid();
Path to = toDirectory Path to = toDirectory
.resolve(serverInfo.getServer().isProxy() ? "server/" + toFileName(server.getName()) : "server") .resolve(serverInfo.getServer().isProxy() ? "server/" + toFileName(server.getName()) : "server")
@ -124,6 +132,28 @@ public class ServerPageExporter extends FileExporter {
export(to, exportPaths.resolveExportPaths(html)); export(to, exportPaths.resolveExportPaths(html));
} }
private void exportReactRedirects(Path toDirectory, ServerUUID serverUUID) throws IOException {
if (config.isFalse(PluginSettings.FRONTEND_BETA)) return;
Resource redirect = files.getResourceFromJar("web/export-redirect.html");
String server = "server/";
exportReactRedirect(toDirectory, redirect, server + serverUUID);
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/overview");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/online-activity");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/sessions");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/pvppve");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/playerbase");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/join-addresses");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/players");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/geolocations");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/performance");
exportReactRedirect(toDirectory, redirect, server + serverUUID + "/plugins-overview");
}
private void exportReactRedirect(Path toDirectory, Resource redirectHtml, String path) throws IOException {
export(toDirectory.resolve(path).resolve("index.html"), redirectHtml.asString());
}
/** /**
* Perform export for a server page json payload. * Perform export for a server page json payload.
* *
@ -200,6 +230,8 @@ public class ServerPageExporter extends FileExporter {
} }
private void exportRequiredResources(Path toDirectory) throws IOException { private void exportRequiredResources(Path toDirectory) throws IOException {
if (config.isTrue(PluginSettings.FRONTEND_BETA)) return;
// Style // Style
exportResources(toDirectory, exportResources(toDirectory,
"../img/Flaticon_circle.png", "../img/Flaticon_circle.png",

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="AuroraLS3" name="author">
<meta content="noindex, nofollow" name="robots">
<title>Plan | Player Analytics</title>
<script>window.location.href = `/?redirect=${encodeURIComponent(window.location.pathname + window.location.hash + window.location.search)}`</script>
</head>
<body>
<noscript>Please enable javascript.</noscript>
</body>
</html>

View File

@ -3,8 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport"> <meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
<meta content="Player Analytics, player page that displays more insights about a specific player" <meta content="Player Analytics" name="description">
name="description">
<meta content="AuroraLS3" name="author"> <meta content="AuroraLS3" name="author">
<meta content="noindex, nofollow" name="robots"> <meta content="noindex, nofollow" name="robots">

View File

@ -2,6 +2,7 @@ import {useAuth} from "../../hooks/authenticationHook";
import {useMetadata} from "../../hooks/metadataHook"; import {useMetadata} from "../../hooks/metadataHook";
import {Navigate} from "react-router-dom"; import {Navigate} from "react-router-dom";
import React, {useEffect, useState} from "react"; import React, {useEffect, useState} from "react";
import {staticSite} from "../../service/backendConfiguration";
const RedirectPlaceholder = () => { const RedirectPlaceholder = () => {
const [redirectStart] = useState(Date.now()) const [redirectStart] = useState(Date.now())
@ -49,14 +50,19 @@ const MainPageRedirect = () => {
const {authLoaded, authRequired, loggedIn, user} = useAuth(); const {authLoaded, authRequired, loggedIn, user} = useAuth();
const {isProxy, serverName} = useMetadata(); const {isProxy, serverName} = useMetadata();
if (staticSite) {
const urlParams = new URLSearchParams(window.location.search);
const redirect = urlParams.get('redirect');
if (redirect) {
return (<Navigate to={redirect} replace={true}/>)
}
}
if (!authLoaded || !serverName) { if (!authLoaded || !serverName) {
return <RedirectPlaceholder/> return <RedirectPlaceholder/>
} }
if (authRequired && !loggedIn) { const redirectBasedOnPermissions = () => {
return (<Navigate to="/login" replace={true}/>)
} else if (authRequired && loggedIn) {
if (isProxy && user.permissions.includes('page.network')) { if (isProxy && user.permissions.includes('page.network')) {
return (<Navigate to={"/network/overview"} replace={true}/>) return (<Navigate to={"/network/overview"} replace={true}/>)
} else if (user.permissions.includes('page.server')) { } else if (user.permissions.includes('page.server')) {
@ -66,6 +72,12 @@ const MainPageRedirect = () => {
} else if (user.permissions.includes('page.player.self')) { } else if (user.permissions.includes('page.player.self')) {
return (<Navigate to={"/player/" + user.linkedToUuid} replace={true}/>) return (<Navigate to={"/player/" + user.linkedToUuid} replace={true}/>)
} }
};
if (authRequired && !loggedIn) {
return (<Navigate to="/login" replace={true}/>)
} else if (authRequired && loggedIn) {
return redirectBasedOnPermissions();
} else { } else {
return (<Navigate to={isProxy ? "/network/overview" : "/server/" + encodeURIComponent(serverName) + "/overview"} return (<Navigate to={isProxy ? "/network/overview" : "/server/" + encodeURIComponent(serverName) + "/overview"}
replace={true}/>) replace={true}/>)