✨ Added email-verification
This commit is contained in:
+3
-3
@@ -12,14 +12,14 @@ async def cache_account(criteria: str, content: str) -> Union[User, None]:
|
||||
|
||||
if criteria == "email":
|
||||
try:
|
||||
res = await User.objects.get(email=content)
|
||||
res = await User.objects.get(email=content, verified=True)
|
||||
except ormar.exceptions.NoMatch:
|
||||
return None
|
||||
await insert_into_redis(res, content)
|
||||
return res
|
||||
elif criteria == "username":
|
||||
try:
|
||||
res = await User.objects.get(username=content)
|
||||
res = await User.objects.get(username=content, verified=True)
|
||||
except ormar.exceptions.NoMatch:
|
||||
return None
|
||||
await insert_into_redis(res, content)
|
||||
@@ -27,7 +27,7 @@ async def cache_account(criteria: str, content: str) -> Union[User, None]:
|
||||
elif criteria == "id":
|
||||
|
||||
try:
|
||||
res = await User.objects.get(id=uuid.UUID(content))
|
||||
res = await User.objects.get(id=uuid.UUID(content), verified=True)
|
||||
except ormar.exceptions.NoMatch:
|
||||
return None
|
||||
await insert_into_redis(res, content)
|
||||
|
||||
@@ -1,4 +1,40 @@
|
||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
from classquiz.db.models import User
|
||||
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from classquiz.config import settings
|
||||
from email.mime.text import MIMEText
|
||||
import smtplib
|
||||
import ssl
|
||||
|
||||
jinja = Environment(
|
||||
loader=PackageLoader('classquiz.emails', 'templates'),
|
||||
autoescape=select_autoescape(['html', 'xml']),
|
||||
enable_async=True)
|
||||
|
||||
|
||||
def _sendMail(template: str, to: str, subject: str):
|
||||
msg = MIMEMultipart('alternative')
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = settings.mail_address
|
||||
msg['To'] = to
|
||||
msg.attach(MIMEText(template, 'html'))
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||
server = smtplib.SMTP(host=settings.mail_server, port=settings.mail_port)
|
||||
server.ehlo()
|
||||
server.starttls(context=context)
|
||||
server.ehlo()
|
||||
server.login(settings.mail_username, settings.mail_password)
|
||||
server.sendmail(settings.mail_address, to, msg.as_string())
|
||||
|
||||
|
||||
async def send_mail(email: str):
|
||||
pass
|
||||
user = await User.objects.get_or_none(email=email, verified=False)
|
||||
if user is None:
|
||||
raise ValueError('User not found')
|
||||
template = jinja.get_template('register.jinja2')
|
||||
template = await template.render_async(
|
||||
base_url=settings.root_address,
|
||||
token=user.verify_key
|
||||
)
|
||||
_sendMail(template=template, to=email, subject='Verify your email')
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<style>
|
||||
.link-hover {
|
||||
background: linear-gradient(90deg, #009444, #39b54a, #8dc63f);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<div style='box-sizing: border-box;clear: both;width: 100%'>
|
||||
<table
|
||||
style='box-sizing: border-box;width: 100%;border-spacing: 0;mso-table-rspace: 0pt;mso-table-lspace: 0pt;font-size: 12px;border-collapse: separate !important'
|
||||
width='100%'>
|
||||
<tbody>
|
||||
<tr style='font-size: 12px'>
|
||||
<td style="box-sizing: border-box;font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;vertical-align: top;font-size: 12px;text-align: center;padding: 20px 0"
|
||||
valign='top' align='center'>
|
||||
<p style="margin: 0;color: #294661;font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-weight: 300;font-size: 12px;margin-bottom: 5px">
|
||||
💌 Send with love by <a href='https://mawoka.eu/?utm_source=ClassQuiz&utm_medium=Email'
|
||||
class='link-hover' target='_blank'>Mawoka</a>
|
||||
</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
+3
-32
@@ -1,18 +1,3 @@
|
||||
<!--<h1>Confirm your email-address</h1>
|
||||
<p>
|
||||
Thank you for registering at ClassQuiz.
|
||||
Please confirm your email-address by clicking on the link below.
|
||||
</p>
|
||||
|
||||
<a href='/confirm/{{TEMPLATE}}' style='text-align: center; background: #2aff10' target='_blank'>Confirm your email</a>-->
|
||||
<style>
|
||||
.link-hover {
|
||||
background: linear-gradient(90deg, #009444, #39b54a, #8dc63f);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<div style='box-sizing: border-box;display: block;max-width: 600px;margin: 0 auto;padding: 10px'><span
|
||||
style='color: transparent;height: 0;max-height: 0;max-width: 0;opacity: 0;overflow: hidden;mso-hide: all;visibility: hidden;width: 0'>Let's confirm your email address.</span>
|
||||
<div style='box-sizing: border-box;width: 100%;margin-bottom: 30px;margin-top: 15px'>
|
||||
@@ -63,7 +48,7 @@
|
||||
<tr>
|
||||
<td style="box-sizing: border-box;padding: 0;font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size: 16px;vertical-align: top;background-color: #348eda;border-radius: 2px;text-align: center;background-color: #348eda"
|
||||
valign='top' align='center'><a
|
||||
href='CONFIRM_URL'
|
||||
href='{{ base_url }}/api/v1/users/verify/{{ token }}'
|
||||
style='box-sizing: border-box;font-weight: 400;text-decoration: none;display: inline-block;margin: 0;color: #ffffff;background: linear-gradient(90deg, #009444, #39b54a, #8dc63f);border: solid 1px black;border-radius: 2px;font-size: 14px;padding: 12px 45px'
|
||||
rel='external nofollow noopener noreferrer' target='_blank'
|
||||
tabindex='-1'>Confirm Email Address</a></td>
|
||||
@@ -83,20 +68,6 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style='box-sizing: border-box;clear: both;width: 100%'>
|
||||
<table
|
||||
style='box-sizing: border-box;width: 100%;border-spacing: 0;mso-table-rspace: 0pt;mso-table-lspace: 0pt;font-size: 12px;border-collapse: separate !important'
|
||||
width='100%'>
|
||||
<tbody>
|
||||
<tr style='font-size: 12px'>
|
||||
<td style="box-sizing: border-box;font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;vertical-align: top;font-size: 12px;text-align: center;padding: 20px 0"
|
||||
valign='top' align='center'>
|
||||
<p style="margin: 0;color: #294661;font-family: 'Open Sans', 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-weight: 300;font-size: 12px;margin-bottom: 5px">
|
||||
💌 Send with love by <a href='https://mawoka.eu/?utm_source=ClassQuiz&utm_medium=Email'
|
||||
class='link-hover' target='_blank'>Mawoka</a>
|
||||
</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include 'footer.jinja2' %}
|
||||
|
||||
</div>
|
||||
@@ -6,7 +6,7 @@ from classquiz.auth import *
|
||||
from fastapi.background import BackgroundTasks
|
||||
from classquiz.emails import send_mail
|
||||
from classquiz.config import redis
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.responses import JSONResponse, RedirectResponse
|
||||
|
||||
from classquiz.db.models import *
|
||||
|
||||
@@ -96,3 +96,14 @@ async def logout(request: Request, response: Response):
|
||||
@router.get("/check")
|
||||
async def check_token(user: User = Depends(get_current_user)):
|
||||
return {"email": user.email}
|
||||
|
||||
|
||||
@router.get("/verify/{verify_key}")
|
||||
async def verify_user(verify_key: str):
|
||||
user = await User.objects.filter(verify_key=verify_key).get_or_none()
|
||||
if user is None:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
user.verified = True
|
||||
user.verify_key = None
|
||||
await user.update()
|
||||
return RedirectResponse(url="/account/login?verified=true")
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
isSubmitting = true;
|
||||
if (res.status === 200) {
|
||||
responseData.data = loginData.password === '' ? 'magic' : 'password';
|
||||
} else if (res.status === 404) {
|
||||
} else if (res.status === 401) {
|
||||
responseData.data = '404';
|
||||
} else {
|
||||
responseData.data = 'error';
|
||||
|
||||
Reference in New Issue
Block a user