Fix: Formatting and support for selecting org (line 109-122)

This commit is contained in:
Daniel Hougaard
2024-03-17 18:49:29 +01:00
parent b9986be387
commit e4dba6d5c8
@@ -1,8 +1,8 @@
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router" import { useRouter } from "next/router";
import axios from "axios" import axios from "axios";
import jwt_decode from "jwt-decode"; import jwt_decode from "jwt-decode";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
@@ -10,9 +10,10 @@ import attemptCliLogin from "@app/components/utilities/attemptCliLogin";
import attemptLogin from "@app/components/utilities/attemptLogin"; import attemptLogin from "@app/components/utilities/attemptLogin";
import { Button, Input } from "@app/components/v2"; import { Button, Input } from "@app/components/v2";
import { useUpdateUserAuthMethods } from "@app/hooks/api"; import { useUpdateUserAuthMethods } from "@app/hooks/api";
import { fetchOrganizations } from "@app/hooks/api/organization/queries";
import { fetchUserDetails } from "@app/hooks/api/users/queries"; import { fetchUserDetails } from "@app/hooks/api/users/queries";
import { navigateUserToOrg } from "../../Login.utils"; import { navigateUserToOrg, navigateUserToSelectOrg } from "../../Login.utils";
type Props = { type Props = {
providerAuthToken: string; providerAuthToken: string;
@@ -20,14 +21,14 @@ type Props = {
password: string; password: string;
setPassword: (password: string) => void; setPassword: (password: string) => void;
setStep: (step: number) => void; setStep: (step: number) => void;
} };
export const PasswordStep = ({ export const PasswordStep = ({
providerAuthToken, providerAuthToken,
email, email,
password, password,
setPassword, setPassword,
setStep, setStep
}: Props) => { }: Props) => {
const { createNotification } = useNotificationContext(); const { createNotification } = useNotificationContext();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@@ -35,15 +36,12 @@ export const PasswordStep = ({
const router = useRouter(); const router = useRouter();
const { mutateAsync } = useUpdateUserAuthMethods(); const { mutateAsync } = useUpdateUserAuthMethods();
const { const { callbackPort, isLinkingRequired, authMethod, organizationId } = jwt_decode(
callbackPort, providerAuthToken
isLinkingRequired, ) as any;
authMethod,
organizationId
} = jwt_decode(providerAuthToken) as any;
const handleLogin = async (e: React.FormEvent) => { const handleLogin = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault();
try { try {
setIsLoading(true); setIsLoading(true);
@@ -53,10 +51,9 @@ export const PasswordStep = ({
email, email,
password, password,
providerAuthToken providerAuthToken
}) });
if (isCliLoginSuccessful && isCliLoginSuccessful.success) { if (isCliLoginSuccessful && isCliLoginSuccessful.success) {
if (isCliLoginSuccessful.mfaEnabled) { if (isCliLoginSuccessful.mfaEnabled) {
// case: login requires MFA step // case: login requires MFA step
setStep(2); setStep(2);
@@ -64,11 +61,11 @@ export const PasswordStep = ({
return; return;
} }
// case: login was successful // case: login was successful
const cliUrl = `http://127.0.0.1:${callbackPort}/` const cliUrl = `http://127.0.0.1:${callbackPort}/`;
// send request to server endpoint // send request to server endpoint
const instance = axios.create() const instance = axios.create();
await instance.post(cliUrl, { ...isCliLoginSuccessful.loginResponse }) await instance.post(cliUrl, { ...isCliLoginSuccessful.loginResponse });
// cli page // cli page
router.push("/cli-redirect"); router.push("/cli-redirect");
@@ -79,7 +76,7 @@ export const PasswordStep = ({
const loginAttempt = await attemptLogin({ const loginAttempt = await attemptLogin({
email, email,
password, password,
providerAuthToken, providerAuthToken
}); });
if (loginAttempt && loginAttempt.success) { if (loginAttempt && loginAttempt.success) {
@@ -102,14 +99,28 @@ export const PasswordStep = ({
if (isLinkingRequired) { if (isLinkingRequired) {
const user = await fetchUserDetails(); const user = await fetchUserDetails();
const newAuthMethods = [...user.authMethods, authMethod] const newAuthMethods = [...user.authMethods, authMethod];
await mutateAsync({ await mutateAsync({
authMethods: newAuthMethods authMethods: newAuthMethods
}); });
} }
// case: organization ID is present from the provider auth token -- navigate directly to the org
if (organizationId) {
await navigateUserToOrg(router, organizationId); await navigateUserToOrg(router, organizationId);
} }
// case: no organization ID is present -- navigate to the select org page IF the user has any orgs
// if the user has no orgs, navigate to the create org page
else {
const userOrgs = await fetchOrganizations();
if (userOrgs.length > 0) {
navigateUserToSelectOrg(router);
} else {
await navigateUserToOrg(router);
}
}
}
} }
} catch (err) { } catch (err) {
setIsLoading(false); setIsLoading(false);
@@ -122,24 +133,22 @@ export const PasswordStep = ({
}; };
return ( return (
<form <form onSubmit={handleLogin} className="mx-auto h-full w-full max-w-md px-6 pt-8">
onSubmit={handleLogin}
className="h-full mx-auto w-full max-w-md px-6 pt-8"
>
<div className="mb-8"> <div className="mb-8">
<p className="mx-auto flex w-max justify-center text-xl font-medium text-transparent bg-clip-text bg-gradient-to-b from-white to-bunker-200 text-center mb-4"> <p className="mx-auto mb-4 flex w-max justify-center bg-gradient-to-b from-white to-bunker-200 bg-clip-text text-center text-xl font-medium text-transparent">
{isLinkingRequired ? "Link your account" : "What's your Infisical password?"} {isLinkingRequired ? "Link your account" : "What's your Infisical password?"}
</p> </p>
{isLinkingRequired && ( {isLinkingRequired && (
<div className="text-bunker-400 text-xs flex flex-col items-center w-max mx-auto"> <div className="mx-auto flex w-max flex-col items-center text-xs text-bunker-400">
<span className='duration-200 max-w-sm text-center px-4'> <span className="max-w-sm px-4 text-center duration-200">
An existing account without this SSO authentication method enabled was found under the same email. Login with your password to link the account. An existing account without this SSO authentication method enabled was found under the
same email. Login with your password to link the account.
</span> </span>
</div> </div>
)} )}
</div> </div>
<div className="relative flex items-center justify-center lg:w-1/6 w-1/4 min-w-[22rem] mx-auto w-full rounded-lg max-h-24 md:max-h-28"> <div className="relative mx-auto flex max-h-24 w-1/4 w-full min-w-[22rem] items-center justify-center rounded-lg md:max-h-28 lg:w-1/6">
<div className="flex items-center justify-center w-full rounded-lg max-h-24 md:max-h-28"> <div className="flex max-h-24 w-full items-center justify-center rounded-lg md:max-h-28">
<Input <Input
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
@@ -152,7 +161,7 @@ export const PasswordStep = ({
/> />
</div> </div>
</div> </div>
<div className='lg:w-1/6 w-1/4 w-full mx-auto flex items-center justify-center min-w-[22rem] text-center rounded-md mt-4'> <div className="mx-auto mt-4 flex w-1/4 w-full min-w-[22rem] items-center justify-center rounded-md text-center lg:w-1/6">
<Button <Button
type="submit" type="submit"
colorSchema="primary" colorSchema="primary"
@@ -164,12 +173,15 @@ export const PasswordStep = ({
{t("login.login")} {t("login.login")}
</Button> </Button>
</div> </div>
<div className="text-bunker-400 text-xs flex flex-col items-center w-max mx-auto mt-4"> <div className="mx-auto mt-4 flex w-max flex-col items-center text-xs text-bunker-400">
<span className='duration-200 max-w-sm text-center px-4'> <span className="max-w-sm px-4 text-center duration-200">
Infisical Master Password serves as a decryption mechanism so that even Google is not able to access your secrets. Infisical Master Password serves as a decryption mechanism so that even Google is not able
to access your secrets.
</span> </span>
<Link href="/verify-email"> <Link href="/verify-email">
<span className='hover:underline mt-2 hover:underline-offset-4 hover:decoration-primary-700 hover:text-bunker-200 duration-200 cursor-pointer'>{t("login.forgot-password")}</span> <span className="mt-2 cursor-pointer duration-200 hover:text-bunker-200 hover:underline hover:decoration-primary-700 hover:underline-offset-4">
{t("login.forgot-password")}
</span>
</Link> </Link>
</div> </div>
<div className="flex flex-row items-center justify-center"> <div className="flex flex-row items-center justify-center">
@@ -178,11 +190,11 @@ export const PasswordStep = ({
router.push("/login"); router.push("/login");
}} }}
type="button" type="button"
className="text-bunker-400 text-xs hover:underline mt-2 hover:underline-offset-4 hover:decoration-primary-700 hover:text-bunker-200 duration-200 cursor-pointer" className="mt-2 cursor-pointer text-xs text-bunker-400 duration-200 hover:text-bunker-200 hover:underline hover:decoration-primary-700 hover:underline-offset-4"
> >
{t("login.other-option")} {t("login.other-option")}
</button> </button>
</div> </div>
</form> </form>
); );
} };