mirror of
https://github.com/Llloooggg/Dyxless.git
synced 2026-03-06 10:46:24 +03:00
Добавлена возможность повторной отправки подтверждения регистрации
This commit is contained in:
@@ -26,6 +26,9 @@ app.config.update(db_settings)
|
|||||||
mail_settings = config_data["mail_settings"]
|
mail_settings = config_data["mail_settings"]
|
||||||
app.config.update(mail_settings)
|
app.config.update(mail_settings)
|
||||||
|
|
||||||
|
auth_settings = config_data["auth_settings"]
|
||||||
|
app.config.update(auth_settings)
|
||||||
|
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
mail.init_app(app)
|
mail.init_app(app)
|
||||||
|
|
||||||
|
|||||||
241
dyxless/auth.py
241
dyxless/auth.py
@@ -21,6 +21,145 @@ from .mails import send_async_email
|
|||||||
auth = Blueprint("auth", __name__)
|
auth = Blueprint("auth", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_confirmation_token(email):
|
||||||
|
serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
|
||||||
|
return serializer.dumps(
|
||||||
|
email, salt=current_app.config["SECURITY_PASSWORD_SALT"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def send_confirmation_email(email):
|
||||||
|
|
||||||
|
token = generate_confirmation_token(email)
|
||||||
|
confirm_url = url_for("auth.confirm_email", token=token, _external=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
send_async_email(
|
||||||
|
subject="Подтверждение регистрации",
|
||||||
|
recipients=[email],
|
||||||
|
html=render_template(
|
||||||
|
"mail/confirmation_mail.html", confirm_url=confirm_url
|
||||||
|
),
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@auth.route("/signup", methods=["GET", "POST"])
|
||||||
|
def signup():
|
||||||
|
|
||||||
|
if current_user.is_authenticated:
|
||||||
|
return redirect(url_for("main.index"))
|
||||||
|
|
||||||
|
elif request.method == "GET":
|
||||||
|
return render_template("signup.html")
|
||||||
|
|
||||||
|
elif request.method == "POST":
|
||||||
|
email = request.form.get("email")
|
||||||
|
username = request.form.get("username")
|
||||||
|
password = request.form.get("password")
|
||||||
|
|
||||||
|
user = User.query.filter_by(email=email).first()
|
||||||
|
|
||||||
|
if user:
|
||||||
|
flash(
|
||||||
|
Markup(
|
||||||
|
f"Указанная почта уже используется<br><a href='{url_for('auth.login')}'>Перейти к странице входа</a>"
|
||||||
|
),
|
||||||
|
"is-danger",
|
||||||
|
)
|
||||||
|
return redirect(url_for("auth.signup"))
|
||||||
|
|
||||||
|
user = User.query.filter_by(username=username).first()
|
||||||
|
|
||||||
|
if user:
|
||||||
|
flash("Указанное имя уже используется", "is-danger")
|
||||||
|
return redirect(url_for("auth.signup"))
|
||||||
|
|
||||||
|
new_user = User(
|
||||||
|
email=email,
|
||||||
|
password=password,
|
||||||
|
username=username,
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.add(new_user)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
confirmation_email_sending = send_confirmation_email(new_user.email)
|
||||||
|
|
||||||
|
if confirmation_email_sending:
|
||||||
|
flash(
|
||||||
|
"На вашу почту была выслана ссылка для подтверждения регистрации",
|
||||||
|
"is-success",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
flash(
|
||||||
|
"Что-то пошло не так, свяжитесь с администратором",
|
||||||
|
"is-danger",
|
||||||
|
)
|
||||||
|
|
||||||
|
return redirect(url_for("auth.login"))
|
||||||
|
|
||||||
|
|
||||||
|
@auth.route("/resend_confirmation", methods=["GET", "POST"])
|
||||||
|
def resend_confirmation():
|
||||||
|
|
||||||
|
if current_user.is_authenticated and current_user.is_confirmed:
|
||||||
|
return redirect(url_for("main.index"))
|
||||||
|
|
||||||
|
elif request.method == "GET":
|
||||||
|
return render_template("resend_confirmation.html")
|
||||||
|
|
||||||
|
elif request.method == "POST":
|
||||||
|
email = request.form.get("email")
|
||||||
|
|
||||||
|
confirmation_email_sending = send_confirmation_email(email)
|
||||||
|
|
||||||
|
if confirmation_email_sending:
|
||||||
|
flash(
|
||||||
|
"На вашу почту была выслана новая ссылка для подтверждения регистрации",
|
||||||
|
"is-success",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
flash(
|
||||||
|
"Что-то пошло не так, свяжитесь с администратором",
|
||||||
|
"is-danger",
|
||||||
|
)
|
||||||
|
|
||||||
|
return redirect(url_for("auth.login"))
|
||||||
|
|
||||||
|
|
||||||
|
def confirm_token(token, expiration):
|
||||||
|
serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
|
||||||
|
try:
|
||||||
|
email = serializer.loads(
|
||||||
|
token,
|
||||||
|
salt=current_app.config["SECURITY_PASSWORD_SALT"],
|
||||||
|
max_age=expiration,
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
return email
|
||||||
|
|
||||||
|
|
||||||
|
@auth.route("/confirm/<token>")
|
||||||
|
def confirm_email(token):
|
||||||
|
try:
|
||||||
|
email = confirm_token(token, current_app.config["TOKEN_EXPIRATION"])
|
||||||
|
except:
|
||||||
|
flash("Ссылка подтверждения невалидна или устарела", "is-danger")
|
||||||
|
user = User.query.filter_by(email=email).first_or_404()
|
||||||
|
if user.is_confirmed:
|
||||||
|
flash("Аккаунт уже подтвержден", "is-success")
|
||||||
|
else:
|
||||||
|
user.is_confirmed = True
|
||||||
|
db.session.commit()
|
||||||
|
flash("Ваш аккаунт подвтержден!", "is-success")
|
||||||
|
return redirect(url_for("auth.login"))
|
||||||
|
|
||||||
|
|
||||||
@auth.route("/login", methods=["GET", "POST"])
|
@auth.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
|
|
||||||
@@ -42,7 +181,9 @@ def login():
|
|||||||
return redirect(url_for("auth.login"))
|
return redirect(url_for("auth.login"))
|
||||||
elif not user.is_confirmed:
|
elif not user.is_confirmed:
|
||||||
flash(
|
flash(
|
||||||
"Аккаунт еще не активирован. Пожалуйста, проверьте вашу почту",
|
Markup(
|
||||||
|
f"Аккаунт еще не активирован. Пожалуйста, проверьте вашу почту<br><a href='{url_for('auth.resend_confirmation')}'>Повторная отправка подвтерждения регистрации</a>"
|
||||||
|
),
|
||||||
"is-warning",
|
"is-warning",
|
||||||
)
|
)
|
||||||
return redirect(url_for("auth.login"))
|
return redirect(url_for("auth.login"))
|
||||||
@@ -56,104 +197,6 @@ def login():
|
|||||||
return redirect(url_for("main.profile"))
|
return redirect(url_for("main.profile"))
|
||||||
|
|
||||||
|
|
||||||
@auth.route("/signup", methods=["GET", "POST"])
|
|
||||||
def signup():
|
|
||||||
|
|
||||||
if current_user.is_authenticated:
|
|
||||||
return redirect(url_for("main.index"))
|
|
||||||
|
|
||||||
elif request.method == "GET":
|
|
||||||
return render_template("signup.html")
|
|
||||||
|
|
||||||
elif request.method == "POST":
|
|
||||||
email = request.form.get("email")
|
|
||||||
username = request.form.get("username")
|
|
||||||
password = request.form.get("password")
|
|
||||||
|
|
||||||
user = User.query.filter_by(email=email).first()
|
|
||||||
|
|
||||||
if user:
|
|
||||||
login_url = url_for("auth.login")
|
|
||||||
flash(
|
|
||||||
Markup(
|
|
||||||
f"Указанная почта уже используется.<br><a href='{login_url}'>Перейти к странице входа</a>"
|
|
||||||
),
|
|
||||||
"is-danger",
|
|
||||||
)
|
|
||||||
return redirect(url_for("auth.signup"))
|
|
||||||
|
|
||||||
user = User.query.filter_by(username=username).first()
|
|
||||||
|
|
||||||
if user:
|
|
||||||
flash("Указанное имя уже используется", "is-danger")
|
|
||||||
return redirect(url_for("auth.signup"))
|
|
||||||
|
|
||||||
new_user = User(
|
|
||||||
email=email,
|
|
||||||
password=password,
|
|
||||||
username=username,
|
|
||||||
)
|
|
||||||
|
|
||||||
db.session.add(new_user)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
token = generate_confirmation_token(new_user.email)
|
|
||||||
confirm_url = url_for(
|
|
||||||
"auth.confirm_email", token=token, _external=True
|
|
||||||
)
|
|
||||||
|
|
||||||
send_async_email(
|
|
||||||
subject="Подтверждение регистрации",
|
|
||||||
recipients=[new_user.email],
|
|
||||||
html=render_template(
|
|
||||||
"mail/confirmation_mail.html", confirm_url=confirm_url
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
flash(
|
|
||||||
"На вашу почту была выслана ссылка для подтверждения регистрации",
|
|
||||||
"is-success",
|
|
||||||
)
|
|
||||||
|
|
||||||
return redirect(url_for("auth.login"))
|
|
||||||
|
|
||||||
|
|
||||||
def generate_confirmation_token(email):
|
|
||||||
serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
|
|
||||||
return serializer.dumps(
|
|
||||||
email, salt=current_app.config["SECURITY_PASSWORD_SALT"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def confirm_token(token, expiration=3600):
|
|
||||||
serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"])
|
|
||||||
try:
|
|
||||||
email = serializer.loads(
|
|
||||||
token,
|
|
||||||
salt=current_app.config["SECURITY_PASSWORD_SALT"],
|
|
||||||
max_age=expiration,
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
return email
|
|
||||||
|
|
||||||
|
|
||||||
@auth.route("/confirm/<token>")
|
|
||||||
def confirm_email(token):
|
|
||||||
try:
|
|
||||||
email = confirm_token(token)
|
|
||||||
except:
|
|
||||||
flash("Ссылка подтверждения невалидна или устарела", "is-danger")
|
|
||||||
user = User.query.filter_by(email=email).first_or_404()
|
|
||||||
if user.is_confirmed:
|
|
||||||
flash("Аккаунт уже подтвержден", "is-success")
|
|
||||||
else:
|
|
||||||
user.is_confirmed = True
|
|
||||||
db.session.commit()
|
|
||||||
flash("Ваш аккаунт подвтержден!", "is-success")
|
|
||||||
return redirect(url_for("auth.login"))
|
|
||||||
|
|
||||||
|
|
||||||
@auth.route("/logout")
|
@auth.route("/logout")
|
||||||
def logout():
|
def logout():
|
||||||
logout_user()
|
logout_user()
|
||||||
|
|||||||
@@ -15,5 +15,8 @@
|
|||||||
"MAIL_USE_SSL": true,
|
"MAIL_USE_SSL": true,
|
||||||
"MAIL_USERNAME": "yourmail@gmail.com",
|
"MAIL_USERNAME": "yourmail@gmail.com",
|
||||||
"MAIL_PASSWORD": "yourpass"
|
"MAIL_PASSWORD": "yourpass"
|
||||||
|
},
|
||||||
|
"auth_settings": {
|
||||||
|
"TOKEN_EXPIRATION": "3600"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="container has-text-centered">
|
<div class="container has-text-centered">
|
||||||
<section class="hero is-medium">
|
<section class="hero is-medium">
|
||||||
<div class="hero-body">
|
<div class="hero-body">
|
||||||
@@ -13,4 +14,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
29
dyxless/templates/resend_confirmation.html
Normal file
29
dyxless/templates/resend_confirmation.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<section class="hero is-medium">
|
||||||
|
<div class="hero-body">
|
||||||
|
<div class="column is-4 is-offset-4">
|
||||||
|
<form class="box" method="POST" action="/resend_confirmation" >
|
||||||
|
<h3 class="title">Повторная отправка подтверждения регистрации</h3>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Введите email, который был указан при регистрации</label>
|
||||||
|
<p class="control has-icons-left">
|
||||||
|
<input class="input" type="email" name="email" placeholder="yourmail@example.com" required>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-success is-outlined is-fullwidth" type="submit">Отправить подтверждение</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Email</label>
|
<label class="label">Email</label>
|
||||||
<p class="control has-icons-left">
|
<p class="control has-icons-left">
|
||||||
<input class="input" type="email" name="email" placeholder="you@mail.com" required>
|
<input class="input" type="email" name="email" placeholder="yourmail@mail.com" required>
|
||||||
<span class="icon is-small is-left">
|
<span class="icon is-small is-left">
|
||||||
<i class="fas fa-envelope"></i>
|
<i class="fas fa-envelope"></i>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user