Prepare for implementing SAML login for the hosted solution

feature/saml-login
Deepak Prabhakara 2021-12-09 00:21:44 +00:00
parent e33eed0371
commit d0ab0e87b1
5 changed files with 31 additions and 8 deletions

View File

@ -24,8 +24,6 @@ GOOGLE_CLIENT_SECRET=
# Enable SAML login using https://github.com/boxyhq/jackson
SAML_LOGIN_URL='http://localhost:5000'
SAML_API_URL='http://localhost:6000'
SAML_TENANT_ID='Cal.com'
SAML_PRODUCT_ID='Cal.com'
JACKSON_API_KEYS='secret'
SAML_ADMINS='onboarding@example.com'

View File

@ -14,7 +14,7 @@ services:
POSTGRES_PASSWORD: ""
POSTGRES_HOST_AUTH_METHOD: trust
boxyhq_saml:
image: boxyhq/jackson:e4a34c9
image: boxyhq/jackson:e3ba514
ports:
- "5000:5000"
- "6000:6000"

View File

@ -3,12 +3,14 @@ export const samlApiUrl = process.env.SAML_API_URL;
export const isSAMLLoginEnabled = !!samlLoginUrl;
export const samlTenantID = process.env.SAML_TENANT_ID || "Cal.com";
export const samlProductID = process.env.SAML_PRODUCT_ID || "Cal.com";
export const samlTenantID = "Cal.com";
export const samlProductID = "Cal.com";
export const samlServiceApiKey = (process.env.JACKSON_API_KEYS || "").split(",")[0];
const samlAdmins = (process.env.SAML_ADMINS || "").split(",");
export const hostedCal = isSAMLLoginEnabled && samlAdmins.length === 0;
export const isSAMLAdmin = (email: string) => {
for (const admin of samlAdmins) {
if (admin.toLowerCase() === email.toLowerCase() && admin.toUpperCase() === email.toUpperCase()) {

View File

@ -6,7 +6,7 @@ import { useState } from "react";
import { ErrorCode, getSession, isGoogleLoginEnabled } from "@lib/auth";
import { useLocale } from "@lib/hooks/useLocale";
import { isSAMLLoginEnabled } from "@lib/saml";
import { isSAMLLoginEnabled, hostedCal, samlTenantID, samlProductID } from "@lib/saml";
import AddToHomescreen from "@components/AddToHomescreen";
import Loader from "@components/Loader";
@ -18,10 +18,16 @@ export default function Login({
csrfToken,
isGoogleLoginEnabled,
isSAMLLoginEnabled,
hostedCal,
samlTenantID,
samlProductID,
}: {
csrfToken: string;
isGoogleLoginEnabled: boolean;
isSAMLLoginEnabled: boolean;
hostedCal: boolean;
samlTenantID: string;
samlProductID: string;
}) {
const { t } = useLocale();
const router = useRouter();
@ -83,6 +89,19 @@ export default function Login({
}
}
const samlSignIn = async () => {
if (!hostedCal) {
await signIn("saml", {}, { tenant: samlTenantID, product: samlProductID });
} else {
if (email.length === 0) {
setErrorMessage(t("saml_email_required"));
return;
}
// hosted solution, TODO: fetch tenant and product from the backend
}
};
return (
<div className="min-h-screen bg-neutral-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<HeadSeo title={t("login")} description={t("login")} />
@ -196,7 +215,7 @@ export default function Login({
{isSAMLLoginEnabled && (
<div style={{ marginTop: "12px" }}>
<button
onClick={async () => await signIn("saml")}
onClick={samlSignIn}
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-black bg-secondary-50 hover:bg-secondary-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black">
{t("signin_with_saml")}
</button>
@ -236,6 +255,9 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
trpcState: ssr.dehydrate(),
isGoogleLoginEnabled,
isSAMLLoginEnabled,
hostedCal,
samlTenantID,
samlProductID,
},
};
}

View File

@ -561,5 +561,6 @@
"saml_configured_for_provider": "SAML configured for {{provider}}",
"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_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"
}