refactor: rework redirects and history storage

This commit is contained in:
Stavros
2025-09-01 18:01:45 +03:00
parent 0c18a64466
commit c80c37ba69
9 changed files with 51 additions and 17 deletions

View File

@@ -5,8 +5,8 @@ export const App = () => {
const { isLoggedIn } = useUserContext();
if (isLoggedIn) {
return <Navigate to="/logout" />;
return <Navigate to="/logout" replace />;
}
return <Navigate to="/login" />;
return <Navigate to="/login" replace />;
};

View File

@@ -7,6 +7,7 @@ import {
} from "../ui/card";
import { Button } from "../ui/button";
import { Trans, useTranslation } from "react-i18next";
import { useLocation } from "react-router";
interface Props {
onClick: () => void;
@@ -17,9 +18,13 @@ interface Props {
export const DomainWarning = (props: Props) => {
const { onClick, appUrl, currentUrl } = props;
const { t } = useTranslation();
const { search } = useLocation();
const searchParams = new URLSearchParams(search);
const redirectUri = searchParams.get("redirect_uri");
return (
<Card className="min-w-xs sm:min-w-sm">
<Card role="alert" aria-live="assertive" className="min-w-xs sm:min-w-sm">
<CardHeader>
<CardTitle className="text-3xl">{t("domainWarningTitle")}</CardTitle>
<CardDescription>
@@ -31,10 +36,20 @@ export const DomainWarning = (props: Props) => {
/>
</CardDescription>
</CardHeader>
<CardFooter className="flex flex-col items-stretch">
<CardFooter className="flex flex-col items-stretch gap-2">
<Button onClick={onClick} variant="warning">
{t("ignoreTitle")}
</Button>
<Button
onClick={() =>
window.location.assign(
`${appUrl}/login?redirect_uri=${encodeURIComponent(redirectUri || "")}`,
)
}
variant="outline"
>
{t("goToCorrectDomainTitle")}
</Button>
</CardFooter>
</Card>
);

View File

@@ -54,5 +54,6 @@
"invalidInput": "Invalid input",
"domainWarningTitle": "Invalid Domain",
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
"ignoreTitle": "Ignore"
"ignoreTitle": "Ignore",
"goToCorrectDomainTitle": "Go to correct domain"
}

View File

@@ -54,5 +54,6 @@
"invalidInput": "Invalid input",
"domainWarningTitle": "Invalid Domain",
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
"ignoreTitle": "Ignore"
"ignoreTitle": "Ignore",
"goToCorrectDomainTitle": "Go to correct domain"
}

View File

@@ -49,7 +49,7 @@ export const ContinuePage = () => {
const handleRedirect = () => {
setLoading(true);
window.location.replace(redirectUriObj!.toString());
window.location.assign(redirectUriObj!.toString());
};
useEffect(() => {
@@ -79,16 +79,21 @@ export const ContinuePage = () => {
}, []);
if (!isLoggedIn) {
return <Navigate to="/login" />;
return (
<Navigate
to={`/login?redirect_uri=${encodeURIComponent(redirectUri || "")}`}
replace
/>
);
}
if (!isValidRedirectUri || !isAllowedRedirectProto) {
return <Navigate to="/logout" />;
return <Navigate to="/logout" replace />;
}
if (!isTrustedRedirectUri) {
return (
<Card className="min-w-xs sm:min-w-sm">
<Card role="alert" aria-live="assertive" className="min-w-xs sm:min-w-sm">
<CardHeader>
<CardTitle className="text-3xl">
{t("continueUntrustedRedirectTitle")}
@@ -126,7 +131,7 @@ export const ContinuePage = () => {
if (isHttpsDowngrade) {
return (
<Card className="min-w-xs sm:min-w-sm">
<Card role="alert" aria-live="assertive" className="min-w-xs sm:min-w-sm">
<CardHeader>
<CardTitle className="text-3xl">
{t("continueInsecureRedirectTitle")}

View File

@@ -113,8 +113,17 @@ export const LoginPage = () => {
[],
);
if (isLoggedIn && redirectUri) {
return (
<Navigate
to={`/continue?redirect_uri=${encodeURIComponent(redirectUri)}`}
replace
/>
);
}
if (isLoggedIn) {
return <Navigate to="/logout" />;
return <Navigate to="/logout" replace />;
}
return (

View File

@@ -32,7 +32,7 @@ export const LogoutPage = () => {
});
redirectTimer.current = window.setTimeout(() => {
window.location.replace("/login");
window.location.assign("/login");
}, 500);
},
onError: () => {
@@ -50,7 +50,7 @@ export const LogoutPage = () => {
);
if (!isLoggedIn) {
return <Navigate to="/login" />;
return <Navigate to="/login" replace />;
}
return (

View File

@@ -57,7 +57,7 @@ export const TotpPage = () => {
);
if (!totpPending) {
return <Navigate to="/" />;
return <Navigate to="/" replace />;
}
return (

View File

@@ -1,6 +1,8 @@
package controller
import (
"fmt"
"net/url"
"tinyauth/internal/utils"
"github.com/gin-gonic/gin"
@@ -34,7 +36,6 @@ type AppContextResponse struct {
type ContextControllerConfig struct {
ConfiguredProviders []string
DisableContinue bool
Title string
GenericName string
AppURL string
@@ -90,13 +91,15 @@ func (controller *ContextController) userContextHandler(c *gin.Context) {
}
func (controller *ContextController) appContextHandler(c *gin.Context) {
appUrl, _ := url.Parse(controller.Config.AppURL) // no need to check error, validated on startup
c.JSON(200, AppContextResponse{
Status: 200,
Message: "Success",
ConfiguredProviders: controller.Config.ConfiguredProviders,
Title: controller.Config.Title,
GenericName: controller.Config.GenericName,
AppURL: controller.Config.AppURL,
AppURL: fmt.Sprintf("%s://%s", appUrl.Scheme, appUrl.Host),
RootDomain: controller.Config.RootDomain,
ForgotPasswordMessage: controller.Config.ForgotPasswordMessage,
BackgroundImage: controller.Config.BackgroundImage,