feat: add logout redirect url (#954)
* feat: add logout redirect url * fix: format issue
This commit is contained in:
@@ -1,19 +1,38 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { createContext, useContext, useEffect } from "react";
|
||||||
import type { PropsWithChildren } from "react";
|
import type { PropsWithChildren } from "react";
|
||||||
import { useEffect } from "react";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import type { Session } from "@homarr/auth";
|
import type { Session } from "@homarr/auth";
|
||||||
import { SessionProvider, signIn } from "@homarr/auth/client";
|
import { SessionProvider, signIn } from "@homarr/auth/client";
|
||||||
|
|
||||||
interface AuthProviderProps {
|
interface AuthProviderProps extends AuthContextProps {
|
||||||
session: Session | null;
|
session: Session | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuthProvider = ({ children, session }: PropsWithChildren<AuthProviderProps>) => {
|
export const AuthProvider = ({ children, session, logoutUrl }: PropsWithChildren<AuthProviderProps>) => {
|
||||||
useLoginRedirectOnSessionExpiry(session);
|
useLoginRedirectOnSessionExpiry(session);
|
||||||
return <SessionProvider session={session}>{children}</SessionProvider>;
|
|
||||||
|
return (
|
||||||
|
<SessionProvider session={session}>
|
||||||
|
<AuthContext.Provider value={{ logoutUrl }}>{children}</AuthContext.Provider>
|
||||||
|
</SessionProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface AuthContextProps {
|
||||||
|
logoutUrl: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AuthContext = createContext<AuthContextProps | null>(null);
|
||||||
|
|
||||||
|
export const useAuthContext = () => {
|
||||||
|
const context = useContext(AuthContext);
|
||||||
|
|
||||||
|
if (!context) throw new Error("useAuthContext must be used within an AuthProvider");
|
||||||
|
|
||||||
|
return context;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useLoginRedirectOnSessionExpiry = (session: Session | null) => {
|
const useLoginRedirectOnSessionExpiry = (session: Session | null) => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import "~/styles/scroll-area.scss";
|
|||||||
|
|
||||||
import { ColorSchemeScript, createTheme, MantineProvider } from "@mantine/core";
|
import { ColorSchemeScript, createTheme, MantineProvider } from "@mantine/core";
|
||||||
|
|
||||||
|
import { env } from "@homarr/auth/env.mjs";
|
||||||
import { auth } from "@homarr/auth/next";
|
import { auth } from "@homarr/auth/next";
|
||||||
import { ModalProvider } from "@homarr/modals";
|
import { ModalProvider } from "@homarr/modals";
|
||||||
import { Notifications } from "@homarr/notifications";
|
import { Notifications } from "@homarr/notifications";
|
||||||
@@ -56,7 +57,7 @@ export default function Layout(props: { children: React.ReactNode; params: { loc
|
|||||||
const StackedProvider = composeWrappers([
|
const StackedProvider = composeWrappers([
|
||||||
async (innerProps) => {
|
async (innerProps) => {
|
||||||
const session = await auth();
|
const session = await auth();
|
||||||
return <AuthProvider session={session} {...innerProps} />;
|
return <AuthProvider session={session} logoutUrl={env.AUTH_LOGOUT_REDIRECT_URL} {...innerProps} />;
|
||||||
},
|
},
|
||||||
(innerProps) => <JotaiProvider {...innerProps} />,
|
(innerProps) => <JotaiProvider {...innerProps} />,
|
||||||
(innerProps) => <TRPCReactProvider {...innerProps} />,
|
(innerProps) => <TRPCReactProvider {...innerProps} />,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { useScopedI18n } from "@homarr/translation/client";
|
|||||||
|
|
||||||
import "flag-icons/css/flag-icons.min.css";
|
import "flag-icons/css/flag-icons.min.css";
|
||||||
|
|
||||||
|
import { useAuthContext } from "~/app/[locale]/_client-providers/session";
|
||||||
import { LanguageCombobox } from "./language/language-combobox";
|
import { LanguageCombobox } from "./language/language-combobox";
|
||||||
|
|
||||||
interface UserAvatarMenuProps {
|
interface UserAvatarMenuProps {
|
||||||
@@ -40,6 +41,7 @@ export const UserAvatarMenu = ({ children }: UserAvatarMenuProps) => {
|
|||||||
const session = useSession();
|
const session = useSession();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const { logoutUrl } = useAuthContext();
|
||||||
const { openModal } = useModalAction(LogoutModal);
|
const { openModal } = useModalAction(LogoutModal);
|
||||||
|
|
||||||
const handleSignout = useCallback(async () => {
|
const handleSignout = useCallback(async () => {
|
||||||
@@ -48,6 +50,10 @@ export const UserAvatarMenu = ({ children }: UserAvatarMenuProps) => {
|
|||||||
});
|
});
|
||||||
openModal({
|
openModal({
|
||||||
onTimeout: () => {
|
onTimeout: () => {
|
||||||
|
if (logoutUrl) {
|
||||||
|
window.location.assign(logoutUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
router.refresh();
|
router.refresh();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ const authProviders = skipValidation ? [] : authProvidersSchema.parse(process.en
|
|||||||
|
|
||||||
export const env = createEnv({
|
export const env = createEnv({
|
||||||
server: {
|
server: {
|
||||||
|
AUTH_LOGOUT_REDIRECT_URL: z.string().url().optional(),
|
||||||
AUTH_SESSION_EXPIRY_TIME: createDurationSchema("30d"),
|
AUTH_SESSION_EXPIRY_TIME: createDurationSchema("30d"),
|
||||||
AUTH_SECRET: process.env.NODE_ENV === "production" ? z.string().min(1) : z.string().min(1).optional(),
|
AUTH_SECRET: process.env.NODE_ENV === "production" ? z.string().min(1) : z.string().min(1).optional(),
|
||||||
AUTH_PROVIDERS: authProvidersSchema,
|
AUTH_PROVIDERS: authProvidersSchema,
|
||||||
@@ -94,6 +95,7 @@ export const env = createEnv({
|
|||||||
},
|
},
|
||||||
client: {},
|
client: {},
|
||||||
runtimeEnv: {
|
runtimeEnv: {
|
||||||
|
AUTH_LOGOUT_REDIRECT_URL: process.env.AUTH_LOGOUT_REDIRECT_URL,
|
||||||
AUTH_SESSION_EXPIRY_TIME: process.env.AUTH_SESSION_EXPIRY_TIME,
|
AUTH_SESSION_EXPIRY_TIME: process.env.AUTH_SESSION_EXPIRY_TIME,
|
||||||
AUTH_SECRET: process.env.AUTH_SECRET,
|
AUTH_SECRET: process.env.AUTH_SECRET,
|
||||||
AUTH_PROVIDERS: process.env.AUTH_PROVIDERS,
|
AUTH_PROVIDERS: process.env.AUTH_PROVIDERS,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"AUTH_LDAP_USER_MAIL_ATTRIBUTE",
|
"AUTH_LDAP_USER_MAIL_ATTRIBUTE",
|
||||||
"AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG",
|
"AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG",
|
||||||
"AUTH_OIDC_AUTO_LOGIN",
|
"AUTH_OIDC_AUTO_LOGIN",
|
||||||
|
"AUTH_LOGOUT_REDIRECT_URL",
|
||||||
"AUTH_PROVIDERS",
|
"AUTH_PROVIDERS",
|
||||||
"AUTH_SECRET",
|
"AUTH_SECRET",
|
||||||
"AUTH_SESSION_EXPIRY_TIME",
|
"AUTH_SESSION_EXPIRY_TIME",
|
||||||
|
|||||||
Reference in New Issue
Block a user