diff --git a/site/src/api/queries/externalAuth.ts b/site/src/api/queries/externalAuth.ts
new file mode 100644
index 0000000000000..2a0c66458752b
--- /dev/null
+++ b/site/src/api/queries/externalAuth.ts
@@ -0,0 +1,63 @@
+import * as API from "api/api";
+import { ExternalAuth } from "api/typesGenerated";
+import { QueryClient, UseMutationOptions } from "react-query";
+
+// Returns all configured external auths for a given user.
+export const externalAuths = () => {
+ return {
+ queryKey: ["external-auth"],
+ queryFn: () => API.getUserExternalAuthProviders(),
+ };
+};
+
+export const externalAuthProvider = (providerId: string) => {
+ return {
+ queryKey: ["external-auth", providerId],
+ queryFn: () => API.getExternalAuthProvider(providerId),
+ };
+};
+
+export const externalAuthDevice = (providerId: string) => {
+ return {
+ queryFn: () => API.getExternalAuthDevice(providerId),
+ queryKey: ["external-auth", providerId, "device"],
+ };
+};
+
+export const exchangeExternalAuthDevice = (
+ providerId: string,
+ deviceCode: string,
+ queryClient: QueryClient,
+) => {
+ return {
+ queryFn: () =>
+ API.exchangeExternalAuthDevice(providerId, {
+ device_code: deviceCode,
+ }),
+ queryKey: ["external-auth", providerId, "device", deviceCode],
+ onSuccess: async () => {
+ // Force a refresh of the Git auth status.
+ await queryClient.invalidateQueries(["external-auth", providerId]);
+ },
+ };
+};
+
+export const validateExternalAuth = (
+ queryClient: QueryClient,
+): UseMutationOptions => {
+ return {
+ mutationFn: API.getExternalAuthProvider,
+ onSuccess: (data, providerId) => {
+ queryClient.setQueryData(["external-auth", providerId], data);
+ },
+ };
+};
+
+export const unlinkExternalAuths = (queryClient: QueryClient) => {
+ return {
+ mutationFn: API.unlinkExternalAuthProvider,
+ onSuccess: async () => {
+ await queryClient.invalidateQueries(["external-auth"]);
+ },
+ };
+};
diff --git a/site/src/api/queries/externalauth.ts b/site/src/api/queries/externalauth.ts
deleted file mode 100644
index 684135db75d13..0000000000000
--- a/site/src/api/queries/externalauth.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as API from "api/api";
-import { QueryClient } from "react-query";
-
-const getUserExternalAuthsKey = () => ["list", "external-auth"];
-
-// listUserExternalAuths returns all configured external auths for a given user.
-export const listUserExternalAuths = () => {
- return {
- queryKey: getUserExternalAuthsKey(),
- queryFn: () => API.getUserExternalAuthProviders(),
- };
-};
-
-const getUserExternalAuthKey = (providerID: string) => [
- providerID,
- "get",
- "external-auth",
-];
-
-export const userExternalAuth = (providerID: string) => {
- return {
- queryKey: getUserExternalAuthKey(providerID),
- queryFn: () => API.getExternalAuthProvider(providerID),
- };
-};
-
-export const validateExternalAuth = (_: QueryClient) => {
- return {
- mutationFn: API.getExternalAuthProvider,
- };
-};
-
-export const unlinkExternalAuths = (queryClient: QueryClient) => {
- return {
- mutationFn: API.unlinkExternalAuthProvider,
- onSuccess: async () => {
- await queryClient.invalidateQueries(["external-auth"]);
- },
- };
-};
diff --git a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
index 59a9855a1c33e..3b9c81a636d82 100644
--- a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
+++ b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
@@ -1,9 +1,4 @@
import { useQuery, useQueryClient } from "react-query";
-import {
- exchangeExternalAuthDevice,
- getExternalAuthDevice,
- getExternalAuthProvider,
-} from "api/api";
import { usePermissions } from "hooks";
import { type FC } from "react";
import { useParams, useSearchParams } from "react-router-dom";
@@ -13,56 +8,44 @@ import { isAxiosError } from "axios";
import Button from "@mui/material/Button";
import { SignInLayout } from "components/SignInLayout/SignInLayout";
import { Welcome } from "components/Welcome/Welcome";
+import {
+ externalAuthDevice,
+ externalAuthProvider,
+ exchangeExternalAuthDevice,
+} from "api/queries/externalAuth";
const ExternalAuthPage: FC = () => {
- const { provider } = useParams();
- if (!provider) {
- throw new Error("provider must exist");
- }
+ const { provider } = useParams() as { provider: string };
const [searchParams] = useSearchParams();
const permissions = usePermissions();
const queryClient = useQueryClient();
- const getExternalAuthProviderQuery = useQuery({
- queryKey: ["externalauth", provider],
- queryFn: () => getExternalAuthProvider(provider),
+ const externalAuthProviderOpts = externalAuthProvider(provider);
+ const externalAuthProviderQuery = useQuery({
+ ...externalAuthProviderOpts,
refetchOnWindowFocus: true,
});
- const getExternalAuthDeviceQuery = useQuery({
+ const externalAuthDeviceQuery = useQuery({
+ ...externalAuthDevice(provider),
enabled:
- Boolean(!getExternalAuthProviderQuery.data?.authenticated) &&
- Boolean(getExternalAuthProviderQuery.data?.device),
- queryFn: () => getExternalAuthDevice(provider),
- queryKey: ["externalauth", provider, "device"],
+ Boolean(!externalAuthProviderQuery.data?.authenticated) &&
+ Boolean(externalAuthProviderQuery.data?.device),
refetchOnMount: false,
});
const exchangeExternalAuthDeviceQuery = useQuery({
- queryFn: () =>
- exchangeExternalAuthDevice(provider, {
- device_code: getExternalAuthDeviceQuery.data?.device_code || "",
- }),
- queryKey: [
- "externalauth",
+ ...exchangeExternalAuthDevice(
provider,
- getExternalAuthDeviceQuery.data?.device_code,
- ],
- enabled: Boolean(getExternalAuthDeviceQuery.data),
- onSuccess: () => {
- // Force a refresh of the Git auth status.
- queryClient.invalidateQueries(["externalauth", provider]).catch((ex) => {
- console.error("invalidate queries", ex);
- });
- },
+ externalAuthDeviceQuery.data?.device_code ?? "",
+ queryClient,
+ ),
+ enabled: Boolean(externalAuthDeviceQuery.data),
retry: true,
- retryDelay: (getExternalAuthDeviceQuery.data?.interval || 5) * 1000,
+ retryDelay: (externalAuthDeviceQuery.data?.interval || 5) * 1000,
refetchOnWindowFocus: (query) =>
query.state.status === "success" ? false : "always",
});
- if (
- getExternalAuthProviderQuery.isLoading ||
- !getExternalAuthProviderQuery.data
- ) {
+ if (externalAuthProviderQuery.isLoading || !externalAuthProviderQuery.data) {
return null;
}
@@ -73,8 +56,8 @@ const ExternalAuthPage: FC = () => {
}
if (
- !getExternalAuthProviderQuery.data.authenticated &&
- !getExternalAuthProviderQuery.data.device
+ !externalAuthProviderQuery.data.authenticated &&
+ !externalAuthProviderQuery.data.device
) {
const redirectedParam = searchParams?.get("redirected");
if (redirectedParam && redirectedParam.toLowerCase() === "true") {
@@ -111,16 +94,16 @@ const ExternalAuthPage: FC = () => {
return (
{
- queryClient.setQueryData(["externalauth", provider], {
- ...getExternalAuthProviderQuery.data,
+ queryClient.setQueryData(externalAuthProviderOpts.queryKey, {
+ ...externalAuthProviderQuery.data,
authenticated: false,
});
}}
viewExternalAuthConfig={permissions.viewExternalAuthConfig}
deviceExchangeError={deviceExchangeError}
- externalAuthDevice={getExternalAuthDeviceQuery.data}
+ externalAuthDevice={externalAuthDeviceQuery.data}
/>
);
};
diff --git a/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPage.tsx b/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPage.tsx
index ced75156bd0c5..f577f31389e3d 100644
--- a/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPage.tsx
+++ b/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPage.tsx
@@ -1,10 +1,10 @@
import { FC, useState } from "react";
import { UserExternalAuthSettingsPageView } from "./UserExternalAuthSettingsPageView";
import {
- listUserExternalAuths,
+ externalAuths,
unlinkExternalAuths,
validateExternalAuth,
-} from "api/queries/externalauth";
+} from "api/queries/externalAuth";
import { Section } from "components/SettingsLayout/Section";
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
import { useMutation, useQuery, useQueryClient } from "react-query";
@@ -17,30 +17,17 @@ const UserExternalAuthSettingsPage: FC = () => {
// need to be refetched
const [unlinked, setUnlinked] = useState(0);
- const {
- data: externalAuths,
- error,
- isLoading,
- refetch,
- } = useQuery(listUserExternalAuths());
-
+ const externalAuthsQuery = useQuery(externalAuths());
const [appToUnlink, setAppToUnlink] = useState();
- const mutateParams = unlinkExternalAuths(queryClient);
- const unlinkAppMutation = useMutation({
- ...mutateParams,
- onSuccess: async () => {
- await mutateParams.onSuccess();
- },
- });
-
+ const unlinkAppMutation = useMutation(unlinkExternalAuths(queryClient));
const validateAppMutation = useMutation(validateExternalAuth(queryClient));
return (
-
+
{
setAppToUnlink(providerID);
@@ -81,7 +68,7 @@ const UserExternalAuthSettingsPage: FC = () => {
// setAppToUnlink closes the modal
setAppToUnlink(undefined);
// refetch repopulates the external auth data
- await refetch();
+ await externalAuthsQuery.refetch();
// this tells our child components to refetch their data
// as at least 1 provider was unlinked.
setUnlinked(unlinked + 1);
diff --git a/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPageView.tsx b/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPageView.tsx
index 96ef1066f43b7..0d00f4d4d596f 100644
--- a/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPageView.tsx
+++ b/site/src/pages/UserExternalAuthSettingsPage/UserExternalAuthSettingsPageView.tsx
@@ -24,7 +24,7 @@ import {
import { ExternalAuthPollingState } from "pages/CreateWorkspacePage/CreateWorkspacePage";
import { useState, useCallback, useEffect } from "react";
import { useQuery } from "react-query";
-import { userExternalAuth } from "api/queries/externalauth";
+import { externalAuthProvider } from "api/queries/externalAuth";
import { FullScreenLoader } from "components/Loader/FullScreenLoader";
export type UserExternalAuthSettingsPageViewProps = {
@@ -61,7 +61,7 @@ export const UserExternalAuthSettingsPageView = ({
Application
Link
-
+
@@ -150,7 +150,7 @@ const ExternalAuthRow = ({
message={authenticated ? "Authenticated" : "Click to Login"}
externalAuthPollingState={externalAuthPollingState}
startPollingExternalAuth={startPollingExternalAuth}
- >
+ />
{(link || externalAuth?.authenticated) && (
@@ -199,7 +199,7 @@ const useExternalAuth = (providerID: string, unlinked: number) => {
}, []);
const { data: externalAuth, refetch } = useQuery({
- ...userExternalAuth(providerID),
+ ...externalAuthProvider(providerID),
refetchInterval: externalAuthPollingState === "polling" ? 1000 : false,
});