diff --git a/cmd/root.go b/cmd/root.go index beaa5d2..d416702 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -111,6 +111,11 @@ var rootCmd = &cobra.Command{ LoginMaxRetries: config.LoginMaxRetries, } + // Create hooks config + hooksConfig := types.HooksConfig{ + Domain: domain, + } + // Create docker service docker := docker.NewDocker() @@ -128,7 +133,7 @@ var rootCmd = &cobra.Command{ providers.Init() // Create hooks service - hooks := hooks.NewHooks(auth, providers) + hooks := hooks.NewHooks(hooksConfig, auth, providers) // Create handlers handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker) @@ -189,7 +194,7 @@ func init() { rootCmd.Flags().String("generic-auth-url", "", "Generic OAuth auth URL.") rootCmd.Flags().String("generic-token-url", "", "Generic OAuth token URL.") rootCmd.Flags().String("generic-user-url", "", "Generic OAuth user info URL.") - rootCmd.Flags().String("generic-name", "Other", "Generic OAuth provider name.") + 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().Int("session-expiry", 86400, "Session (cookie) expiration time in seconds.") diff --git a/frontend/bun.lockb b/frontend/bun.lockb index f5d3b69..0b06ed5 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 0000000..2ddf63c --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,4 @@ +span, +p { + word-break: break-word; +} diff --git a/frontend/src/lib/i18n/locales/en-US.json b/frontend/src/lib/i18n/locales/en-US.json index 12135fe..6d1af3c 100644 --- a/frontend/src/lib/i18n/locales/en-US.json +++ b/frontend/src/lib/i18n/locales/en-US.json @@ -41,7 +41,8 @@ "totpTitle": "Enter your TOTP code", "unauthorizedTitle": "Unauthorized", "unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource {{resource}}.", - "unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.", + "unauthorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.", + "unauthorizedGroupsSubtitle": "The user with username {{username}} is not in the groups required by the resource {{resource}}.", "unauthorizedButton": "Try again", "untrustedRedirectTitle": "Untrusted redirect", "untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain ({{domain}}). Are you sure you want to continue?", diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json index 12135fe..6d1af3c 100644 --- a/frontend/src/lib/i18n/locales/en.json +++ b/frontend/src/lib/i18n/locales/en.json @@ -41,7 +41,8 @@ "totpTitle": "Enter your TOTP code", "unauthorizedTitle": "Unauthorized", "unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource {{resource}}.", - "unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.", + "unauthorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.", + "unauthorizedGroupsSubtitle": "The user with username {{username}} is not in the groups required by the resource {{resource}}.", "unauthorizedButton": "Try again", "untrustedRedirectTitle": "Untrusted redirect", "untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain ({{domain}}). Are you sure you want to continue?", diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index c5a39d6..2efd797 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -19,6 +19,7 @@ import { TotpPage } from "./pages/totp-page.tsx"; import { AppContextProvider } from "./context/app-context.tsx"; import "./lib/i18n/i18n.ts"; import { ForgotPasswordPage } from "./pages/forgot-password-page.tsx"; +import "./index.css"; const queryClient = new QueryClient(); @@ -38,7 +39,10 @@ createRoot(document.getElementById("root")!).render( } /> } /> } /> - } /> + } + /> } /> diff --git a/frontend/src/pages/logout-page.tsx b/frontend/src/pages/logout-page.tsx index 5ef6041..06a9421 100644 --- a/frontend/src/pages/logout-page.tsx +++ b/frontend/src/pages/logout-page.tsx @@ -10,7 +10,7 @@ import { useAppContext } from "../context/app-context"; import { Trans, useTranslation } from "react-i18next"; export const LogoutPage = () => { - const { isLoggedIn, username, oauth, provider } = useUserContext(); + const { isLoggedIn, oauth, provider, email, username } = useUserContext(); const { genericName } = useAppContext(); const { t } = useTranslation(); @@ -56,7 +56,7 @@ export const LogoutPage = () => { values={{ provider: provider === "generic" ? genericName : capitalize(provider), - username: username, + username: email, }} /> ) : ( diff --git a/frontend/src/pages/unauthorized-page.tsx b/frontend/src/pages/unauthorized-page.tsx index 6825bd2..84bb8d6 100644 --- a/frontend/src/pages/unauthorized-page.tsx +++ b/frontend/src/pages/unauthorized-page.tsx @@ -3,11 +3,13 @@ import { Layout } from "../components/layouts/layout"; import { Navigate } from "react-router"; import { isQueryValid } from "../utils/utils"; import { Trans, useTranslation } from "react-i18next"; +import React from "react"; export const UnauthorizedPage = () => { const queryString = window.location.search; const params = new URLSearchParams(queryString); const username = params.get("username") ?? ""; + const groupErr = params.get("groupErr") ?? ""; const resource = params.get("resource") ?? ""; const { t } = useTranslation(); @@ -16,33 +18,54 @@ export const UnauthorizedPage = () => { return ; } + if (isQueryValid(resource) && !isQueryValid(groupErr)) { + return ( + + }} + values={{ resource, username }} + /> + + ); + } + + if (isQueryValid(groupErr) && isQueryValid(resource)) { + return ( + + }} + values={{ username, resource }} + /> + + ); + } + + return ( + + }} + values={{ username }} + /> + + ); +}; + +const UnauthorizedLayout = ({ children }: { children: React.ReactNode }) => { + const { t } = useTranslation(); + return ( {t("Unauthorized")} - - {isQueryValid(resource) ? ( - - }} - values={{ resource, username }} - /> - - ) : ( - - }} - values={{ username }} - /> - - )} - + {children}