Skip to content

Commit

Permalink
Added send emails validation
Browse files Browse the repository at this point in the history
  • Loading branch information
jpcadena committed Jun 17, 2023
1 parent 023324c commit d0e024d
Show file tree
Hide file tree
Showing 9 changed files with 549 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ local.properties
#.project

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
Expand Down Expand Up @@ -967,5 +969,3 @@ ClientBin/
*.pfx
*.publishsettings
orleans.codegen.cs
!/logs/log-17-Jun-2023-13-04-47.log
!/logs/
70 changes: 70 additions & 0 deletions app/assets/templates/new_account.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="/app/assets/css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
rel="stylesheet">
</head>
<body style="background-color:#ffffff;">
<div style="background-color:#ffffff;">
<div style="margin:0 auto;max-width:600px;">
<table class="main-table" role="presentation">
<tbody>
<tr>
<td style="direction:ltr;font-size:0;padding:20px 0;text-align:center;">
<div class="mj-column">
<table role="presentation" style="width:100%;">
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<p style="border-top:solid 4px #555555;font-size:2px;margin:0 auto;width:100%;"></p>
</td>
</tr>
<tr>
<td style="font-size:20px;padding:10px 25px;word-break:break-word;text-align:left;color:#555555;">
{{ project_name }} - New Account
</td>
</tr>
<tr>
<td style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;padding:10px 25px;word-break:break-word;text-align:left;color:#555555;">
You have a new account:
</td>
</tr>
<tr>
<td style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;padding:10px 25px;word-break:break-word;text-align:left;color:#555555;">
Username: {{ username }}
</td>
</tr>
<tr>
<td style="font-size:0;padding:50px 0;word-break:break-word;text-align:center;">
<table class="button-table"
role="presentation">
<tr>
<td class="button-cell">
<a class="button-link"
href="{{ link }}"
target="_blank">Go to
Dashboard</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<p style="border-top:solid 2px #555555;font-size:2px;margin:0 auto;width:100%;"></p>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
104 changes: 104 additions & 0 deletions app/assets/templates/reset_password.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="/app/assets/css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
rel="stylesheet">
</head>
<body style="background-color:#ffffff;">
<div style="background-color:#ffffff;">
<div style="margin:0 auto;max-width:600px;">
<table class="main-table-centered" role="presentation">
<tbody>
<tr>
<td class="center" style="direction:ltr;font-size:0;padding:20px 0;">
<div class="mj-column">
<table class="inner-table" role="presentation">
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<p class="separator"></p>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="heading">
{{ project_name }} - Password Recovery
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="content">
We received a request to recover the password for user {{
username }} with email {{ email }}
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="content">
Reset your password by clicking the button below:
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:50px 0;word-break:break-word;text-align:center;">
<table role="presentation"
style="border-collapse:separate;line-height:100%;">
<tr>
<td class="button">
<a href="{{ link }}" target="_blank">Reset Password</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="content">
Or open the following link:
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="content">
<a href="{{ link }}">{{ link }}</a>
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<p class="separator-sm"></p>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="footer">
The reset password link / button will expire in {{
valid_hours }} hours.
</div>
</td>
</tr>
<tr>
<td style="font-size:0;padding:10px 25px;word-break:break-word;">
<div class="footer">
If you didn't request a password recovery, you can disregard
this email.
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
56 changes: 56 additions & 0 deletions app/assets/templates/test_email.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="/app/assets/css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
rel="stylesheet">
</head>
<body style="background-color:#ffffff;">
<div style="background-color:#ffffff;">
<div style="Margin:0 auto;max-width:600px;">
<table class="table-center table-collapse" role="presentation"
style="width:100%;">
<tbody>
<tr>
<td class="p-20"
style="direction:ltr;font-size:0;text-align:center;vertical-align:top;">
<div class="mj-column-per-100 outlook-group-fix"
style="font-size:13px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
<table class="table-collapse border-none table-full-width"
role="presentation" style="vertical-align:top;">
<tr>
<td class="px-25 pb-10 border-top"
style="font-size:0;word-break:break-word;">
<p style="font-size:2px;margin:0 auto;width:100%;"></p>
</td>
</tr>
<tr>
<td class="px-25 pb-10 text-left"
style="font-size:0;word-break:break-word;">
<div style="font-family:helvetica,serif;font-size:20px;line-height:1;color:#555555;">
{{ project_name }}
</div>
</td>
</tr>
<tr>
<td class="px-25 pb-10 text-left"
style="font-size:0;word-break:break-word;">
<div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;line-height:1;color:#555555;">
Test email for: {{ email }}
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions app/utils/email_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Package app.utils.email utils initialization.
"""
116 changes: 116 additions & 0 deletions app/utils/email_utils/email_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""
A module for email utilities in the app.utils package.
"""
from pathlib import Path

