Files
netbird-dashboard/src/auth/OIDCProvider.tsx
Eduard Gert d34ae9beb2 Sync changes with netbird cloud (#407)
* Update axa oidc library and package.json

* Update ACL port state to show correct value

* Filter user groups by unique groups only

* Add peer multiselect, optimize dropdown performance for peer selection, remove 'all' group from some dropdowns, various ui / ux optimizations

* Add peer multiselect, optimize dropdown performance for peer selection, remove 'all' group from some dropdowns, various ui / ux optimizations
2024-08-13 15:51:22 +02:00

122 lines
3.9 KiB
TypeScript

"use client";
import {
AuthorityConfiguration,
OidcConfiguration,
OidcProvider,
} from "@axa-fr/react-oidc";
import FullScreenLoading from "@components/ui/FullScreenLoading";
import { useLocalStorage } from "@hooks/useLocalStorage";
import { useRedirect } from "@hooks/useRedirect";
import loadConfig, { buildExtras } from "@utils/config";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import React, { useEffect, useState } from "react";
import { OIDCError } from "@/auth/OIDCError";
import { SecureProvider } from "@/auth/SecureProvider";
type Props = {
children: React.ReactNode;
};
const config = loadConfig();
/**
* Unfortunately Auth0 https://<DOMAIN>/.well-known/openid-configuration doesn't contain end_session_endpoint that
* is required for doing logout. Therefore, we need to hardcode the config for auth
*/
const auth0AuthorityConfig: AuthorityConfiguration = {
authorization_endpoint: new URL("authorize", config.authority).href,
token_endpoint: new URL("oauth/token", config.authority).href,
revocation_endpoint: new URL("oauth/revoke", config.authority).href,
end_session_endpoint: new URL("v2/logout", config.authority).href,
userinfo_endpoint: new URL("userinfo", config.authority).href,
issuer: new URL("", config.authority).href,
};
const onEvent = (configurationName: any, eventName: any, data: any) => {
if (process.env.NODE_ENV !== "production") {
//console.info(`oidc:${configurationName}:${eventName}`, data);
}
};
export default function OIDCProvider({ children }: Props) {
const [providerConfig, setProviderConfig] = useState<OidcConfiguration>();
const [mounted, setMounted] = useState(false);
const router = useRouter();
const path = usePathname();
const params = useSearchParams()?.toString();
const [, setQueryParams] = useLocalStorage("netbird-query-params", params);
useEffect(() => {
if (
params?.includes("tab") ||
params?.includes("search") ||
params?.includes("id")
) {
setQueryParams(params);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const withCustomHistory = () => {
return {
replaceState: (url: any) => {
router.replace(url);
window.dispatchEvent(new Event("popstate"));
},
};
};
useEffect(() => {
setProviderConfig({
authority: config.authority,
client_id: config.clientId,
redirect_uri: window.location.origin + config.redirectURI,
refresh_time_before_tokens_expiration_in_second: 30,
silent_redirect_uri: window.location.origin + config.silentRedirectURI,
scope: config.scopesSupported,
// disabling service worker
//service_worker_relative_url: "/OidcServiceWorker.js",
service_worker_only: false,
authority_configuration: config.auth0Auth
? auth0AuthorityConfig
: undefined,
extras: buildExtras(),
...(config.clientSecret
? { token_request_extras: { client_secret: config.clientSecret } }
: null),
});
setMounted(true);
}, []);
// We bypass authentication for pages that do not require auth.
// E.g., when we just want to show installation steps for public.
if (path === "/install") return children;
return mounted && providerConfig ? (
<OidcProvider
configuration={providerConfig}
//withCustomHistory={withCustomHistory}
authenticatingComponent={FullScreenLoading}
authenticatingErrorComponent={OIDCError}
loadingComponent={FullScreenLoading}
callbackSuccessComponent={CallBackSuccess}
onEvent={onEvent}
onSessionLost={() => void 0}
//sessionLostComponent={SessionLost}
>
<SecureProvider>{children}</SecureProvider>
</OidcProvider>
) : (
<FullScreenLoading />
);
}
const CallBackSuccess = () => {
const params = useSearchParams();
const errorParam = params.get("error");
const currentPath = usePathname();
useRedirect(currentPath, true, !errorParam);
return <FullScreenLoading />;
};