Skip to content

Commit

Permalink
Fix type errors
Browse files Browse the repository at this point in the history
  • Loading branch information
nicole-stytch committed Mar 8, 2024
1 parent c971918 commit b790d03
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 85 deletions.
20 changes: 10 additions & 10 deletions components/LoginDiscoveryForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ const ContinueToTenantForm = ({ onBack }: { onBack: () => void }) => {
<div>
<h1>Log into a specific Organization</h1>
<p>
Provide the slug of the Organization that you&apos;d like to log into below,
and you&apos;ll be redirected to the Organization&apos;s unique login URL. Note
that you can also navigate directly to your Organization&apos;s unique login
URL, if you know it.
Provide the slug of the Organization that you&apos;d like to log into
below, and you&apos;ll be redirected to the Organization&apos;s unique
login URL. Note that you can also navigate directly to your
Organization&apos;s unique login URL, if you know it.
</p>
<form onSubmit={onSubmit}>
<input
Expand Down Expand Up @@ -61,10 +61,10 @@ const LoginDiscoveryForm = ({ domain }: Props) => {
<EmailLoginForm title="Log in or sign up" onSubmit={discoveryStart}>
<p>
Once you complete one of the below authentication methods (Email
Magic Links or OAuth), you&apos;ll be able to view which Organizations
you have access to and choose which one you&apos;d like to log into. If
you don&apos;t currently have access to any Organizations, you&apos;ll be able
to create one.
Magic Links or OAuth), you&apos;ll be able to view which
Organizations you have access to and choose which one you&apos;d
like to log into. If you don&apos;t currently have access to any
Organizations, you&apos;ll be able to create one.
</p>
<p>
We refer to this as the Discovery flow, since the user authenticates
Expand All @@ -91,8 +91,8 @@ const LoginDiscoveryForm = ({ domain }: Props) => {
/>
<br></br>
<p>
If you already know the slug of the Organization that you&apos;d like to
log into,&nbsp;
If you already know the slug of the Organization that you&apos;d like
to log into,&nbsp;
<Link href="" onClick={() => setIsDiscovery(false)}>
click here
</Link>
Expand Down
6 changes: 3 additions & 3 deletions components/MembersCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const isValidEmail = (emailValue: string) => {
return regex.test(emailValue);
};

const isAdmin = (member: Member) => !!member.trusted_metadata.admin;
const isAdmin = (member: Member) => !!member.trusted_metadata?.admin;

const MemberRow = ({
member,
Expand Down Expand Up @@ -137,8 +137,8 @@ const MembersCard = ({
<h1>Members</h1>
<p>
You&apos;re currently logged in as&nbsp;
<span className="code">{currentUser.email_address}</span>. Below, you&apos;ll
find a full list of Members who belong to&nbsp;
<span className="code">{currentUser.email_address}</span>. Below,
you&apos;ll find a full list of Members who belong to&nbsp;
{organization.organization_name}:
</p>
<MemberList
Expand Down
7 changes: 6 additions & 1 deletion components/OrganizationCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import Link from "next/link";
import CodeBlock from "./common/CodeBlock";
import { Organization } from "@/lib/loadStytch";

const OrganizationCard = ({ organization }) => {
type Props = {
organization: Organization;
};

const OrganizationCard = ({ organization }: Pick<Props, "organization">) => {
return (
<div className="card profile-card">
<div className="section">
Expand Down
4 changes: 2 additions & 2 deletions components/SMSSendForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const SMSSendForm = ({ memberID, orgID }: SMSProps) => {
return (
<div>
<p>
Enter your phone number below. You&apos;ll receive an SMS with a one-time
login code.
Enter your phone number below. You&apos;ll receive an SMS with a
one-time login code.
</p>
<form method="POST" action="/api/smsmfa/send" className="row">
<input type={"text"} placeholder={`+18005551234`} name="phone_number" />
Expand Down
18 changes: 9 additions & 9 deletions components/SSOCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const SSO_METHOD = {
OIDC: "OIDC",
};

const isAdmin = (member: Member) => !!member.trusted_metadata.admin;
const isAdmin = (member: Member) => !!member.trusted_metadata?.admin;

const IDPList = ({
currentUser,
Expand Down Expand Up @@ -65,15 +65,15 @@ const IDPList = ({
{saml_connections.length === 0 && <p>No connections configured.</p>}
<ul>
{saml_connections.map((conn) => (
<li key={conn.connection_id}>
<li key={conn?.connection_id}>
<Link
href={`/${router.query.slug}/dashboard/saml/${conn.connection_id}`}
href={`/${router.query.slug}/dashboard/saml/${conn?.connection_id}`}
>
<button className="primary small">Edit</button>
</Link>
<span>
&nbsp;<span className="code">{conn.display_name}</span> (
{conn.status})&nbsp;
&nbsp;<span className="code">{conn?.display_name}</span> (
{conn?.status})&nbsp;
</span>
</li>
))}
Expand All @@ -84,15 +84,15 @@ const IDPList = ({
{oidc_connections.length === 0 && <p>No connections configured.</p>}
<ul>
{oidc_connections.map((conn) => (
<li key={conn.connection_id}>
<li key={conn?.connection_id}>
<Link
href={`/${router.query.slug}/dashboard/oidc/${conn.connection_id}`}
href={`/${router.query.slug}/dashboard/oidc/${conn?.connection_id}`}
>
<button className="primary small">Edit</button>
</Link>
<span>
&nbsp;<span className="code">{conn.display_name}</span> (
{conn.status})
&nbsp;<span className="code">{conn?.display_name}</span> (
{conn?.status})
</span>
</li>
))}
Expand Down
4 changes: 2 additions & 2 deletions lib/loadStytch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ export type SessionsAuthenticateResponse = Awaited<
ReturnType<typeof client.sessions.authenticate>
>;
export type SAMLConnection = Awaited<
ReturnType<typeof client.sso.saml.create>
ReturnType<typeof client.sso.saml.createConnection>
>["connection"];

export type OIDCConnection = Awaited<
ReturnType<typeof client.sso.oidc.create>
ReturnType<typeof client.sso.oidc.createConnection>
>["connection"];

export type DiscoveredOrganizations = Awaited<
Expand Down
3 changes: 2 additions & 1 deletion pages/[slug]/dashboard/oidc/[connection_id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { findByID } from "@/lib/orgService";
import { FormEventHandler } from "react";
import { updateOidcSSOConn } from "@/lib/api";
import { useRouter } from "next/router";
import { formatSSOStartURL, OIDCConnection } from "@/lib/loadStytch";
import { formatSSOStartURL } from "@/lib/loadStytch";
import { OIDCConnection } from "stytch";
import { useAuth, withSession } from "@/lib/sessionService";
import Link from "next/link";
import { list } from "@/lib/ssoService";
Expand Down
9 changes: 5 additions & 4 deletions pages/[slug]/dashboard/saml/[connection_id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { findByID } from "@/lib/orgService";
import { FormEventHandler } from "react";
import { updateSamlSSOConn } from "@/lib/api";
import { useRouter } from "next/router";
import { formatSSOStartURL, SAMLConnection } from "@/lib/loadStytch";
import { formatSSOStartURL } from "@/lib/loadStytch";
import { SAMLConnection } from "stytch";
import { useAuth, withSession } from "@/lib/sessionService";
import Link from "next/link";
import { list } from "@/lib/ssoService";
Expand Down Expand Up @@ -79,21 +80,21 @@ function ConnectionEditPage({ connection, domain }: Props) {
type="text"
name="email_attribute"
placeholder="NameID"
defaultValue={connection.attribute_mapping["email"]}
defaultValue={connection.attribute_mapping?.email}
/>
<label htmlFor="first_name_attribute">First Name Attribute</label>
<input
type="text"
name="first_name_attribute"
placeholder="firstName"
defaultValue={connection.attribute_mapping["first_name"]}
defaultValue={connection.attribute_mapping?.first_name}
/>
<label htmlFor="last_name_attribute">Last Name Attribute</label>
<input
type="text"
name="last_name_attribute"
placeholder="lastName"
defaultValue={connection.attribute_mapping["last_name"]}
defaultValue={connection.attribute_mapping?.last_name}
/>
<label htmlFor="certificate">Signing Certificate</label>
<textarea
Expand Down
2 changes: 1 addition & 1 deletion pages/api/discovery/[orgId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function redirectToSMSMFA(
res: NextApiResponse,
organization: Organization,
member: Member,
mfa_required: MfaRequired | null
mfa_required: MfaRequired | undefined
) {
if (
mfa_required != null &&
Expand Down
69 changes: 36 additions & 33 deletions pages/api/discovery/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,47 +40,50 @@ export async function handler(
organization_name: organization_name,
session_duration_minutes: SESSION_DURATION_MINUTES,
mfa_policy: require_mfa ? "REQUIRED_FOR_ALL" : "OPTIONAL",
organization_slug: organization_name.toLowerCase().replace(/\s/g, ""),
});

// Make the organization discoverable to other emails
try {
await stytchClient.organizations.update({
if (organization) {
try {
await stytchClient.organizations.update({
organization_id: organization.organization_id,
email_jit_provisioning: "RESTRICTED",
sso_jit_provisioning: "ALL_ALLOWED",
email_allowed_domains: [toDomain(member.email_address)],
});
} catch (e) {
if (
e instanceof StytchError &&
e.error_type == "organization_settings_domain_too_common"
) {
console.log(
"User domain is common email provider, cannot link to organization"
);
} else {
throw e;
}
}

// Mark the first user in the organization as the admin
await stytchClient.organizations.members.update({
organization_id: organization.organization_id,
email_jit_provisioning: "RESTRICTED",
sso_jit_provisioning: "ALL_ALLOWED",
email_allowed_domains: [toDomain(member.email_address)],
member_id: member.member_id,
trusted_metadata: { admin: true },
});
} catch (e) {
if (
e instanceof StytchError &&
e.error_type == "organization_settings_domain_too_common"
) {
console.log(
"User domain is common email provider, cannot link to organization"

if (session_jwt === "") {
setIntermediateSession(req, res, intermediate_session_token);
clearSession(req, res);
return res.redirect(
302,
`/${organization.organization_slug}/smsmfa?sent=false&org_id=${organization.organization_id}&member_id=${member.member_id}`
);
} else {
throw e;
}
clearIntermediateSession(req, res);
setSession(req, res, session_jwt);
return res.redirect(307, `/${organization.organization_slug}/dashboard`);
}

// Mark the first user in the organization as the admin
await stytchClient.organizations.members.update({
organization_id: organization.organization_id,
member_id: member.member_id,
trusted_metadata: { admin: true },
});

if (session_jwt === "") {
setIntermediateSession(req, res, intermediate_session_token);
clearSession(req, res);
return res.redirect(
302,
`/${organization.organization_slug}/smsmfa?sent=false&org_id=${organization.organization_id}&member_id=${member.member_id}`
);
}
clearIntermediateSession(req, res);
setSession(req, res, session_jwt);
return res.redirect(307, `/${organization.organization_slug}/dashboard`);
} catch (error) {
const errorString = JSON.stringify(error);
console.log(error);
Expand Down
2 changes: 1 addition & 1 deletion pages/api/sso/oidc/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function handler(
);
console.log(
"Successfully created new OIDC connection",
connection.connection_id
connection?.connection_id
);
return res.status(200).json(connection);
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion pages/api/sso/oidc/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async function handler(
jwks_url,
} = JSON.parse(req.body);

await loadStytch().sso.oidc.update({
await loadStytch().sso.oidc.updateConnection({
organization_id: member.organization_id,
connection_id,
display_name: display_name,
Expand Down
2 changes: 1 addition & 1 deletion pages/api/sso/saml/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function handler(
);
console.log(
"Successfully created new SAML connection",
connection.connection_id
connection?.connection_id
);
return res.status(200).json(connection);
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion pages/api/sso/saml/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async function handler(
certificate,
connection_id,
} = JSON.parse(req.body);
await loadStytch().sso.saml.update({
await loadStytch().sso.saml.updateConnection({
organization_id: member.organization_id,
connection_id,
idp_entity_id: idp_entity_id,
Expand Down
22 changes: 11 additions & 11 deletions pages/discovery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@ const DiscoveredOrganizationsList = ({ discovered_organizations }: Props) => {
membership,
organization,
}: Pick<DiscoveredOrganizations[0], "membership" | "organization">) => {
if (membership.type === "pending_member") {
return `Join ${organization.organization_name}`;
if (membership?.type === "pending_member") {
return `Join ${organization?.organization_name}`;
}
if (membership.type === "eligible_to_join_by_email_domain") {
return `Join ${organization.organization_name}`;
if (membership?.type === "eligible_to_join_by_email_domain") {
return `Join ${organization?.organization_name}`;
}
if (membership.type === "invited_member") {
return `Accept invitation to ${organization.organization_name}`;
if (membership?.type === "invited_member") {
return `Accept invitation to ${organization?.organization_name}`;
}
return `Log into ${organization.organization_name}`;
return `Log into ${organization?.organization_name}`;
};

return (
<div className="section">
<h1>Select an Organization</h1>
<p>
Below, you&apos;ll find a list of Organizations that you can access. Select
the Organization that you&apos;d like to log into.
Below, you&apos;ll find a list of Organizations that you can access.
Select the Organization that you&apos;d like to log into.
</p>
{discovered_organizations.length === 0 && (
<p>No existing organizations.</p>
)}
<ul>
{discovered_organizations.map(({ organization, membership }) => (
<li key={organization.organization_id}>
<Link href={`/api/discovery/${organization.organization_id}`}>
<li key={organization?.organization_id}>
<Link href={`/api/discovery/${organization?.organization_id}`}>
<span>{formatMembership({ organization, membership })}</span>
</Link>
</li>
Expand Down
8 changes: 4 additions & 4 deletions pages/orgswitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ const OrgSwitcherList = ({ discovered_organizations, user }: Props) => {
</p>
<ul>
{discovered_organizations.map(({ organization }) => (
<li key={organization.organization_id}>
<Link href={`/api/discovery/${organization.organization_id}`}>
<span>{organization.organization_name}</span>
{organization.organization_id === user.organization_id && (
<li key={organization?.organization_id}>
<Link href={`/api/discovery/${organization?.organization_id}`}>
<span>{organization?.organization_name}</span>
{organization?.organization_id === user.organization_id && (
<span>&nbsp;(Active)</span>
)}
</Link>
Expand Down

0 comments on commit b790d03

Please sign in to comment.