7from flask
import current_app, flash, redirect
8from flask_mail
import Mail, Message
10MAIL_SERVER=
'SMTP_SERVER'
14MAIL_USERNAME=
'SMTP_USERNAME'
15MAIL_PASSWORD=
'SMTP_PASSWORD'
16MAIL_DEFAULT_SENDER=
'FROM_EMAIL'
17IMAP_SERVER=
'IMAP_SERVER'
26 Initialize Flask-Mail with SMTP parameters from environment variables
29 MAIL_SERVER, MAIL_PORT, \
30 MAIL_USE_SSL, MAIL_USE_TLS, \
31 MAIL_USERNAME, MAIL_PASSWORD, MAIL_DEFAULT_SENDER, \
32 IMAP_SERVER, IMAP_PORT
36 MAIL_SERVER=os.getenv(
'SMTP_SERVER')
37 MAIL_PORT=int(os.getenv(
'SMTP_PORT'))
38 MAIL_USE_SSL=os.getenv(
'SMTP_USE_SSL').lower() ==
'true'
39 MAIL_USE_TLS=os.getenv(
'SMTP_USE_TLS').lower() ==
'true'
40 MAIL_USERNAME=os.getenv(
'SMTP_USERNAME')
41 MAIL_PASSWORD=os.getenv(
'SMTP_PASSWORD')
42 MAIL_DEFAULT_SENDER=os.getenv(
'FROM_EMAIL')
43 IMAP_SERVER=os.getenv(
'IMAP_SERVER')
44 IMAP_PORT=int(os.getenv(
'IMAP_PORT'))
46 app.config[
'MAIL_SERVER'] = MAIL_SERVER
47 app.config[
'MAIL_PORT'] = MAIL_PORT
48 app.config[
'MAIL_USE_SSL'] = MAIL_USE_SSL
49 app.config[
'MAIL_USE_TLS'] = MAIL_USE_TLS
50 app.config[
'MAIL_USERNAME'] = MAIL_USERNAME
51 app.config[
'MAIL_PASSWORD'] = MAIL_PASSWORD
52 app.config[
'MAIL_DEFAULT_SENDER'] = MAIL_DEFAULT_SENDER
64 Return Flask-Mail instance
70 flash(
"Error with SMTP mail server not configured.")
71 return redirect(url_for(
"home"))
76def generate_verification_token(user_id, secret_key=None, expiration_sec=3600):
78 Generate a JWT token for email verification
80 user_id: The user's ID
81 secret_key: Secret key for JWT signing (if None, will try to get from current_app)
82 expiration_sec: Token expiration time in seconds (default: 1 hour)
87 expiration_time = datetime.datetime.utcnow() + datetime.timedelta(seconds=expiration_sec)
91 "exp": expiration_time,
96 if secret_key
is None:
98 secret_key = current_app.secret_key
101 secret_key = os.getenv(
'SECRET_KEY',
'I-am-a-funny-unicorn')
104 token = jwt.encode(data, secret_key, algorithm=
"HS512")
107def verify_token(token, secret_key=None):
109 Verify and decode a JWT token
111 token: JWT token string
112 secret_key: Secret key for JWT verification (if None, will try to get from current_app)
114 dict with user_id if valid, None if invalid
118 if secret_key
is None:
120 secret_key = current_app.secret_key
123 secret_key = os.getenv(
'SECRET_KEY',
'I-am-a-funny-unicorn')
126 data = jwt.decode(token, secret_key, algorithms=[
"HS512"])
128 except jwt.ExpiredSignatureError:
131 except jwt.InvalidSignatureError:
134 except jwt.InvalidTokenError:
139def send_verification_email(user_email, username, token):
141 Send verification email with JWT token
143 user_email: Recipient email address
144 username: Username for personalization
145 token: JWT verification token
147 True if email sent successfully, False otherwise
150 from flask
import current_app
153 smtp_server = MAIL_SERVER
154 smtp_port = MAIL_PORT
155 smtp_username = MAIL_USERNAME
156 smtp_password = MAIL_PASSWORD
157 from_email = MAIL_DEFAULT_SENDER
160 from flask_mail
import Mail
164 server_name = os.getenv(
'SERVER_NAME')
165 domain = os.getenv(
'DOMAIN')
166 verification_url = f
"https://{server_name}.{domain}/verify-email/{token}"
170 subject=
"TiledViz - Email Verification",
171 recipients=[user_email],
179 <h2>Welcome to TiledViz, {username}!</h2>
180 <p>Thank you for registering. Please verify your email address by clicking the link below:</p>
181 <p><a href="{verification_url}" style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Verify Email Address</a></p>
182 <p>Or copy and paste this link in your browser:</p>
183 <p>{verification_url}</p>
184 <p>This link will expire in 1 hour.</p>
185 <p>If you didn't create an account, please ignore this email.</p>
187 <p>Best regards,<br>The TiledViz Team</p>
194 Welcome to TiledViz, {username}!
196 Thank you for registering. Please verify your email address by visiting the link below:
200 This link will expire in 1 hour.
202 If you didn't create an account, please ignore this email.
209 msg.html = html_content
210 msg.body = text_content
215 print(
" Email sent successfully")
218 except Exception
as e:
219 print(f
" Error sending verification email: {e}")
220 print(f
" Error type: {type(e)}")
222 print(f
" Traceback: {traceback.format_exc()}")
225def send_new_register_email(admin_emails,username,creation_date,user_email,user_company,user_manager):
227 Send email to an admin when a new user register
229 admin_emails : All admins emails
230 username : To see if admin knows it
231 user_email: User email for verification
232 user_company: User company for verification
233 user_manager: User manager for verification
235 True if email sent successfully, False otherwise
238 from flask
import current_app
241 smtp_server = MAIL_SERVER
242 smtp_port = MAIL_PORT
243 smtp_username = MAIL_USERNAME
244 smtp_password = MAIL_PASSWORD
245 from_email = MAIL_DEFAULT_SENDER
248 from flask_mail
import Mail
253 subject=
"TiledViz - New Register",
262 <h2>{username} just registered in TiledViz.</h2>
263 <p>Here are the different information entered by the user :</p>
264 <p>- Username : {username}</p>
265 <p>- Email : {user_email}</p>
266 <p>- Company : {user_company}</p>
267 <p>- Manager : {user_manager}</p>
268 <p>If you did not authorize this registration, you can review or delete this account from your admin dashboard.</p>
270 <p>Best regards,<br>The TiledViz Team</p>
277 {username} just registered in TiledViz.
279 Here are the different information entered by the user :
281 - Username : {username}
282 - Email : {user_email}
283 - Company : {user_company}
284 - Manager : {user_manager}
286 If you did not authorize this registration, you can review or delete this account from your admin dashboard.
293 msg.html = html_content
294 msg.body = text_content
299 print(
" Email sent successfully")
302 except Exception
as e:
303 print(f
" Error sending verification email: {e}")
304 print(f
" Error type: {type(e)}")
306 print(f
" Traceback: {traceback.format_exc()}")
310def delete_sent_email(subject, recipient):
312 Delete sent email from IMAP Sent folder
314 subject: Email subject to search for
315 recipient: Recipient email address
317 True if email deleted successfully, False otherwise
321 if not subject
or not recipient:
322 print(f
"Error deleting sent email: Missing subject or recipient (subject={subject}, recipient={recipient})")
326 imap_server = IMAP_SERVER
327 imap_port = IMAP_PORT
328 username = MAIL_USERNAME
329 password = MAIL_PASSWORD
333 print(f
"Error deleting sent email: SMTP_PASSWORD not configured")
339 mail = imaplib.IMAP4_SSL(imap_server, imap_port)
340 mail.login(username, password)
341 except Exception
as e:
342 print(f
"Error connecting to IMAP server: {e}")
346 mail.select(
'INBOX.Sent')
349 search_criteria = f
'(SUBJECT "{subject}" TO "{recipient}")'
350 status, messages = mail.search(
None, search_criteria)
352 if status ==
'OK' and messages
and messages[0]:
354 message_bytes = messages[0]
355 if isinstance(message_bytes, bytes):
356 message_str = message_bytes.decode(
'utf-8')
358 message_str = str(message_bytes)
if message_bytes
else ''
360 if message_str.strip():
361 message_ids = message_str.split()
364 for msg_id
in message_ids:
365 mail.store(msg_id,
'+FLAGS',
'\\Deleted')
377 except Exception
as e:
378 print(f
"Error deleting sent email: {e}")
383def generate_verification_code():
385 Generate a 6 digits code for 2FA login verification
387 user_id: The user's ID
388 expiration_sec: Token expiration time in seconds (default: 6 minutes)
394 code = random.randrange(100000, 999999)
398def send_2FAcode_email(user_email, username, code):
400 Send 2FAcode email with JWT token
402 user_email: Recipient email address
403 username: Username for personalization
406 True if email sent successfully, False otherwise
409 from flask
import current_app
412 smtp_server = MAIL_SERVER
413 smtp_port = MAIL_PORT
414 smtp_username = MAIL_USERNAME
415 smtp_password = MAIL_PASSWORD
416 from_email = MAIL_DEFAULT_SENDER
419 from flask_mail
import Mail
423 server_name = os.getenv(
'SERVER_NAME')
424 domain = os.getenv(
'DOMAIN')
428 subject=
"TiledViz - 2FA code",
429 recipients=[user_email],
437 <h2>Welcome to TiledViz, {username}!</h2>
438 <p>You tried to login to TiledViz. Use this code in login page to validate 2FA verification.
439 <p><a style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">{code}</a></p>
440 <p>This link will expire in 5 minutes.</p>
442 <p>Best regards,<br>The TiledViz Team</p>
449 Welcome to TiledViz, {username}!
451 Please use this code to validate your 2FA security check:
455 This code will expire in 5 minutes.
457 If you didn't create an account, please ignore this email.
464 msg.html = html_content
465 msg.body = text_content
470 print(
" Email sent successfully")
473 except Exception
as e:
474 print(f
" Error sending verification email: {e}")
475 print(f
" Error type: {type(e)}")
477 print(f
" Traceback: {traceback.format_exc()}")