diff --git a/frontend/src/index.css b/frontend/src/index.css
index c80b8371..450e642c 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -136,7 +136,7 @@ h4 {
}
p {
- @apply leading-7 [&:not(:first-child)]:mt-6;
+ @apply leading-6 [&:not(:first-child)]:mt-6;
}
blockquote {
diff --git a/frontend/src/pages/continue-page.tsx b/frontend/src/pages/continue-page.tsx
index 8b932dbd..cc4d4326 100644
--- a/frontend/src/pages/continue-page.tsx
+++ b/frontend/src/pages/continue-page.tsx
@@ -12,6 +12,7 @@ import { isValidUrl } from "@/lib/utils";
import { Trans, useTranslation } from "react-i18next";
import { Navigate, useLocation, useNavigate } from "react-router";
import DOMPurify from "dompurify";
+import { useState } from "react";
export const ContinuePage = () => {
const { isLoggedIn } = useUserContext();
@@ -22,6 +23,7 @@ export const ContinuePage = () => {
const { domain, disableContinue } = useAppContext();
const { search } = useLocation();
+ const [loading, setLoading] = useState(false);
const searchParams = new URLSearchParams(search);
const redirectURI = searchParams.get("redirect_uri");
@@ -34,10 +36,15 @@ export const ContinuePage = () => {
return ;
}
- if (disableContinue) {
+ const handleRedirect = () => {
+ setLoading(true);
window.location.href = DOMPurify.sanitize(redirectURI);
}
+ if (disableContinue) {
+ handleRedirect();
+ }
+
const { t } = useTranslation();
const navigate = useNavigate();
@@ -63,14 +70,13 @@ export const ContinuePage = () => {
-
@@ -97,14 +103,13 @@ export const ContinuePage = () => {
- (window.location.href = DOMPurify.sanitize(redirectURI))
- }
+ onClick={handleRedirect}
+ loading={loading}
variant="warning"
>
{t("continueTitle")}
- navigate("/logout")} variant="outline">
+ navigate("/logout")} variant="outline" disabled={loading}>
{t("cancelTitle")}
@@ -120,9 +125,8 @@ export const ContinuePage = () => {
- (window.location.href = DOMPurify.sanitize(redirectURI))
- }
+ onClick={handleRedirect}
+ loading={loading}
>
{t("continueTitle")}
diff --git a/frontend/src/pages/login-page.tsx b/frontend/src/pages/login-page.tsx
index 642d59b4..9f048f5a 100644
--- a/frontend/src/pages/login-page.tsx
+++ b/frontend/src/pages/login-page.tsx
@@ -126,6 +126,8 @@ export const LoginPage = () => {
icon={}
className="w-full"
onClick={() => oauthMutation.mutate("google")}
+ loading={oauthMutation.isPending && oauthMutation.variables === "google"}
+ disabled={oauthMutation.isPending || loginMutation.isPending}
/>
)}
{configuredProviders.includes("github") && (
@@ -134,6 +136,8 @@ export const LoginPage = () => {
icon={}
className="w-full"
onClick={() => oauthMutation.mutate("github")}
+ loading={oauthMutation.isPending && oauthMutation.variables === "github"}
+ disabled={oauthMutation.isPending || loginMutation.isPending}
/>
)}
{configuredProviders.includes("generic") && (
@@ -142,6 +146,8 @@ export const LoginPage = () => {
icon={}
className="w-full"
onClick={() => oauthMutation.mutate("generic")}
+ loading={oauthMutation.isPending && oauthMutation.variables === "generic"}
+ disabled={oauthMutation.isPending || loginMutation.isPending}
/>
)}
@@ -152,7 +158,7 @@ export const LoginPage = () => {
{userAuthConfigured && (
loginMutation.mutate(values)}
- loading={loginMutation.isPending}
+ loading={loginMutation.isPending || oauthMutation.isPending}
/>
)}
{configuredProviders.length == 0 && (
diff --git a/frontend/src/pages/not-found-page.tsx b/frontend/src/pages/not-found-page.tsx
index 8f0c0517..f0d82f89 100644
--- a/frontend/src/pages/not-found-page.tsx
+++ b/frontend/src/pages/not-found-page.tsx
@@ -6,12 +6,19 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
+import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router";
export const NotFoundPage = () => {
const { t } = useTranslation();
const navigate = useNavigate();
+ const [loading, setLoading] = useState(false);
+
+ const handleRedirect = () => {
+ setLoading(true);
+ navigate("/");
+ };
return (
@@ -20,7 +27,7 @@ export const NotFoundPage = () => {
{t("notFoundSubtitle")}
- navigate("/")}>{t("notFoundButton")}
+ {t("notFoundButton")}
);
diff --git a/frontend/src/pages/totp-page.tsx b/frontend/src/pages/totp-page.tsx
index 09a16eeb..e04fb2f4 100644
--- a/frontend/src/pages/totp-page.tsx
+++ b/frontend/src/pages/totp-page.tsx
@@ -8,18 +8,24 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
+import { useUserContext } from "@/context/user-context";
import { TotpSchema } from "@/schemas/totp-schema";
import { useMutation } from "@tanstack/react-query";
import axios from "axios";
import { useId } from "react";
import { useTranslation } from "react-i18next";
-import { useLocation, useNavigate } from "react-router";
+import { Navigate, useLocation } from "react-router";
import { toast } from "sonner";
export const TotpPage = () => {
+ const { totpPending } = useUserContext();
+
+ if (!totpPending) {
+ return ;
+ }
+
const { t } = useTranslation();
const { search } = useLocation();
- const navigate = useNavigate();
const formId = useId();
const searchParams = new URLSearchParams(search);
@@ -34,7 +40,7 @@ export const TotpPage = () => {
});
setTimeout(() => {
- navigate(
+ window.location.replace(
`/continue?redirect_uri=${encodeURIComponent(redirectUri ?? "")}`,
);
}, 500);
diff --git a/frontend/src/pages/unauthorized-page.tsx b/frontend/src/pages/unauthorized-page.tsx
index 1dbbd66a..e41cad8e 100644
--- a/frontend/src/pages/unauthorized-page.tsx
+++ b/frontend/src/pages/unauthorized-page.tsx
@@ -6,6 +6,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
+import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { Navigate, useLocation, useNavigate } from "react-router";
@@ -23,6 +24,12 @@ export const UnauthorizedPage = () => {
const { t } = useTranslation();
const navigate = useNavigate();
+ const [loading, setLoading] = useState(false);
+
+ const handleRedirect = () => {
+ setLoading(true);
+ navigate("/login");
+ };
let i18nKey = "unauthorizedLoginSubtitle";
@@ -53,7 +60,7 @@ export const UnauthorizedPage = () => {
- navigate("/login")}>
+
{t("unauthorizedButton")}
diff --git a/internal/utils/utils.go b/internal/utils/utils.go
index 9c2a6aba..e7957c2d 100644
--- a/internal/utils/utils.go
+++ b/internal/utils/utils.go
@@ -255,16 +255,16 @@ func ParseUser(user string) (types.User, error) {
// Check if the user has a totp secret
if len(userSplit) == 2 {
return types.User{
- Username: userSplit[0],
- Password: userSplit[1],
+ Username: strings.TrimSpace(userSplit[0]),
+ Password: strings.TrimSpace(userSplit[1]),
}, nil
}
// Return the user struct
return types.User{
- Username: userSplit[0],
- Password: userSplit[1],
- TotpSecret: userSplit[2],
+ Username: strings.TrimSpace(userSplit[0]),
+ Password: strings.TrimSpace(userSplit[1]),
+ TotpSecret: strings.TrimSpace(userSplit[2]),
}, nil
}