from fastapi import Depends
from pydantic import EmailStr

from app.core import config
from app.core.decorators import with_logging
from app.utils.email_utils.notificaction import send_email
from app.utils.email_utils.template import read_template_file


async def build_email_template(
template_file: str, settings: config.Settings
) -> str:
"""
Builds the email template
:param template_file: The template file
:type template_file: str
:param settings: Dependency method for cached setting object
:type settings: config.Settings
:return: The template read as a string
:rtype: str
"""
template_path: Path = Path(settings.EMAIL_TEMPLATES_DIR) / template_file
template_str: str = await read_template_file(template_path, settings)
return template_str


@with_logging
async def send_test_email(
email_to: EmailStr,
settings: config.Settings = Depends(config.get_settings)
) -> bool:
"""
Send test email
:param email_to: The email address of the recipient
:type email_to: EmailStr
:param settings: Dependency method for cached setting object
:type settings: config.Settings
:return: True if the email was sent; otherwise false
:rtype: bool
"""
subject: str = f"{settings.PROJECT_NAME} - Test email"
template_str: str = await build_email_template("test_email.html", settings)
is_sent: bool = await send_email(
email_to=email_to, subject_template=subject,
html_template=template_str,
environment={"project_name": settings.PROJECT_NAME, "email": email_to},
settings=settings)
return is_sent


@with_logging
async def send_reset_password_email(
email_to: EmailStr, username: str, token: str,
settings: config.Settings = Depends(config.get_settings)
) -> bool:
"""
Sends a password reset email to a user with the given email address
:param email_to: The email address of the user
:type email_to: EmailStr
:param username: The username of the user
:type username: str
:param token: The reset password token generated for the user
:type token: str
:param settings: Dependency method for cached setting object
:type settings: config.Settings
:return: True if the email was sent successfully; False otherwise
:rtype: bool
"""
subject: str = f"{settings.PROJECT_NAME} - Password recovery for user " \
f"{username}"
template_str: str = await build_email_template(
"reset_password.html", settings)
link: str = f"{settings.SERVER_HOST}/reset-password?token={token}"
is_sent: bool = await send_email(
email_to=email_to,
subject_template=subject,
html_template=template_str,
environment={
"project_name": settings.PROJECT_NAME, "username": username,
"email": email_to,
"valid_hours": settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS,
"link": link}, settings=settings)
return is_sent


@with_logging
async def send_new_account_email(
email_to: EmailStr, username: str,
settings: config.Settings = Depends(config.get_settings)
) -> bool:
"""
Send a new account email
:param email_to: The email address of the recipient with new
account
:type email_to: EmailStr
:param username: Username of the recipient
:type username: str
:param settings: Dependency method for cached setting object
:type settings: config.Settings
:return: True if the email was sent; otherwise false
:rtype: bool
"""
subject: str = f"{settings.PROJECT_NAME} - New account for user {username}"
template_str: str = await build_email_template("new_account.html", settings)
is_sent: bool = await send_email(
email_to=email_to, subject_template=subject,
html_template=template_str,
environment={
"project_name": settings.PROJECT_NAME, "username": username,
"email": email_to, "link": settings.SERVER_HOST}, settings=settings)
return is_sent
Loading

0 comments on commit d0e024d

Please sign in to comment.