Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/teams/sso/OIDCClients.tsx
2501 views
1
/**
2
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { OIDCClientConfig } from "@gitpod/public-api/lib/gitpod/experimental/v1/oidc_pb";
8
import { FC, useCallback, useState } from "react";
9
import { Button } from "@podkit/buttons/Button";
10
import { EmptyMessage } from "../../components/EmptyMessage";
11
import { Item, ItemField, ItemFieldIcon, ItemsList } from "../../components/ItemsList";
12
import { SpinnerLoader } from "../../components/Loader";
13
import { Heading2, Subheading } from "../../components/typography/headings";
14
import { useOIDCClientsQuery } from "../../data/oidc-clients/oidc-clients-query";
15
import { OIDCClientConfigModal } from "./OIDCClientConfigModal";
16
import { OIDCClientListItem } from "./OIDCClientListItem";
17
import { useToast } from "../../components/toasts/Toasts";
18
import { LinkButton } from "../../components/LinkButton";
19
import { ActivateConfigModal } from "./ActivateConfigModal";
20
import { useVerifyClient } from "./use-verify-client";
21
22
export const OIDCClients: FC = () => {
23
const { data, isLoading } = useOIDCClientsQuery();
24
25
if (isLoading) {
26
return <SpinnerLoader />;
27
}
28
29
return <OIDCClientsList clientConfigs={data || []} />;
30
};
31
32
type OIDCClientsListProps = {
33
clientConfigs: OIDCClientConfig[];
34
};
35
const OIDCClientsList: FC<OIDCClientsListProps> = ({ clientConfigs }) => {
36
const { toast } = useToast();
37
const [showCreateModal, setShowCreateModal] = useState(false);
38
const [activateModalConfigId, setActivateModalConfigID] = useState("");
39
40
const verifyClient = useVerifyClient({
41
onSuccess: (configId: string) => {
42
toast(
43
<span>
44
Single sign-on configuration was successfully verified.{" "}
45
<LinkButton inverted onClick={() => setActivateModalConfigID(configId)}>
46
Activate configuration
47
</LinkButton>
48
</span>,
49
);
50
},
51
onError: (errorMessage) => {
52
toast(errorMessage);
53
},
54
});
55
56
const onCreate = useCallback(() => setShowCreateModal(true), []);
57
const hideModal = useCallback(() => setShowCreateModal(false), []);
58
59
const handleSaved = useCallback(
60
(configId: string) => {
61
toast(
62
<span>
63
Single sign-on configuration was successfully saved.{" "}
64
<LinkButton inverted onClick={() => verifyClient(configId)}>
65
Verify configuration
66
</LinkButton>
67
</span>,
68
);
69
},
70
[toast, verifyClient],
71
);
72
73
const hasActiveConfig = clientConfigs.some((config) => config.active);
74
75
return (
76
<>
77
{showCreateModal && <OIDCClientConfigModal onSaved={handleSaved} onClose={hideModal} />}
78
79
<div className="flex flex-col space-y-2 md:flex-row md:items-start md:justify-between md:space-y-0">
80
<div>
81
<Heading2>SSO Configurations</Heading2>
82
<Subheading>Configure OpenID Connect single sign-on for your organization.</Subheading>
83
</div>
84
85
{clientConfigs.length !== 0 ? (
86
<div>
87
<Button className="whitespace-nowrap" onClick={onCreate}>
88
New Configuration
89
</Button>
90
</div>
91
) : null}
92
</div>
93
94
{clientConfigs.length === 0 ? (
95
<EmptyMessage
96
subtitle="Enable single sign-on for your organization using an external identity provider (IdP) service that supports the OpenID Connect (OIDC) standard, such as Google or Okta."
97
buttonText="New Configuration"
98
onClick={onCreate}
99
/>
100
) : (
101
<ItemsList className="pt-6">
102
<Item header={true}>
103
<ItemFieldIcon />
104
<ItemField>Issuer URL</ItemField>
105
</Item>
106
{clientConfigs.map((cc) => (
107
<OIDCClientListItem
108
key={cc.id}
109
clientConfig={cc}
110
hasActiveConfig={hasActiveConfig}
111
onVerify={verifyClient}
112
onActivate={setActivateModalConfigID}
113
onSaved={handleSaved}
114
/>
115
))}
116
</ItemsList>
117
)}
118
119
{!!activateModalConfigId && (
120
<ActivateConfigModal
121
configId={activateModalConfigId}
122
hasActiveConfig={hasActiveConfig}
123
onClose={() => setActivateModalConfigID("")}
124
/>
125
)}
126
</>
127
);
128
};
129
130