fix mail service

This commit is contained in:
Simon Larsen 2022-11-11 20:13:35 +00:00
parent addfc9d69c
commit a0fc136870
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
7 changed files with 203 additions and 158 deletions

View File

@ -38,21 +38,34 @@ const RegisterPage: FunctionComponent = () => {
<h5 className="mb-0">
Reset Password.
</h5>
{!isSuccess && <p className="text-muted mt-2 mb-0">
Please enter your new password and we will have it updated.{' '}
</p>}
{isSuccess && <p className="text-muted mt-2 mb-0">
Your password has been updated. Please log in.
</p>}
{!isSuccess && (
<p className="text-muted mt-2 mb-0">
Please enter your new
password and we will have it
updated.{' '}
</p>
)}
{isSuccess && (
<p className="text-muted mt-2 mb-0">
Your password has been
updated. Please log in.
</p>
)}
</div>
{!isSuccess && <ModelForm<User>
{!isSuccess && (
<ModelForm<User>
modelType={User}
id="register-form"
onBeforeCreate={(item: User) => {
item.resetPasswordToken = Navigation.getLastParam()?.toString().replace("/", "").toString() ||''
onBeforeCreate={(
item: User
) => {
item.resetPasswordToken =
Navigation.getLastParam()
?.toString()
.replace('/', '')
.toString() || '';
return item;
}}
showAsColumns={1}
@ -62,7 +75,6 @@ const RegisterPage: FunctionComponent = () => {
confirmPassword: '',
}}
fields={[
{
field: {
password: true,
@ -72,7 +84,8 @@ const RegisterPage: FunctionComponent = () => {
validation: {
minLength: 6,
},
placeholder: 'New Password',
placeholder:
'New Password',
title: 'New Password',
required: true,
},
@ -97,11 +110,14 @@ const RegisterPage: FunctionComponent = () => {
]}
apiUrl={apiUrl}
formType={FormType.Create}
submitButtonText={'Reset Password'}
submitButtonText={
'Reset Password'
}
onSuccess={() => {
setIsSuccess(true);
}}
/>}
/>
)}
<div className="mt-5 text-center">
<p className="text-muted mb-0">

View File

@ -4,7 +4,7 @@ import OneUptimeLogo from 'CommonUI/src/Images/logos/OneUptimePNG/7.png';
import Link from 'CommonUI/src/Components/Link/Link';
import PageLoader from 'CommonUI/src/Components/Loader/PageLoader';
import ModelAPI from 'CommonUI/src/Utils/ModelAPI/ModelAPI';
import EmailVerificationToken from "Model/Models/EmailVerificationToken"
import EmailVerificationToken from 'Model/Models/EmailVerificationToken';
import { VERIFY_EMAIL_API_URL } from '../Utils/ApiPaths';
import { FormType } from 'CommonUI/src/Components/Forms/ModelForm';
import Navigation from 'CommonUI/src/Utils/Navigation';
@ -17,16 +17,18 @@ const VerifyEmail: FunctionComponent = () => {
const [error, setError] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(true);
const init = async (): Promise<void> => {
const init: Function = async (): Promise<void> => {
// Ping an API here.
setError('');
setIsLoading(true);
try {
// strip data.
const emailverificationToken = new EmailVerificationToken();
emailverificationToken.token = new ObjectID(Navigation.getLastParam()?.toString().replace('/', '') || '');
const emailverificationToken: EmailVerificationToken =
new EmailVerificationToken();
emailverificationToken.token = new ObjectID(
Navigation.getLastParam()?.toString().replace('/', '') || ''
);
await ModelAPI.createOrUpdate<EmailVerificationToken>(
emailverificationToken,
@ -36,8 +38,6 @@ const VerifyEmail: FunctionComponent = () => {
{},
{}
);
} catch (err) {
setError(
(err as HTTPErrorResponse).message ||
@ -46,14 +46,16 @@ const VerifyEmail: FunctionComponent = () => {
}
setIsLoading(false);
}
};
useEffect(() => {
init();
}, [])
init().catch((err: Error) => {
setError(err.toString());
});
}, []);
if (isLoading) {
return <PageLoader isVisible={true} />
return <PageLoader isVisible={true} />;
}
return (
@ -76,7 +78,8 @@ const VerifyEmail: FunctionComponent = () => {
src={`/accounts/public/${OneUptimeLogo}`}
/>
</div>
{!error && <div className="text-center">
{!error && (
<div className="text-center">
<h5 className="mb-0">
Your email is verified.
</h5>
@ -85,16 +88,19 @@ const VerifyEmail: FunctionComponent = () => {
email. You can now log in to
OneUptime.{' '}
</p>
</div>}
</div>
)}
{error && <div className="text-center">
{error && (
<div className="text-center">
<h5 className="mb-0">
Sorry, something went wrong!
</h5>
<p className="text-muted mt-2 mb-0">
{error}
</p>
</div>}
</div>
)}
<div className="mt-5 text-center">
<p className="text-muted mb-0">

View File

@ -116,8 +116,6 @@ class DatabaseService<TBaseModel extends BaseModel> {
protected checkRequiredFields(data: TBaseModel): void {
// Check required fields.
console.log(data);
const relatationalColumns: Dictionary<string> = {};
const tableColumns: Array<string> = data.getTableColumns().columns;
@ -143,11 +141,15 @@ class DatabaseService<TBaseModel extends BaseModel> {
!(data as any)[requiredField] &&
!data.isDefaultValueColumn(requiredField)
) {
const metadata: TableColumnMetadata =
data.getTableColumnMetadata(requiredField);
if (metadata && metadata.manyToOneRelationColumn && metadata.type === TableColumnType.Entity && data.getColumnValue(metadata.manyToOneRelationColumn)) {
if (
metadata &&
metadata.manyToOneRelationColumn &&
metadata.type === TableColumnType.Entity &&
data.getColumnValue(metadata.manyToOneRelationColumn)
) {
continue;
}

View File

@ -16,7 +16,7 @@ export default class MailService {
const body: JSONObject = {
...mail,
clusterKey: ClusterKey.toString(),
toEmail: mail.toEmail.toString()
toEmail: mail.toEmail.toString(),
};
if (mailServer) {

View File

@ -56,7 +56,6 @@ router.post(
user.isEmailVerified = false;
}
const alreadySavedUser: User | null = await UserService.findOneBy({
query: { email: user.email! },
select: {
@ -99,20 +98,19 @@ router.post(
});
}
console.log(savedUser);
const generatedToken: ObjectID = ObjectID.generate();
const generatedToken = ObjectID.generate();
const emailVerificationToken = new EmailVerificationToken();
const emailVerificationToken: EmailVerificationToken =
new EmailVerificationToken();
emailVerificationToken.userId = savedUser?.id!;
emailVerificationToken.email = savedUser?.email!;
emailVerificationToken.token = generatedToken;
emailVerificationToken.expires = OneUptimeDate.getOneDayAfter()
emailVerificationToken.expires = OneUptimeDate.getOneDayAfter();
await EmailVerificationTokenService.create({
data: emailVerificationToken,
props: {
isRoot: true
isRoot: true,
},
});
@ -127,7 +125,8 @@ router.post(
Domain,
new Route(AccountsRoute.toString()).addRoute(
'/verify-email/' + generatedToken.toString()
)).toString(),
)
).toString(),
homeUrl: new URL(HttpProtocol, HomeHostname).toString(),
},
}).catch((err: Error) => {
@ -234,15 +233,20 @@ router.post(
try {
const data: JSONObject = req.body['data'];
const token: EmailVerificationToken = EmailVerificationToken.fromJSON(data as JSONObject, EmailVerificationToken) as EmailVerificationToken;
const token: EmailVerificationToken =
EmailVerificationToken.fromJSON(
data as JSONObject,
EmailVerificationToken
) as EmailVerificationToken;
const alreadySavedToken: EmailVerificationToken | null = await EmailVerificationTokenService.findOneBy({
const alreadySavedToken: EmailVerificationToken | null =
await EmailVerificationTokenService.findOneBy({
query: { token: token.token! },
select: {
_id: true,
userId: true,
email: true,
expires: true
expires: true,
},
props: {
isRoot: true,
@ -250,29 +254,35 @@ router.post(
});
if (!alreadySavedToken) {
throw new BadDataException("Invalid link. Please try to log in and we will resend you another link which you should be able to verify email with.")
throw new BadDataException(
'Invalid link. Please try to log in and we will resend you another link which you should be able to verify email with.'
);
}
if (OneUptimeDate.hasExpired(alreadySavedToken.expires!)) {
throw new BadDataException("Link expired. Please try to log in and we will resend you another link which you should be able to verify email with.")
throw new BadDataException(
'Link expired. Please try to log in and we will resend you another link which you should be able to verify email with.'
);
}
let user = await UserService.findOneBy({
const user: User | null = await UserService.findOneBy({
query: {
email: token.email!,
_id: token._id!
_id: token._id!,
},
props: {
isRoot: true
isRoot: true,
},
select: {
_id: true,
email: true
}
email: true,
},
});
if (!user) {
throw new BadDataException("Invalid link. Please try to log in and we will resend you another link which you should be able to verify email with.")
throw new BadDataException(
'Invalid link. Please try to log in and we will resend you another link which you should be able to verify email with.'
);
}
await UserService.updateOneBy({
@ -280,15 +290,13 @@ router.post(
_id: user._id!,
},
data: {
isEmailVerified: true
isEmailVerified: true,
},
props: {
isRoot: true
}
isRoot: true,
},
});
console.log(user.email);
MailService.sendMail({
toEmail: user.email!,
subject: 'Email Verified.',
@ -318,17 +326,21 @@ router.post(
const data: JSONObject = req.body['data'];
const user: User = User.fromJSON(data as JSONObject, User) as User;
await user.password?.hashValue(EncryptionSecret);
const alreadySavedUser: User | null = await UserService.findOneBy({
query: { resetPasswordToken: user.resetPasswordToken as string || '' },
query: {
resetPasswordToken:
(user.resetPasswordToken as string) || '',
},
select: {
_id: true,
password: true,
name: true,
email: true,
isMasterAdmin: true,
resetPasswordExpires: true
resetPasswordExpires: true,
},
props: {
isRoot: true,
@ -336,20 +348,26 @@ router.post(
});
if (!alreadySavedUser) {
throw new BadDataException("Invalid link. Please go to forgot password page again and request a new link.")
throw new BadDataException(
'Invalid link. Please go to forgot password page again and request a new link.'
);
}
if (alreadySavedUser && OneUptimeDate.hasExpired(alreadySavedUser.resetPasswordExpires!)) {
throw new BadDataException("Expired link. Please go to forgot password page again and request a new link.")
if (
alreadySavedUser &&
OneUptimeDate.hasExpired(alreadySavedUser.resetPasswordExpires!)
) {
throw new BadDataException(
'Expired link. Please go to forgot password page again and request a new link.'
);
}
await UserService.updateOneById({
id: alreadySavedUser.id!,
data: {
password: user.password!,
resetPasswordToken: null!,
resetPasswordExpires: null!
resetPasswordExpires: null!,
},
props: {
isRoot: true,
@ -368,7 +386,6 @@ router.post(
});
return Response.sendEmptyResponse(req, res);
} catch (err) {
return next(err);
}
@ -405,24 +422,23 @@ router.post(
});
if (alreadySavedUser) {
if (!alreadySavedUser.isEmailVerified) {
const generatedToken = ObjectID.generate();
const generatedToken: ObjectID = ObjectID.generate();
const emailVerificationToken = new EmailVerificationToken();
const emailVerificationToken:EmailVerificationToken = new EmailVerificationToken();
emailVerificationToken.userId = alreadySavedUser?.id!;
emailVerificationToken.email = alreadySavedUser?.email!;
emailVerificationToken.token = generatedToken;
emailVerificationToken.expires = OneUptimeDate.getOneDayAfter()
emailVerificationToken.expires =
OneUptimeDate.getOneDayAfter();
await EmailVerificationTokenService.create({
data: emailVerificationToken,
props: {
isRoot: true
isRoot: true,
},
});
MailService.sendMail({
toEmail: alreadySavedUser.email!,
subject: 'Please verify email.',
@ -434,14 +450,20 @@ router.post(
Domain,
new Route(AccountsRoute.toString()).addRoute(
'/verify-email/' + generatedToken.toString()
)).toString(),
homeUrl: new URL(HttpProtocol, HomeHostname).toString(),
)
).toString(),
homeUrl: new URL(
HttpProtocol,
HomeHostname
).toString(),
},
}).catch((err: Error) => {
logger.error(err);
});
throw new BadDataException("Email is not verified. We have sent you an email with the verification link. Please do not forget to check spam.")
throw new BadDataException(
'Email is not verified. We have sent you an email with the verification link. Please do not forget to check spam.'
);
}
const token: string = JSONWebToken.sign(

View File

@ -164,7 +164,6 @@ export default class MailService {
to: mail.toEmail.toString(),
subject: mail.subject,
html: mail.body,
});
}