From abb5fd36f36b7e2fd0dfdcdff836910139954e42 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Wed, 25 Jan 2023 01:32:43 +0530 Subject: [PATCH] Support OIDC (#6661) * Support OIDC * tweak to the Configure button * fix the type import --- apps/web/package.json | 2 +- apps/web/pages/api/auth/oidc.ts | 37 ++++ apps/web/public/static/locales/en/common.json | 30 ++- .../ee/sso/components/ConfigDialogForm.tsx | 85 -------- .../ee/sso/components/ConnectionInfo.tsx | 168 ++++++++++++++++ .../ee/sso/components/OIDCConnection.tsx | 168 ++++++++++++++++ .../ee/sso/components/SAMLConfiguration.tsx | 184 ------------------ .../ee/sso/components/SAMLConnection.tsx | 131 +++++++++++++ .../ee/sso/components/SSOConfiguration.tsx | 61 ++++++ packages/features/ee/sso/lib/jackson.ts | 3 +- packages/features/ee/sso/lib/saml.ts | 9 + .../features/ee/sso/page/teams-sso-view.tsx | 12 +- .../features/ee/sso/page/user-sso-view.tsx | 14 +- packages/trpc/server/routers/viewer.tsx | 4 +- .../routers/viewer/{saml.tsx => sso.tsx} | 84 ++++++-- 15 files changed, 685 insertions(+), 307 deletions(-) create mode 100644 apps/web/pages/api/auth/oidc.ts delete mode 100644 packages/features/ee/sso/components/ConfigDialogForm.tsx create mode 100644 packages/features/ee/sso/components/ConnectionInfo.tsx create mode 100644 packages/features/ee/sso/components/OIDCConnection.tsx delete mode 100644 packages/features/ee/sso/components/SAMLConfiguration.tsx create mode 100644 packages/features/ee/sso/components/SAMLConnection.tsx create mode 100644 packages/features/ee/sso/components/SSOConfiguration.tsx rename packages/trpc/server/routers/viewer/{saml.tsx => sso.tsx} (60%) diff --git a/apps/web/package.json b/apps/web/package.json index 2a9628c4a7..7516a64b3d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -23,7 +23,7 @@ "yarn": ">=1.19.0 < 2.0.0" }, "dependencies": { - "@boxyhq/saml-jackson": "1.3.6", + "@boxyhq/saml-jackson": "1.7.1", "@calcom/app-store": "*", "@calcom/app-store-cli": "*", "@calcom/core": "*", diff --git a/apps/web/pages/api/auth/oidc.ts b/apps/web/pages/api/auth/oidc.ts new file mode 100644 index 0000000000..1cd2af2c69 --- /dev/null +++ b/apps/web/pages/api/auth/oidc.ts @@ -0,0 +1,37 @@ +import { NextApiRequest, NextApiResponse } from "next"; + +import jackson from "@calcom/features/ee/sso/lib/jackson"; + +import { HttpError } from "@lib/core/http/error"; + +// This is the callback endpoint for the OIDC provider +// A team must set this endpoint in the OIDC provider's configuration +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + if (req.method !== "GET") { + return res.status(400).send("Method not allowed"); + } + + const { code, state } = req.query as { + code: string; + state: string; + }; + + const { oauthController } = await jackson(); + + try { + const { redirect_url } = await oauthController.oidcAuthzResponse({ code, state }); + + if (!redirect_url) { + throw new HttpError({ + message: "No redirect URL found", + statusCode: 500, + }); + } + + return res.redirect(302, redirect_url); + } catch (err) { + const { message, statusCode = 500 } = err as HttpError; + + return res.status(statusCode).send(message); + } +} diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 1b1e382c70..8157b4ddbc 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -1375,15 +1375,6 @@ "error_editing_availability": "Error editing availability", "dont_have_permission": "You don't have permission to access this resource.", "saml_config": "Single Sign-On", - "saml_description": "Allow team members to login using an Identity Provider", - "saml_config_deleted_successfully": "SAML configuration deleted successfully", - "saml_config_updated_successfully": "SAML configuration updated successfully", - "saml_configuration": "SAML configuration", - "delete_saml_configuration": "Delete SAML configuration", - "delete_saml_configuration_confirmation_message": "Are you sure you want to delete the SAML configuration? Your team members who use SAML login will no longer be able to access Cal.com.", - "confirm_delete_saml_configuration": "Yes, delete SAML configuration", - "saml_not_configured_yet": "SAML not configured yet", - "saml_configuration_description": "Please paste the SAML metadata from your Identity Provider in the textbox below to update your SAML configuration.", "saml_configuration_placeholder": "Please paste the SAML metadata from your Identity Provider here", "saml_email_required": "Please enter an email so we can find your SAML Identity Provider", "saml_sp_title": "Service Provider Details", @@ -1523,5 +1514,24 @@ "reporting": "Reporting", "reporting_feature": "See all incoming from data and download it as a CSV", "teams_plan_required": "Teams plan required", - "routing_forms_are_a_great_way": "Routing forms are a great way to route your incoming leads to the right person. Upgrade to a Teams plan to access this feature." + "routing_forms_are_a_great_way": "Routing forms are a great way to route your incoming leads to the right person. Upgrade to a Teams plan to access this feature.", + "configure": "Configure", + "sso_configuration": "Single Sign-On", + "sso_configuration_description": "Configure SAML/OIDC SSO and allow team members to login using an Identity Provider", + "sso_oidc_heading": "SSO with OIDC", + "sso_oidc_description": "Configure OIDC SSO with Identity Provider of your choice.", + "sso_oidc_configuration_title": "OIDC Configuration", + "sso_oidc_configuration_description": "Configure OIDC connection to your identity provider. You can find the required information in your identity provider.", + "sso_oidc_callback_copied": "Callback URL copied", + "sso_saml_heading": "SSO with SAML", + "sso_saml_description": "Configure SAML SSO with Identity Provider of your choice.", + "sso_saml_configuration_title": "SAML Configuration", + "sso_saml_configuration_description": "Configure SAML connection to your identity provider. You can find the required information in your identity provider.", + "sso_saml_acsurl_copied": "ACS URL copied", + "sso_saml_entityid_copied": "Entity ID copied", + "sso_connection_created_successfully": "{{connectionType}} configuration created successfully", + "sso_connection_deleted_successfully": "{{connectionType}} configuration deleted successfully", + "delete_sso_configuration": "Delete {{connectionType}} configuration", + "delete_sso_configuration_confirmation": "Yes, delete {{connectionType}} configuration", + "delete_sso_configuration_confirmation_description": "Are you sure you want to delete the {{connectionType}} configuration? Your team members who use {{connectionType}} login will no longer be able to access Cal.com." } diff --git a/packages/features/ee/sso/components/ConfigDialogForm.tsx b/packages/features/ee/sso/components/ConfigDialogForm.tsx deleted file mode 100644 index e65414adcb..0000000000 --- a/packages/features/ee/sso/components/ConfigDialogForm.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { Controller, useForm } from "react-hook-form"; - -import LicenseRequired from "@calcom/ee/common/components/v2/LicenseRequired"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry"; -import { trpc } from "@calcom/trpc/react"; -import { Button, DialogFooter, Form, showToast, TextArea } from "@calcom/ui"; - -interface TeamSSOValues { - metadata: string; -} - -export default function ConfigDialogForm({ - teamId, - handleClose, -}: { - teamId: number | null; - handleClose: () => void; -}) { - const { t } = useLocale(); - const utils = trpc.useContext(); - - const telemetry = useTelemetry(); - - const form = useForm(); - - const mutation = trpc.viewer.saml.update.useMutation({ - async onSuccess() { - telemetry.event(telemetryEventTypes.samlConfig, collectPageParameters()); - await utils.viewer.saml.get.invalidate(); - showToast(t("saml_config_updated_successfully"), "success"); - handleClose(); - }, - onError: (err) => { - showToast(err.message, "error"); - }, - }); - - return ( - -
{ - mutation.mutate({ - teamId, - encodedRawMetadata: Buffer.from(values.metadata).toString("base64"), - }); - }}> -
-

- {t("saml_configuration")} -

-

{t("saml_configuration_description")}

-
- ( -
-