openreplay/api/chalicelib/utils/email_handler.py
Kraiem Taha Yassine a29c02b43a
Api FastApi (#252)
* feat(api): dynamic-api 1/2

* feat(api): dynamic-api 2/2
feat(api): core-api 1/2

* feat(api): changed schemas
feat(api): aipkey authorizer
feat(api): jwt authorizer payload
feat(api): core-api 2/3

* feat(api): apikey authorizer
feat(api): shared context
feat(api): response editor
feat(api): middleware
feat(api): custom router
feat(api): fix auth double call

* feat(api): dashboard
feat(api): insights
feat(api): public api v1

* feat(api): allow full CORS

* feat(api): use decouple-config instead of env
feat(api): fixed conflict slack endpoint
feat(api): fixed favorite errors param

* feat(api): migration fixes

* feat(api): changes

* feat(api): crons

* feat(api): changes and fixes

* feat(api): added new endpoints
feat(api): applied new changes
feat(api): Docker image

* feat(api): EE 1/4

* feat(api): EE core_dynamic

* feat(api): global routers generator

* feat(api): project authorizer
feat(api): docker image
feat(api): crons

* feat(api): EE trace activity

* feat(api): changed ORRouter

* feat(api): EE trace activity parameters&payload

* feat(api): EE trace activity action name & path_format

* feat(db): user trace

* feat(api): EE trace activity ignore routes and hide attribute
feat(api): fix funnel payload schema

* feat(api): mobile support

* feat(api): changed build script

* feat(api): changed mobile sign endpoint
feat(api): changed requirements.txt

* feat(api): changed dockerfile

* feat(api): changed mobile-env-var

* feat(api): removed insights

* feat(api): changed EE Dockerfile

* feat(api): cast session_id to str for signing

* feat(api): fixed error_id type

* feat(api): fixed /errors priority conflict

* feat(api): fixed /errors/{errorId} default params

* feat(api): fixed change password after invitation

* feat(api): use background task for emails instead of low-timeout-api
feat(api): EE fixed missing required params

* feat(api): funnel-insights payload change

* feat(api): funnel-insights payload change

* feat(api): changed edit user payload schema

* feat(api): changed metrics payload schema

* feat(api): changed metrics payload schema

* feat(api): changed edit user default values
feat(api): fixed change error status route

* feat(api): changed edit user

* feat(api): stop user from changing his own role

* feat(api): changed add slack

* feat(api): changed get funnel

* feat(api): changed get funnel on the fly payload
feat(api): changed update payload

* feat(api): changed get funnel on the fly payload

* feat(api): changed update funnel payload

* feat(api): changed get funnel-sessions/issues on the fly payload

* feat(api): fixed funnel missing rangeValue

* feat(api): fixes

* feat(api): iceServers configuration

* feat(api): fix issueId casting

* feat(api): changed issues-sessions endpoint payload-schema

* feat(api): EE changed traces-ignored-routes

* feat(api): EE include core sessions.py

* feat(api): EE check licence on every request if expired

* feat(api): move general stats to dynamic

* feat(api): code cleanup
feat(api): removed sentry

* feat(api): changed traces-ignore-routes

* feat(api): changed dependencies

* feat(api): changed jwt-auth-response code

* feat(api): changed traces-ignore-routes

* feat(api): changed traces-ignore-routes

* feat(api): removed PyTZ
feat(api): migrated time-helper to zoneinfo

* feat(api): EE added missing dependency
feat(api): changed base docker image

* feat(api): merge after roles

* feat(api): EE roles fastapi

* feat(db): handel HTTPExceptions

* feat(db): changed payload schema

* feat(db): changed payload schema

* feat(api): included insights

* feat(api): removed unused helper

* feat(api): merge from dev to fatsapi

* feat(api): merge fixes
feat(api): SAML migration

* feat(api): changed GET /signup response
feat(api): changed EE Dockerfile

* feat(api): changed edition detection

* feat(api): include ee endpoints

* feat(api): add/edit member changes

* feat(api): saml changed redirect

* feat(api): track session's replay
feat(api): track error's details

* feat(api): ignore tracking for read roles

* feat(api): define global queue
feat(api): define global scheduler
feat(api): traces use queue
feat(api): traces batch insert
feat(DB): changed traces schema

* feat(api): fix signup captcha

* feat(api): fix signup captcha

* feat(api): optional roleId
feat(api): set roleId to member if None

* feat(api): fixed edit role

* feat(api): return role details when creating a new member

* feat(api): trace: use BackgroundTasks instead of BackgroundTask to not override previous tasks

* feat(api): trace: use BackgroundTask if no other background task is defined

* feat(api): optimised delete metadata

* feat(api): Notification optional message

* feat(api): fix background-task reference

* feat(api): fix trace-background-task

* feat(api): fixed g-captcha for reset password

* feat(api): fix edit self-user

* feat(api): fixed create github-issue

* feat(api): set misfire_grace_time for crons

* feat(api): removed chalice
feat(api): freeze dependencies

* feat(api): refactored blueprints

* feat(api): /metadata/session_search allow projectId=None

* feat(api): public API, changed userId type

* feat(api): fix upload sourcemaps

* feat(api): user-trace support ApiKey endpoints

* feat(api): fixed user-trace foreign key type

* feat(api): fixed trace schema

* feat(api): trace save auth-method

* feat(api): trace fixed auth-method

* feat(api): trace changed schema
2021-12-16 19:10:12 +01:00

90 lines
3 KiB
Python

import base64
import re
from email.header import Header
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from chalicelib.utils import helper, smtp
from decouple import config
def __get_subject(subject):
return subject
def __get_html_from_file(source, formatting_variables):
if formatting_variables is None:
formatting_variables = {}
formatting_variables["frontend_url"] = config("SITE_URL")
with open(source, "r") as body:
BODY_HTML = body.read()
if formatting_variables is not None and len(formatting_variables.keys()) > 0:
BODY_HTML = re.sub(r"%(?![(])", "%%", BODY_HTML)
BODY_HTML = BODY_HTML % {**formatting_variables}
return BODY_HTML
def __replace_images(HTML):
pattern_holder = re.compile(r'<img[\w\W\n]+?(src="[a-zA-Z0-9.+\/\\-]+")')
pattern_src = re.compile(r'src="(.*?)"')
mime_img = []
swap = []
for m in re.finditer(pattern_holder, HTML):
sub = m.groups()[0]
sub = str(re.findall(pattern_src, sub)[0])
if sub not in swap:
swap.append(sub)
HTML = HTML.replace(sub, f"cid:img-{len(mime_img)}")
sub = "chalicelib/utils/html/" + sub
with open(sub, "rb") as image_file:
img = base64.b64encode(image_file.read()).decode('utf-8')
mime_img.append(MIMEImage(base64.standard_b64decode(img)))
mime_img[-1].add_header('Content-ID', f'<img-{len(mime_img) - 1}>')
return HTML, mime_img
def send_html(BODY_HTML, SUBJECT, recipient, bcc=None):
BODY_HTML, mime_img = __replace_images(BODY_HTML)
if not isinstance(recipient, list):
recipient = [recipient]
msg = MIMEMultipart()
msg['Subject'] = Header(__get_subject(SUBJECT), 'utf-8')
msg['From'] = config("EMAIL_FROM")
msg['To'] = ""
body = MIMEText(BODY_HTML.encode('utf-8'), 'html', "utf-8")
msg.attach(body)
for m in mime_img:
msg.attach(m)
with smtp.SMTPClient() as s:
for r in recipient:
msg.replace_header("To", r)
r = [r]
if bcc is not None and len(bcc) > 0:
r += [bcc]
try:
print(f"Email sending to: {r}")
s.sendmail(msg['FROM'], r, msg.as_string().encode('ascii'))
except Exception as e:
print("!!! Email error!")
print(e)
def send_text(recipients, text, subject):
with smtp.SMTPClient() as s:
msg = MIMEMultipart()
msg['Subject'] = Header(__get_subject(subject), 'utf-8')
msg['From'] = config("EMAIL_FROM")
msg['To'] = ", ".join(recipients)
body = MIMEText(text)
msg.attach(body)
try:
s.sendmail(msg['FROM'], recipients, msg.as_string().encode('ascii'))
except Exception as e:
print("!! Text-email failed: " + subject),
print(e)
def __escape_text_html(text):
return text.replace("@", "<span>@</span>").replace(".", "<span>.</span>").replace("=", "<span>=</span>")