Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/dashboard/src/dedicated-setup/SSOSetupStep.tsx
2506 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 { FC, useCallback, useReducer, useState } from "react";
8
import { Heading1, Subheading } from "../components/typography/headings";
9
import { SetupLayout } from "./SetupLayout";
10
import { SSOConfigForm, isValid, ssoConfigReducer, useSaveSSOConfig } from "../teams/sso/SSOConfigForm";
11
import Alert from "../components/Alert";
12
import { OIDCClientConfig } from "@gitpod/public-api/lib/gitpod/experimental/v1/oidc_pb";
13
import { openOIDCStartWindow } from "../provider-utils";
14
import { LoadingButton } from "@podkit/buttons/LoadingButton";
15
16
type Props = {
17
config?: OIDCClientConfig;
18
onComplete: () => void;
19
progressCurrent?: number;
20
progressTotal?: number;
21
};
22
export const SSOSetupStep: FC<Props> = ({ config, onComplete, progressCurrent, progressTotal }) => {
23
const [ssoLoginError, setSSOLoginError] = useState("");
24
25
const [ssoConfig, dispatch] = useReducer(ssoConfigReducer, {
26
id: config?.id ?? "",
27
issuer: config?.oidcConfig?.issuer ?? "",
28
clientId: config?.oauth2Config?.clientId ?? "",
29
clientSecret: config?.oauth2Config?.clientSecret ?? "",
30
celExpression: config?.oauth2Config?.celExpression ?? "",
31
usePKCE: config?.oauth2Config?.usePkce ?? false,
32
});
33
const configIsValid = isValid(ssoConfig);
34
35
const { save, isLoading, isError, error } = useSaveSSOConfig();
36
37
const handleVerify = useCallback(
38
async (e) => {
39
e.preventDefault();
40
41
if (isLoading) {
42
return;
43
}
44
45
try {
46
let configId = ssoConfig.id;
47
48
const response = await save(ssoConfig);
49
50
// Create returns the new config, update does not
51
if ("config" in response && response.config) {
52
configId = response.config.id;
53
54
// Update our local state with the new config ID in case we created a new one
55
// This ensures we update the correct config if we save again vs. create a new one
56
dispatch({
57
id: configId,
58
});
59
}
60
61
await openOIDCStartWindow({
62
activate: true,
63
configId: configId,
64
onSuccess: async () => {
65
onComplete();
66
},
67
onError: (payload) => {
68
let errorMessage: string;
69
if (typeof payload === "string") {
70
errorMessage = payload;
71
} else {
72
errorMessage = payload.description ? payload.description : `Error: ${payload.error}`;
73
}
74
setSSOLoginError(errorMessage);
75
},
76
});
77
} catch (e) {
78
console.error(e);
79
}
80
},
81
[isLoading, onComplete, save, ssoConfig],
82
);
83
84
return (
85
<SetupLayout showOrg progressCurrent={progressCurrent} progressTotal={progressTotal}>
86
<div className="mb-10">
87
<Heading1>Configure single sign-on</Heading1>
88
<Subheading>
89
Enable single sign-on for your organization using the OpenID Connect (OIDC) standard.{" "}
90
<a
91
href="https://www.gitpod.io/docs/enterprise/setup-gitpod/configure-sso"
92
target="_blank"
93
rel="noreferrer noopener"
94
className="gp-link"
95
>
96
Learn more
97
</a>
98
</Subheading>
99
</div>
100
{isError && <Alert type="danger">{error?.message}</Alert>}
101
102
{ssoLoginError && <Alert type="danger">{ssoLoginError}</Alert>}
103
104
<form onSubmit={handleVerify}>
105
<SSOConfigForm config={ssoConfig} onChange={dispatch} />
106
107
<div className="mt-6">
108
<LoadingButton type="submit" className="w-full" disabled={!configIsValid} loading={isLoading}>
109
Verify SSO Configuration
110
</LoadingButton>
111
</div>
112
</form>
113
</SetupLayout>
114
);
115
};
116
117