Skip to content

Verify email #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import NotFoundPage from './pages/404Page';

import ProjectPage from './pages/ProjectsPage/index';
import JoinTeamsPage from './pages/Competitions/CompetitionTeamPages/JoinTeamsPage';
import VerifyEmailPage from './pages/Auth/VerifyEmail';

let cookie = getCookie(COOKIE_NAME);

Expand Down
52 changes: 45 additions & 7 deletions src/actions/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { setCookie, deleteCookie } from '../utils/cookie';
import { User } from '../UserContext';
import { COMPETITIONS_COOKIE_NAME, COOKIE_NAME } from '../configs';

interface RegisterResponse {
msg: string;
id: string;
}

export const resetPassword = async (data: {
username: string;
userID: string;
code: string;
password: string;
}) => {
Expand All @@ -18,7 +23,7 @@ export const resetPassword = async (data: {
.post(
process.env.REACT_APP_API +
'/v1/users/' +
data.username +
data.userID +
'/resetpassword',
body
)
Expand All @@ -27,11 +32,29 @@ export const resetPassword = async (data: {
})
.catch((error) => {
message.error('Reset Failed');
console.log(error);
message.error(error.response.data.error.message);
reject(error);
});
});
};

export const verifyEmail = async (data: { code: string, id : string}) => {
return new Promise((resolve, reject) => {
axios
.post(process.env.REACT_APP_API + '/v1/users/verifyEmail', data)
.then((res: AxiosResponse) => {
resolve(res);
})
.catch((error) => {
message.error('Verification Failed');
message.error('Please check your code and expiration time');
reject(error);
});
});
}


export const requestReset = async (username: string) => {
return new Promise((resolve, reject) => {
axios
Expand All @@ -43,7 +66,8 @@ export const requestReset = async (username: string) => {
})
.catch((error) => {
message.error('Request Failed');
//reject(error);
message.error(error.response.data.error.message);
reject(error);
});
});
};
Expand All @@ -59,16 +83,16 @@ export const registerUser = async (data: {
email: data.email,
isUCSD: data.isUCSD,
};
return new Promise((resolve, reject) => {
return new Promise<RegisterResponse>((resolve, reject) => {
axios
.post(process.env.REACT_APP_API + '/v1/users', body)
.then((res: AxiosResponse) => {
resolve(res);
resolve(res.data);
})
.catch((error) => {
//message.error(error.response.data.error.message);
message.error(error.response.data.error.message);
console.error(error);
//reject(error);
reject(error);
});
});
};
Expand Down Expand Up @@ -123,6 +147,20 @@ export const loginUser = async (
})
.catch((error) => {
message.error(error.response.data.error.message);
console.error(error);
if (error.response.data.error.message === 'User not verified') {

axios
.get(process.env.REACT_APP_API + '/v1/users/' + data.username + '/verifyEmail' )
.then((res: AxiosResponse) => {
resolve(res.data.token);
})
.catch((error) => {
reject(error);
});

message.error("Check your email to verify");
}
//reject(error);
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Auth/ForgotPassword/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function ForgotPasswordPage({ location }: RouteComponentProps) {
let queries = query.parse(location.search);

let body = {
username: String(queries['username']),
userID: String(queries['username']), // Update the property name to 'userID'
code: String(queries['?code']),
password: values['password'],
};
Expand Down Expand Up @@ -117,4 +117,4 @@ function handlePasswordErrors(errors: any) {
}
}
}
export default ForgotPasswordPage;
export default ForgotPasswordPage;
13 changes: 10 additions & 3 deletions src/pages/Auth/LoginPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ function LoginPage() {
// setRegisterStep('processing');

loginUser(DIMENSION_ID, values).then((res: any) => {
setUser(getUserFromToken(res));
message.success('Logged in!');
window.location.href = '/';
if (res) {
// Now we know that user has successfully logged in or verified
setUser(getUserFromToken(res));
message.success('Logged in!');

// Only redirect after verification is done (if the user was already verified)
window.location.href = '/'; // Or use a different page based on your app flow
}
}).catch((error) => {
message.error(error.response.data.error.message);
});
};

Expand Down
3 changes: 2 additions & 1 deletion src/pages/Auth/RegisterPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ function RegisterPage() {
handlePasswordErrors(errors);
}
registerUser({ ...values, isUCSD: checked, admin: isAdmin }).then((res) => {
message.success('Please check your email to verify your account');
message.success(isAdmin ?
'Admin registered! Redirecting to login page' :
'Registered! Redirecting to login page');
history.push('/login');
history.push('/verify/?id=' + res.id);
});
};
const onCheckChange = (e: any) => {
Expand Down
82 changes: 82 additions & 0 deletions src/pages/Auth/VerifyEmail/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@import '../../../newStyles/text.less';
@import '../../../newStyles/components.less';
@import '../../../newStyles/variables.less';

.VerifyEmailPage {

.noContainer();

display: flex;
justify-content: center;
align-items: center;

.VerifyDetails {
.generic-centered-section();
.constrained-bounds();

.VerifyHeader {
margin-top: 4rem;
width: 60%;
max-width: @max-width2;
text-align: center;
@media only screen and (max-width: @xxs) {
width: 90%;
}

}

form {
margin-top: 3rem;
width: 60%;
max-width: @max-width1;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;

@media only screen and (max-width: @xxs) {
width: 90%;
}
Input {
line-height: 2.5rem ;
font-size: @font3;

}

#VerifyButton {
width: 100%;
height: 45px;
.button-black-square();
margin: auto;
}

}
}


.loginLink {
margin-top: @margin-base2;
text-align: center;
}
}


/*
.LoginPage {

.danger {
color: @danger;
}
.loginButton {
margin-top: @margin-base;
}
.loginCard {
margin: auto;
.smack-center();
max-width: 90%;
}
.register-info {
margin-top: 12px;
}
}
*/
84 changes: 84 additions & 0 deletions src/pages/Auth/VerifyEmail/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useEffect, useState } from 'react';
import './index.less';
import DefaultLayout from '../../../components/layouts/default';
import { Form, Input, message, Button, Layout } from 'antd';
import { Link, useHistory } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import { verifyEmail } from '../../../actions/auth';

const { Content } = Layout;

const VerifyEmailPage = () => {
const { handleSubmit, control, formState: { errors } } = useForm();
const history = useHistory();


const onSubmit = (values: any) => {

const queries = new URLSearchParams(window.location.search);
const id = queries.get('id');
if (!id) {
message.error('Invalid verification link');
return;
}

let body = {
code: values.code,
id: id,
};


verifyEmail(body).then((res) => {
message.success('Email Verified! Redirecting to login page');
history.push('/login'); // Redirect to login page
});
};

return (
<DefaultLayout>
<div className="VerifyEmailPage">
<Content className="VerifyDetails">
<div className="VerifyHeader">
<h2>Verify Email</h2>
<h4>Enter the verification code sent to your email</h4>
</div>

<form onSubmit={handleSubmit(onSubmit)}>
<Controller
render={({ field }) => (
<Form.Item style={{ marginBottom: '12px' }}>
<Input
{...field} // Ensure field props are spread
size="large"
autoComplete="off"
type="text"
placeholder="Verification Code"
name="code"
allowClear={true}
/>
</Form.Item>
)}
name="code"
control={control}
rules={{ required: true }}
/>

<Button htmlType="submit" size="large" id="VerifyButton">
<p>Verify</p>
</Button>
</form>

<div className="loginLink">
<Link to="./login">
<p className="option">Back to Login</p>
</Link>
</div>
</Content>
</div>
</DefaultLayout>
);
};

export default VerifyEmailPage;