diff --git a/.env.example b/.env.example
index e131e6b..fc33be8 100644
--- a/.env.example
+++ b/.env.example
@@ -27,4 +27,5 @@ LOGIN_TIMEOUT=300
LOGIN_MAX_RETRIES=5
LOG_LEVEL=0
APP_TITLE=Tinyauth SSO
-FORGOT_PASSWORD_MESSAGE=Some message about resetting the password
\ No newline at end of file
+FORGOT_PASSWORD_MESSAGE=Some message about resetting the password
+OAUTH_AUTO_REDIRECT=none
\ No newline at end of file
diff --git a/cmd/root.go b/cmd/root.go
index d416702..eabbfb6 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -91,6 +91,7 @@ var rootCmd = &cobra.Command{
CookieSecure: config.CookieSecure,
Domain: domain,
ForgotPasswordMessage: config.FogotPasswordMessage,
+ OAuthAutoRedirect: config.OAuthAutoRedirect,
}
// Create api config
@@ -197,6 +198,7 @@ func init() {
rootCmd.Flags().String("generic-name", "Generic", "Generic OAuth provider name.")
rootCmd.Flags().Bool("disable-continue", false, "Disable continue screen and redirect to app directly.")
rootCmd.Flags().String("oauth-whitelist", "", "Comma separated list of email addresses to whitelist when using OAuth.")
+ rootCmd.Flags().String("oauth-auto-redirect", "none", "Auto redirect to the specified OAuth provider if configured. (available providers: github, google, generic)")
rootCmd.Flags().Int("session-expiry", 86400, "Session (cookie) expiration time in seconds.")
rootCmd.Flags().Int("login-timeout", 300, "Login timeout in seconds after max retries reached (0 to disable).")
rootCmd.Flags().Int("login-max-retries", 5, "Maximum login attempts before timeout (0 to disable).")
@@ -229,6 +231,7 @@ func init() {
viper.BindEnv("generic-name", "GENERIC_NAME")
viper.BindEnv("disable-continue", "DISABLE_CONTINUE")
viper.BindEnv("oauth-whitelist", "OAUTH_WHITELIST")
+ viper.BindEnv("oauth-auto-redirect", "OAUTH_AUTO_REDIRECT")
viper.BindEnv("session-expiry", "SESSION_EXPIRY")
viper.BindEnv("log-level", "LOG_LEVEL")
viper.BindEnv("app-title", "APP_TITLE")
diff --git a/frontend/src/lib/hooks/use-is-mounted.ts b/frontend/src/lib/hooks/use-is-mounted.ts
new file mode 100644
index 0000000..1fabe17
--- /dev/null
+++ b/frontend/src/lib/hooks/use-is-mounted.ts
@@ -0,0 +1,26 @@
+import { useCallback, useEffect, useRef } from 'react'
+
+/**
+ * Custom hook that determines if the component is currently mounted.
+ * @returns {() => boolean} A function that returns a boolean value indicating whether the component is mounted.
+ * @public
+ * @see [Documentation](https://usehooks-ts.com/react-hook/use-is-mounted)
+ * @example
+ * ```tsx
+ * const isComponentMounted = useIsMounted();
+ * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.
+ * ```
+ */
+export function useIsMounted(): () => boolean {
+ const isMounted = useRef(false)
+
+ useEffect(() => {
+ isMounted.current = true
+
+ return () => {
+ isMounted.current = false
+ }
+ }, [])
+
+ return useCallback(() => isMounted.current, [])
+}
\ No newline at end of file
diff --git a/frontend/src/pages/continue-page.tsx b/frontend/src/pages/continue-page.tsx
index 8061282..846b7d0 100644
--- a/frontend/src/pages/continue-page.tsx
+++ b/frontend/src/pages/continue-page.tsx
@@ -4,7 +4,7 @@ import { Navigate } from "react-router";
import { useUserContext } from "../context/user-context";
import { Layout } from "../components/layouts/layout";
import { ReactNode } from "react";
-import { escapeRegex, isQueryValid } from "../utils/utils";
+import { escapeRegex, isValidRedirectUri } from "../utils/utils";
import { useAppContext } from "../context/app-context";
import { Trans, useTranslation } from "react-i18next";
@@ -21,7 +21,7 @@ export const ContinuePage = () => {
return ;
}
- if (!isQueryValid(redirectUri)) {
+ if (!isValidRedirectUri(redirectUri)) {
return ;
}
@@ -51,7 +51,7 @@ export const ContinuePage = () => {
);
}
- const regex = new RegExp(`^.*${escapeRegex(domain)}$`)
+ const regex = new RegExp(`^.*${escapeRegex(domain)}$`);
if (!regex.test(uri.hostname)) {
return (
@@ -60,19 +60,24 @@ export const ContinuePage = () => {
{t("untrustedRedirectTitle")}
}}
- values={{ domain: domain }}
- />
+ i18nKey="untrustedRedirectSubtitle"
+ t={t}
+ components={{ Code: }}
+ values={{ domain: domain }}
+ />
-