Skip to content

Commit

Permalink
Implement OTP verification for password reset (#517)
Browse files Browse the repository at this point in the history
  • Loading branch information
VictiniX888 authored Nov 3, 2023
1 parent 79df1f8 commit 9c28eee
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 44 deletions.
4 changes: 4 additions & 0 deletions apps/sso/components/reset-card/reset-email-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useHibiscusSupabase } from '@hibiscus/hibiscus-supabase-context';
import { Button, ColorSpanBold } from '@hibiscus/ui-kit-2023';
import { StyledAuthCard } from '../auth-components/styled-card';
import { Input } from '../auth-components/styled-input';
import { useRouter } from 'next/router';

/* eslint-disable-next-line */
export interface ResetCardProps {}
Expand All @@ -18,6 +19,8 @@ export function ResetEmailCard(props: ResetCardProps) {
const [hideSuccessMessage, setHideSuccessMessage] = useState(false);
const { supabase } = useHibiscusSupabase();

const router = useRouter();

async function handleSubmit(event) {
event.preventDefault();

Expand All @@ -30,6 +33,7 @@ export function ResetEmailCard(props: ResetCardProps) {
alert(error);
} else {
setHideSuccessMessage(true);
router.push(`/reset-verify?email=${email}`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion apps/sso/components/routeGuard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function RouteGuard({ children }) {
'/reset',
'/reset#',
'/reset-email',
'/reset-redirect',
'/reset-verify',
];

const path = url.split('?')[0];
Expand Down
137 changes: 137 additions & 0 deletions apps/sso/components/verify-card/reset-verify-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import styled from 'styled-components';
import { H3, ItalicText, Text } from '@hibiscus/ui';
import { Colors2023 } from '@hibiscus/styles';
import OTPInput from '../otp-input/otp-input';
import { useState } from 'react';
import { useRouter } from 'next/router';
import { HibiscusSupabaseClient } from '@hibiscus/hibiscus-supabase-client';
import Image from 'next/image';
import { MutatingDots } from 'react-loader-spinner';
import { Button } from '@hibiscus/ui-kit-2023';
import { useHibiscusSupabase } from '@hibiscus/hibiscus-supabase-context';

export function ResetVerifyCard() {
const router = useRouter();
const { supabase } = useHibiscusSupabase();
const [verifyState, setVerifyState] = useState('');
const [hideErrorMessage, setHideErrorMessage] = useState(false);
const [code, setCode] = useState('');
const [pinReady, setPinReady] = useState(false);
const MAX_CODE_LENGTH = 6;

const handleOTP = async () => {
const email = String(router.query.email);

const { data, error } = await supabase.verifyOtp(email, code, 'recovery');

if (error) {
console.log(error);
setHideErrorMessage(true);
}
if (data.user) {
setVerifyState('verifying');

HibiscusSupabaseClient.setTokenCookieClientSide(
data.session.access_token,
data.session.refresh_token
);

router.push('/reset');
}
};

const handleKeyDown = (e) => {
//it triggers by pressing the enter key
console.log(e.target.value);
if (e.keyCode === 13) {
handleOTP();
}
};

return (
<StyledVerifyCard>
<Image
src="/static/images/logo-2023.svg"
alt="HackSC Logo"
width={100}
height={100}
/>
<StyledText>
We&apos;ve sent you an email containing a unique 6-digit PIN code.
</StyledText>
<ItalicText>
This email may take up to 2 minutes to arrive. Do not share this code
with anyone else.
</ItalicText>
<OTPInput
setPinReady={setPinReady}
code={code}
setCode={setCode}
maxLength={MAX_CODE_LENGTH}
handleKeyDown={handleKeyDown}
/>
<StyledErrorText style={{ display: hideErrorMessage ? 'block' : 'none' }}>
Token is expired or incorrect.
</StyledErrorText>
<Button
color="blue"
onClick={handleOTP}
disabled={!pinReady}
style={{
opacity: !pinReady ? 0.5 : 1,
cursor: 'pointer',
transitionDuration: '0.5s',
}}
>
SUBMIT
</Button>

<Text>If you did not receive your email, please sign up again</Text>

{verifyState === 'verifying' ? (
<MutatingDots
height="100"
width="100"
color={Colors2023.BLUE.LIGHT}
secondaryColor={Colors2023.BLUE.LIGHT}
radius="12.5"
ariaLabel="mutating-dots-loading"
/>
) : (
''
)}
</StyledVerifyCard>
);
}

export default ResetVerifyCard;

const StyledVerifyCard = styled.div`
min-width: 55vw;
max-width: 90vw;
padding: 5rem 2rem;
display: flex;
flex-direction: column;
margin: auto;
align-items: center;
border-radius: 20px;
border: 5px solid ${Colors2023.BLUE.STANDARD};
box-shadow: 0px 0px 10px ${Colors2023.BLUE.LIGHT};
gap: 15px;
> p {
text-align: center;
}
@media (max-width: 400px) {
padding: 2rem;
}
`;

const StyledText = styled(H3)`
text-align: center;
`;

const StyledErrorText = styled(Text)`
font-size: 20px;
padding-top: 1rem;
color: red;
`;
2 changes: 1 addition & 1 deletion apps/sso/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const REGISTERED_PATHS = new Set([
'login',
'reset',
'reset-email',
'reset-redirect',
'reset-verify',
'signup',
'verify',
'logout',
Expand Down
42 changes: 0 additions & 42 deletions apps/sso/pages/reset-redirect/index.tsx

This file was deleted.

24 changes: 24 additions & 0 deletions apps/sso/pages/reset-verify/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import styled from 'styled-components';
import Head from 'next/head';
import { getWebTitle } from '@hibiscus/metadata';
import ResetVerifyCard from '../../components/verify-card/reset-verify-card';

export function Index() {
return (
<MainPageWrapper>
<Head>
<title>{getWebTitle('Reset your password')}</title>
</Head>

<ResetVerifyCard />
</MainPageWrapper>
);
}
export default Index;

const MainPageWrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100vh;
`;

7 comments on commit 9c28eee

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

pointr – ./

pointr.vercel.app
www.hack.sc
pointr-git-main-hacksc.vercel.app
pointr-hacksc.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

interim – ./

interim-hacksc.vercel.app
interim-git-main-hacksc.vercel.app
www.socalhacks.org
socalhacks.org

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

recruitment – ./

recruitment-git-main-hacksc.vercel.app
recruitment-hacksc.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

www-2023 – ./

www-2023-hacksc.vercel.app
2023.hacksc.com
www-2023-git-main-hacksc.vercel.app
www-2023.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

sso – ./

sso-steel.vercel.app
sso-hacksc.vercel.app
sso-git-main-hacksc.vercel.app
sso.hacksc.com

@vercel
Copy link

@vercel vercel bot commented on 9c28eee Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.