mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 14:49:07 +00:00
fix accounts page
This commit is contained in:
parent
30d9242e2d
commit
addfc9d69c
@ -16,6 +16,7 @@ import 'CommonUI/src/Styles/theme.scss';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
import VerifyEmail from './Pages/VerifyEmail';
|
||||
import User from 'CommonUI/src/Utils/User';
|
||||
import ResetPasswordPage from './Pages/ResetPassword';
|
||||
|
||||
function App(): ReactElement {
|
||||
Navigation.setNavigateHook(useNavigate());
|
||||
@ -37,7 +38,7 @@ function App(): ReactElement {
|
||||
/>
|
||||
<Route
|
||||
path="/accounts/reset-password/:token"
|
||||
element={<ForgotPasswordPage />}
|
||||
element={<ResetPasswordPage />}
|
||||
/>
|
||||
<Route path="/accounts/register" element={<RegisterPage />} />
|
||||
<Route path="/accounts/login/sso" element={<SsoLoginPage />} />
|
||||
|
134
Accounts/src/Pages/ResetPassword.tsx
Normal file
134
Accounts/src/Pages/ResetPassword.tsx
Normal file
@ -0,0 +1,134 @@
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
import ModelForm, { FormType } from 'CommonUI/src/Components/Forms/ModelForm';
|
||||
import User from 'Model/Models/User';
|
||||
import Link from 'CommonUI/src/Components/Link/Link';
|
||||
import Route from 'Common/Types/API/Route';
|
||||
import FormFieldSchemaType from 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
|
||||
import OneUptimeLogo from 'CommonUI/src/Images/logos/OneUptimePNG/7.png';
|
||||
|
||||
import URL from 'Common/Types/API/URL';
|
||||
import { RESET_PASSWORD_API_URL } from '../Utils/ApiPaths';
|
||||
import Navigation from 'CommonUI/src/Utils/Navigation';
|
||||
|
||||
const RegisterPage: FunctionComponent = () => {
|
||||
const apiUrl: URL = RESET_PASSWORD_API_URL;
|
||||
const [isSuccess, setIsSuccess] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<div className="auth-page">
|
||||
<div className="container-fluid p-0">
|
||||
<div className="row g-0">
|
||||
<div className="col-xxl-3 col-lg-3 col-md-2"></div>
|
||||
|
||||
<div className="col-xxl-6 col-lg-6 col-md-8">
|
||||
<div className="auth-full-page-content d-flex p-sm-5 p-4">
|
||||
<div className="w-100">
|
||||
<div className="d-flex flex-column h-100">
|
||||
<div className="auth-content my-auto">
|
||||
<div
|
||||
className="mt-4 text-center"
|
||||
style={{ marginBottom: '40px' }}
|
||||
>
|
||||
<img
|
||||
style={{ height: '40px' }}
|
||||
src={`/accounts/public/${OneUptimeLogo}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<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>}
|
||||
|
||||
</div>
|
||||
|
||||
{!isSuccess && <ModelForm<User>
|
||||
modelType={User}
|
||||
id="register-form"
|
||||
onBeforeCreate={(item: User) => {
|
||||
item.resetPasswordToken = Navigation.getLastParam()?.toString().replace("/", "").toString() ||''
|
||||
return item;
|
||||
}}
|
||||
showAsColumns={1}
|
||||
maxPrimaryButtonWidth={true}
|
||||
initialValues={{
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
}}
|
||||
fields={[
|
||||
|
||||
{
|
||||
field: {
|
||||
password: true,
|
||||
},
|
||||
fieldType:
|
||||
FormFieldSchemaType.Password,
|
||||
validation: {
|
||||
minLength: 6,
|
||||
},
|
||||
placeholder: 'New Password',
|
||||
title: 'New Password',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
password: true,
|
||||
},
|
||||
validation: {
|
||||
minLength: 6,
|
||||
toMatchField:
|
||||
'password',
|
||||
},
|
||||
fieldType:
|
||||
FormFieldSchemaType.Password,
|
||||
placeholder:
|
||||
'Confirm Password',
|
||||
title: 'Confirm Password',
|
||||
overideFieldKey:
|
||||
'confirmPassword',
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
apiUrl={apiUrl}
|
||||
formType={FormType.Create}
|
||||
submitButtonText={'Reset Password'}
|
||||
onSuccess={() => {
|
||||
setIsSuccess(true);
|
||||
}}
|
||||
/>}
|
||||
|
||||
<div className="mt-5 text-center">
|
||||
<p className="text-muted mb-0">
|
||||
Know your password?{' '}
|
||||
<Link
|
||||
to={
|
||||
new Route(
|
||||
'/accounts/login'
|
||||
)
|
||||
}
|
||||
className="underline-on-hover text-primary fw-semibold"
|
||||
>
|
||||
Log in.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-xxl-3 col-lg-3 col-md-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RegisterPage;
|
@ -15,4 +15,8 @@ export const FORGOT_PASSWORD_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
|
||||
|
||||
export const VERIFY_EMAIL_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
|
||||
new Route('/verify-email')
|
||||
);
|
||||
|
||||
export const RESET_PASSWORD_API_URL: URL = URL.fromURL(IDENTITY_URL).addRoute(
|
||||
new Route('/reset-password')
|
||||
);
|
@ -2,6 +2,7 @@ enum EmailTemplateType {
|
||||
ForgotPassword = 'ForgotPassword.hbs',
|
||||
SignupWelcomeEmail = 'SignupWelcomeEmail.hbs',
|
||||
EmailVerified = 'EmailVerified.hbs',
|
||||
PasswordChanged = 'PasswordChanged.hbs',
|
||||
}
|
||||
|
||||
export default EmailTemplateType;
|
||||
|
@ -106,7 +106,7 @@ router.post(
|
||||
const emailVerificationToken = new EmailVerificationToken();
|
||||
emailVerificationToken.userId = savedUser?.id!;
|
||||
emailVerificationToken.email = savedUser?.email!;
|
||||
emailVerificationToken.token = generatedToken;
|
||||
emailVerificationToken.token = generatedToken;
|
||||
emailVerificationToken.expires = OneUptimeDate.getOneDayAfter()
|
||||
|
||||
await EmailVerificationTokenService.create({
|
||||
@ -321,33 +321,54 @@ router.post(
|
||||
await user.password?.hashValue(EncryptionSecret);
|
||||
|
||||
const alreadySavedUser: User | null = await UserService.findOneBy({
|
||||
query: { email: user.email!, password: user.password! },
|
||||
query: { resetPasswordToken: user.resetPasswordToken as string || '' },
|
||||
select: {
|
||||
_id: true,
|
||||
password: true,
|
||||
name: true,
|
||||
email: true,
|
||||
isMasterAdmin: true,
|
||||
resetPasswordExpires: true
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (alreadySavedUser) {
|
||||
const token: string = JSONWebToken.sign(
|
||||
alreadySavedUser,
|
||||
OneUptimeDate.getSecondsInDays(new PositiveNumber(30))
|
||||
);
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
token: token,
|
||||
user: BaseModel.toJSON(alreadySavedUser, User),
|
||||
});
|
||||
if (!alreadySavedUser) {
|
||||
throw new BadDataException("Invalid link. Please go to forgot password page again and request a new link.")
|
||||
}
|
||||
throw new BadDataException(
|
||||
'Invalid login: Email or password does not match.'
|
||||
);
|
||||
|
||||
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!
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
MailService.sendMail({
|
||||
toEmail: alreadySavedUser.email!,
|
||||
subject: 'Password Changed.',
|
||||
templateType: EmailTemplateType.PasswordChanged,
|
||||
vars: {
|
||||
homeURL: new URL(HttpProtocol, Domain).toString(),
|
||||
},
|
||||
}).catch((err: Error) => {
|
||||
logger.error(err);
|
||||
});
|
||||
|
||||
return Response.sendEmptyResponse(req, res);
|
||||
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
@ -391,16 +412,16 @@ router.post(
|
||||
const emailVerificationToken = new EmailVerificationToken();
|
||||
emailVerificationToken.userId = alreadySavedUser?.id!;
|
||||
emailVerificationToken.email = alreadySavedUser?.email!;
|
||||
emailVerificationToken.token = generatedToken;
|
||||
emailVerificationToken.token = generatedToken;
|
||||
emailVerificationToken.expires = OneUptimeDate.getOneDayAfter()
|
||||
|
||||
|
||||
await EmailVerificationTokenService.create({
|
||||
data: emailVerificationToken,
|
||||
props: {
|
||||
isRoot: true
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
MailService.sendMail({
|
||||
toEmail: alreadySavedUser.email!,
|
||||
|
550
Mail/Templates/PasswordChanged.hbs
Normal file
550
Mail/Templates/PasswordChanged.hbs
Normal file
@ -0,0 +1,550 @@
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=3Dutf-8">
|
||||
<meta name="viewport" content="width=3Ddevice-width">
|
||||
<title>Welcome to OneUptime.</title>
|
||||
<style>
|
||||
/**
|
||||
* IMPORTANT:
|
||||
* Please read before changing anything, CSS involved in our HTML emails is
|
||||
* extremely specific and written a certain way for a reason. It might not make
|
||||
* sense in a normal setting but Outlook loves it this way.
|
||||
*
|
||||
* !!! [override] prevents Yahoo Mail breaking media queries. It must be used
|
||||
* !!! at the beginning of every line of CSS inside a media query.
|
||||
* !!! Do not remove.
|
||||
*
|
||||
* !!! div[style*="margin: 16px 0"] allows us to target a weird margin
|
||||
* !!! bug in Android's email client.
|
||||
* !!! Do not remove.
|
||||
*
|
||||
* Also, the img files are hosted on S3. Please don't break these URLs!
|
||||
* The images are also versioned by date, so please update the URLs accordingly
|
||||
* if you create new versions
|
||||
*
|
||||
***/
|
||||
|
||||
|
||||
/**
|
||||
* # Root
|
||||
* - CSS resets and general styles go here.
|
||||
**/
|
||||
|
||||
html,
|
||||
body,
|
||||
a,
|
||||
span,
|
||||
div[style*="margin: 16px 0"] {
|
||||
border: 0 !important;
|
||||
margin: 0 !important;
|
||||
outline: 0 !important;
|
||||
padding: 0 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
a,
|
||||
span,
|
||||
td,
|
||||
th {
|
||||
-webkit-font-smoothing: antialiased !important;
|
||||
-moz-osx-font-smoothing: grayscale !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Delink
|
||||
* - Classes for overriding clients which creates links out of things like
|
||||
* emails, addresses, phone numbers, etc.
|
||||
**/
|
||||
|
||||
span.st-Delink a {
|
||||
color: #000000 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** Modifier: preheader */
|
||||
span.st-Delink.st-Delink--preheader a {
|
||||
color: white !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: title */
|
||||
span.st-Delink.st-Delink--title a {
|
||||
color: #000000 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: footer */
|
||||
span.st-Delink.st-Delink--footer a {
|
||||
color: #8898aa !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
.ii a[href] {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Mobile
|
||||
* - This affects emails views in clients less than 600px wide.
|
||||
**/
|
||||
|
||||
@media all and (max-width: 600px) {
|
||||
|
||||
/**
|
||||
* # Wrapper
|
||||
**/
|
||||
|
||||
body[override] table.st-Wrapper,
|
||||
body[override] table.st-Width.st-Width--mobile {
|
||||
min-width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Spacer
|
||||
**/
|
||||
|
||||
/** Modifier: gutter */
|
||||
body[override] td.st-Spacer.st-Spacer--gutter {
|
||||
width: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: kill */
|
||||
body[override] td.st-Spacer.st-Spacer--kill {
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: emailEnd */
|
||||
body[override] td.st-Spacer.st-Spacer--emailEnd {
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/**
|
||||
* # Font
|
||||
**/
|
||||
|
||||
/** Modifier: title */
|
||||
body[override] td.st-Font.st-Font--title,
|
||||
body[override] td.st-Font.st-Font--title span,
|
||||
body[override] td.st-Font.st-Font--title a {
|
||||
font-size: 28px !important;
|
||||
line-height: 36px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: header */
|
||||
body[override] td.st-Font.st-Font--header,
|
||||
body[override] td.st-Font.st-Font--header span,
|
||||
body[override] td.st-Font.st-Font--header a {
|
||||
font-size: 24px !important;
|
||||
line-height: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: body */
|
||||
body[override] td.st-Font.st-Font--body,
|
||||
body[override] td.st-Font.st-Font--body span,
|
||||
body[override] td.st-Font.st-Font--body a {
|
||||
font-size: 18px !important;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: caption */
|
||||
body[override] td.st-Font.st-Font--caption,
|
||||
body[override] td.st-Font.st-Font--caption span,
|
||||
body[override] td.st-Font.st-Font--caption a {
|
||||
font-size: 14px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: simplified */
|
||||
body[override] table.st-Header.st-Header--simplified td.st-Header-logo {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Header.st-Header--simplified td.st-Header-spacing {
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Divider
|
||||
**/
|
||||
|
||||
body[override] table.st-Divider td.st-Spacer.st-Spacer--gutter,
|
||||
body[override] tr.st-Divider td.st-Spacer.st-Spacer--gutter {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Blocks
|
||||
**/
|
||||
|
||||
body[override] table.st-Blocks table.st-Blocks-inner {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Blocks table.st-Blocks-inner table.st-Blocks-item td.st-Blocks-item-cell {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Button
|
||||
**/
|
||||
|
||||
body[override] table.st-Button {
|
||||
margin: 0 auto !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Button td.st-Button-area,
|
||||
body[override] table.st-Button td.st-Button-area a.st-Button-link,
|
||||
body[override] table.st-Button td.st-Button-area span.st-Button-internal {
|
||||
height: 44px !important;
|
||||
line-height: 44px !important;
|
||||
font-size: 18px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="st-Email" bgcolor="f7f7f7"
|
||||
style="border: 0; margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; min-width: 100%; width: 100%;"
|
||||
override="fix">
|
||||
|
||||
<!-- Background -->
|
||||
<table class="st-Background" bgcolor="f7f7f7" border="0" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="border: 0; margin: 0; padding: 0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border: 0; margin: 0; padding: 0;">
|
||||
|
||||
<!-- Wrapper -->
|
||||
<table class="st-Wrapper" align="center" bgcolor="ffffff" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600"
|
||||
style="border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; margin: 0 auto; min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border: 0; margin: 0; padding: 0;">
|
||||
|
||||
|
||||
|
||||
<table class="st-Header st-Header--simplified st-Width st-Width--mobile" border="0" cellpadding="0"
|
||||
cellspacing="0" width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="4" height="19"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td align="left" style="height:80px; border: 0; margin: 0; padding: 0;">
|
||||
<div>
|
||||
<a style="border: 0; margin: 0; padding: 0; text-decoration: none;" href={{homeURL}}>
|
||||
|
||||
<img alt="OneUptime" border="0"
|
||||
style="height:70px; width:70px; border: 0; margin: 0; padding: 0; color: #000000; display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; font-weight: normal;"
|
||||
src="https://res.cloudinary.com/deityhub/image/upload/v1637736803/1png.png">
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="st-Header-spacing" width="423" style="border: 0; margin: 0; padding: 0;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="4" height="19"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="st-Divider">
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td bgcolor="#fdfdfd" colspan="2" height="1"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="color: #000000 !important; border:0;margin:0;padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Ubuntu,sans-serif;font-size:16px;line-height:24px">
|
||||
|
||||
<h3>You have changed your password.</h3>
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
|
||||
Your password has been updated. You can now log in.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body link-content"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
If you did not do this action, please send us an email at <a
|
||||
style="color: #000000; text-decoration: none; font-weight: bold"
|
||||
href="mailto:support@oneuptime.com" target="_blank">support@oneuptime.com</a> and let us
|
||||
know.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
Thanks, have a great day.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
OneUptime Team.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="st-Footer st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="3" height="20"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="st-Divider">
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td bgcolor="#fdfdfd" colspan="2" height="1"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="3" height="31"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--caption"
|
||||
style="border: 0; margin: 0;padding: 0; color: #8898aa; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; line-height: 16px;">
|
||||
<span class="st-Delink st-Delink--footer"
|
||||
style="border: 0; margin: 0; padding: 0; color: #8898aa; text-decoration: none;">
|
||||
© {{year}} OneUptime Inc.
|
||||
</span>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--emailEnd" colspan="3" height="64"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /Wrapper -->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--emailEnd" height="64"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /Background -->
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user