From 7288df8ef0c7c98369f1d208f16bbb455547850f Mon Sep 17 00:00:00 2001 From: a2-imeri <alfret2.imeri@live.uwe.ac.uk> Date: Thu, 9 Mar 2023 09:19:30 +0000 Subject: [PATCH] Add email verification --- store/models.py | 49 +++++- store/routes.py | 166 ++++++++++++++++++-- store/site.db | Bin 36864 -> 40960 bytes store/static/main.css | 24 ++- store/static/oldmain.css | 69 ++++++++ store/templates/account.html | 9 ++ store/templates/accountDetails.html | 10 ++ store/templates/base.html | 67 +++++--- store/templates/login.html | 23 ++- store/templates/register.html | 11 ++ store/templates/reset_password.html | 21 +++ store/templates/reset_password_confirm.html | 26 +++ store/templates/verify_code.html | 21 +++ store/utility.py | 13 +- 14 files changed, 446 insertions(+), 63 deletions(-) create mode 100644 store/static/oldmain.css create mode 100644 store/templates/account.html create mode 100644 store/templates/accountDetails.html create mode 100644 store/templates/reset_password.html create mode 100644 store/templates/reset_password_confirm.html create mode 100644 store/templates/verify_code.html diff --git a/store/models.py b/store/models.py index 145f149..3857678 100644 --- a/store/models.py +++ b/store/models.py @@ -2,6 +2,9 @@ #from flask import current_app from store import db +from flask_login import UserMixin +from werkzeug.security import generate_password_hash, check_password_hash + # Helper tables for many to many relationships, see https://flask-sqlalchemy.palletsprojects.com/en/2.x/models/#many-to-many-relationships. items = db.Table('Items', @@ -47,13 +50,45 @@ class ItemSet(db.Model): # database for user register it will be added more cullomns in the future # that is a basic implementation to check if it works # Freddy implemented that -class User(db.Model): - id = db.Column(db.Integer, primary_key=True) - username = db.Column(db.String(256), nullable=False) - password = db.Column(db.String(256), nullable=False) +#UserMixin is to inherit flask-login implementetion +class User( db.Model, UserMixin): + user_id = db.Column(db.Integer, primary_key=True, autoincrement=True) + username = db.Column(db.String(256), nullable=False, unique=True) + email = db.Column(db.String(256), nullable=False) + phone_number = db.Column(db.Integer, nullable=False) + password_hash = db.Column(db.String(256), nullable=False) + @classmethod - def insert(cls, username, password): - user = cls(username=username, password=password) + def create_user(cls, username: str, password: str,email: str , phone_number: int ) : + password_hash = generate_password_hash(password) + user = cls(username=username, password_hash= password_hash, email=email, phone_number=phone_number) db.session.add(user) - db \ No newline at end of file + db.session.commit() + return user + + @classmethod + def update_passwords(cls, user_id: int, password: str): + user = cls.query.get(user_id) + password_hash = generate_password_hash(password) + user.password_hash = password_hash + db.session.commit() + + + def is_active(self) -> bool: + return True + + + def get_userDetails(self): + lis = [self.username, self.email, self.phone_number] + return lis + + + def get_id(self): + return str(self.user_id) + + def check_password(self, password: str) -> bool: + return check_password_hash(self.password_hash, password) + + def __repr__(self) -> str: + return f"User(user_id={self.user_id}, username='{self.username}')" \ No newline at end of file diff --git a/store/routes.py b/store/routes.py index abebd48..10dcbca 100644 --- a/store/routes.py +++ b/store/routes.py @@ -1,8 +1,47 @@ from store import app, db -from flask import render_template, request, flash, redirect, url_for +from flask import render_template, request, flash, redirect, url_for, Flask, session from store.utility import * +# Official flask-login doc free liecense +#https://flask-login.readthedocs.io/en/latest/ +from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user +#Official flask-mail docum +#https://pythonhosted.org/Flask-Mail/ +from flask_mail import Mail, Message + + + + + +#Email configuration +app.config['MAIL_SERVER']='smtp.gmail.com' +app.config['MAIL_PORT'] = 465 +app.config['MAIL_USERNAME'] = 'antique.store7111@gmail.com' +app.config['MAIL_PASSWORD'] = 'nbouhrtaurcefgvj' +app.config['MAIL_USE_TLS'] = False +app.config['MAIL_USE_SSL'] = True + +mail = Mail(app) + + +#Create an instance of the LoginManager class and initialise +#it with your Flask application to begin using Flask-Login. +login_manager = LoginManager() +login_manager.init_app(app) +login_manager.login_view = 'login' + + + +@login_manager.user_loader +def load_user(user_id): + return User.query.get(int(user_id)) + +def get_user_id(): + if current_user.is_authenticated: + return current_user.user_id + else: + return None @app.route("/") @app.route("/index") @@ -10,6 +49,7 @@ def index(): return render_template('index.html', title='Home') # If the title is unspecified then a default is used that is set in base.html @app.route("/basket") +@login_required def basket(): return render_template('basket.html', title='Basket') @@ -21,26 +61,124 @@ def items(): def itemSets(): return render_template('itemSets.html', title='Item Sets') -@app.route("/login") -def login(): - return render_template('login.html', title='Login') + @app.route("/register", methods=['POST', 'GET']) def register(): - if request.method == "POST": + if request.method == "POST": + error = None # errors username = request.form['username'] password = request.form['password'] - #register_user(username,password ) - new_user = User(username=username, password= password) - db.session.add(new_user) - db.session.commit() - flash('Your account has been created! You are now able to log in', 'success') - return redirect(url_for('index')) - - return render_template('register.html', title='register') + email = request.form['email'] + phone_number = request.form['phone_number'] + user_exists = User.query.filter_by(username=username).first() + if user_exists: + error = 'The username you chose is already taken.' + return render_template('register.html', title='Register', error=error) + else: + new_user = User.create_user(username=username, password=password, email = email, phone_number = phone_number) + flash('Your account has been created! You are now able to log in.', 'success') + return redirect(url_for('index')) + return render_template('register.html', title='Register') +@app.route("/login", methods=['POST', 'GET']) +def login(): + if request.method == "POST": + username = request.form['username'] + password = request.form['password'] + user = User.query.filter_by(username=username).first() + if user and user.check_password(password): + login_user(user) + return redirect(url_for('index')) + else: + flash('Login unsuccessful. Please check username and password.', 'danger') + return render_template('login.html', title='Login') + + +@app.route('/logout') +@login_required +def logout(): + logout_user() + return redirect(url_for('index')) + + + +@app.route("/account") +@login_required +def account(): + return render_template('account.html', title='account') + +@app.route("/accountDetails") +@login_required +def accountDetails(): + a = get_user_id() + user = User.query.filter_by(user_id = a).first() + return render_template('accountDetails.html', user=user) + + + + +@app.route('/reset_password', methods=['GET', 'POST']) +def reset_password(): + if request.method == 'POST': + email = request.form['email'] + print("the email was :", email) + user = User.query.filter_by(email=email).first() + if user: + verification_code = getcode() + session['verification_code'] = verification_code + session['user_id'] = user.user_id + msg = Message('Password Reset Verification Code', sender='your-email@gmail.com', recipients=[email]) + msg.body = f"Hello, Your password reset verification code is {verification_code}" + mail.send(msg) + flash('A verification code has been sent to your email') + return redirect(url_for('verify_code')) + else: + flash('Invalid email address') + return render_template('reset_password.html') + +@app.route('/verify_code', methods=['GET', 'POST']) +def verify_code(): + if 'user_id' not in session or 'verification_code' not in session: + return redirect(url_for('reset_password')) + if request.method == 'POST': + verification_code = request.form['verification_code'] + if int(verification_code) == session['verification_code']: + session.pop('verification_code', None) + return redirect(url_for('reset_password_confirm')) + else: + flash('Invalid verification code') + return render_template('verify_code.html') + + + + +@app.route('/reset_password_confirm', methods=['GET', 'POST']) +def reset_password_confirm(): + if 'user_id' not in session: + return redirect(url_for('reset_password')) + user_id = session['user_id'] + if request.method == 'POST': + password = request.form['password'] + confirm_password = request.form['confirm_password'] + if password == confirm_password: + User.update_passwords(user_id, password) + session.pop('user_id', None) + flash('Your password has been successfully reset') + return redirect(url_for('login')) + else: + flash('Passwords do not match') + return render_template('reset_password_confirm.html') + + + +def getcode(): + randomchar = [str(random.choice(string.ascii_letters)) + str(random.randint(10,99)) for _ in range(4)] + randomdString = "" + for i in range(0, 4): + randomdString += randomchar[i % 4] - \ No newline at end of file + return randomdString \ No newline at end of file diff --git a/store/site.db b/store/site.db index d0ce28bb3cf992ceb0252d3a9fa53b791c2a52f3..fea106e361dc25f6ae2631941a7eee8a15d041cb 100644 GIT binary patch delta 1571 zcmZozz|?SnX@az%3IhWJ7Xt#wP1G@#S7Ffep1{lJ$-v2VmVtjJ-zUC6UL`&S?%zD$ zxz2K*+SusN#oSoMF*%l7hLLk}756<x&dHHHdeU5tm2B+d;^K_WfhCDaIjNo{sky~q zf_?HLp2w{0Y~r@!lVf>ggp1=1!Qvc^)hz7dqN0q=k&_SdDzlUprxs0qz#}pFH?I<F zYHng?&SXb^Y3_{tywv!-(%hufqR9t&L?_Ggaj?c`Bo=2(cI20uY|qE53ep&#nWCwq zz{MHr=NTC4s-OW9%S+5n)#TDtXJr$&7M&c+BOweDjW-05Yzzzx93Zc64&>Xc$j8cW z#=w7ve+R!Ae-i)X&4L0d{F9^XTN!gEKd@Jre8*mcjgh~Kfxl|Apg;kCeIqj?JA=42 zQ=?~MN^WLeT2X3BN~K<AZfa4cp+h>z<$B5axdyrgN!clBMpnfciAJVoR)(eq1_lNy zMHvBR`6edGD#qrPCdTF#CT7XW$;rm%X2z*$#%5;bX~~JEDaMH@sm94hrlux_rYT95 zMuwI~CPt}-rY1?L$;pCAM#%=Isg|I)W90wN!2f--pu=1Kcn)T9POyV`85kJU`ED`r z|KR_?|C0Y9|1JJY{HOU3^Y7u`!oQY(DgQkF>HPit?feb=75s(#nfyuoQT)ODKKw5H zHvA_1I{Yg9GW??ay!>o@|M<T1ec*e^_lWP-W<h}#zIrxwW+q0%%}lIn%uJky3s_Y_ z)Ld2-5T(Yd45Fmilt5}WF|jIwxYBG2%uI|%TuiL;Ag%<P97uKp6PqlE-pIrz1CnNE zVv`2ZY)ouYAo2A~Y?2^8D-){(NLxLtIGAE)69WmeFtLh)_;qX|Al2)bScRFHI1LKf zgg~-POss++Sz|T<knA!hHhz#WBNHnhNYy`9UXZK_8xKf!EfXs@h^x=W1>!DcV&w!W z`oqQn(!;>S$`0cGWMc!#)^BHGWd-qHv9W;o+n89HLENWoOd#$SCN@S8y_E?RIqG~{ z82ID)pYvbiKgz#_zl-0N?>paBzGr-A`4{sS@K56R<2U6y%D0z)HGc*FEdDTlWxoIX z9DH~Aw(!5_|G|Hc|1AF={zm?Eeph}Sekp!IzIP0pg#=>x>N!}L7(tPs&d$Qb$!NGh z4MNXVh0tm$5L!wZqHq(F5=1~+5iDTD#iRfckdOxp7;a#agD^HS$$}Y1>`XEc1{;$! zm|?h{Neav`Vy$PAglMmqfY8k15E&LGF^E8&C|JO79g_%Hz@ShVEMUaMBm@>PG!_I4 z7%pQH05gmjnfSpn2LJfLw4n(vSi*2E6Awf{pBo~uw4R9zEMoA76D(rHz{CL&_{k0y zFx<|>1`&A03K7`G!~zj`$_x?M!o<YR!o<jFxRnW%UHJJc8Th~RzvF+(e~14v|0({1 z{5$y9^DpC{%Rhy`o4<*_5>!|~@n#tT5B@-Qer6^ngMTSG?0g``pOhSSUJ&DHN)9^@ zGZT~Hrj#OfZV+RAN)bC3h_N=Mh@BI}&`+7n&H-ZRrc7pM2Qf5KCQm+9Z>7Y~pAB+I zJ^x$&QvS#M+5EftH}Ws%zsY}||0w@l{>l8En*{}2`6D@5n3xzrw(~<+e^PSzAgre; qIlN#N$N@YM*7}qpZU}2_N)Z=?rJpjH6T;F>nalxUfn0H<-v$8H>^s{4 delta 1217 zcmZoTz|^pSX@az%2m=EHCj$ZqP1G@#6=Bfxp1{kyo`Hiqih+M7-zUC6-t9acye-^O zJmH%K1@3V%H&(GvzQ85J$T9gX*F8p#$!ECrSU4LiSttMF7Gq?aEXwnkm5oi@R($dW zZW-y~ctg*U)ZAir1_lNWkX?=9EbQW<qKr*~lXZBNC(HATPtN95ntYa*W3nT^)Z};k zLYo8mHY@V5@JBK5-{FtqZ{y#-Sx~@>f3lf<>*V|Ps!R+5n*{})^G}>09LCGQz@W}| zi-G?K{|EjT{15nV@L%LV#eax@H~$v?wfxKY=kZVD@8fUhujjAeFW}GQPvno{590Uc zcjmX@H{sXeSLK)G7vtySXXj_&`@#2-?-k!8zFV6G1zPy(+0>bt7>(GN*wjEYD-)|K zGZUvFGph=Ss%KLMiLx-UDuK9ltcuJ`oCbw#3d~H5hU=JE<w4wkY;qt)OiZk@AVtP( zG9cMyOl;C1VMZoaDUh%Un<PkhEfcE*h^x;g4&pAYXJQot8S;ls6r`GgiB$x|{mCW_ zlHSh5Dg@%bViN>$w=uB_fVfZD_(9yQOl*80dNUInFNog4#L5FQdjTsqh*D$a0#S2W zIYE>Z8wW_uCMH&P5LcR&4Ma)Qv$2Bg<zixE0ZDIQVq*sJ*_qgwK>YPgY>Xg!BNG=m z4z@7xJ?F3BPv;Ngcjf!RcZ~lG|7QLp{EPWb_&NEN`R?<b<6q4`o8N|CkYAhcJ^y?D zyZk@+ck_4hPvURj&*zWh_vM%3XW+ZWx0i1V|1<t844Z`nV)^PhSeO_=k)RG?urjH! zvoLWo8ZxUw=z0~11PhZgM4(OyOdAv`f+Y;sF)2U<{>g&{jF_0@zygNGvS0zjWlS<) zh7lu^G(^Tk3M^o_mZ@G6BBCz=5n0M44i+%@BL)^QVqg-52>cWQ3m9%^5{3x85`qY9 zV-kc2JQaWlY-QqyFg7#sK^R+@c)>~x7w|x6HEsw!H;)U#km7`>+{DBI5s+qw&=PE5 z2_r5hRxrbG0}~6FVZ_eF3}zUvXJTS!VPfPo+{gsVE<F5G82G>QzvF+(e~14v|0({1 z{5$y9^DpC{%Rgnapg;+~89NU%6O*BS%4BwK5JNX*GCLQDp^-9~ofE{^lv2db0b;CA zDPm^_G1jIOO+M9crNG1A2{QaG|6~5S{FC`R`ET-{=ReB7n|~w!as~zlrp<x^sr=TQ qEKE#{APaaPEZvmJ+z^&V%49AGYg0-QCxo>=rHBK<0@-q8z6}8C!`HU} diff --git a/store/static/main.css b/store/static/main.css index 34c795d..b024be0 100644 --- a/store/static/main.css +++ b/store/static/main.css @@ -1,6 +1,4 @@ -body { - background-color: white; -} + footer { background-color: black; @@ -17,7 +15,7 @@ div{ width:100%; } -li a { +.navbar li a { color:white; display: block; text-align: center; @@ -25,7 +23,7 @@ li a { padding: 14px 16px; } -ul { +.navbar ul { list-style-type: none; margin: 0; padding: 0; @@ -43,11 +41,11 @@ input[type=text] { font-size: 17px; } -li { +.navbar li { float:left; } -li a:hover { +.navbar li a:hover { background-color: white; color:black; } @@ -59,4 +57,14 @@ li a:hover { h1{ color: black; -} \ No newline at end of file + font-size: 30px; +} + +.error{ + text-decoration: none; + color:red; + font-size: 30px; +} + + + diff --git a/store/static/oldmain.css b/store/static/oldmain.css new file mode 100644 index 0000000..5a6d56f --- /dev/null +++ b/store/static/oldmain.css @@ -0,0 +1,69 @@ +body { + background-color: white; +} + +footer { + background-color: black; + color: white; + position: fixed; + bottom:0; + left:0; + width:100%; +} + +div{ + position:fixed; + left:0; + width:100%; +} + +.navbar li a { + color:white; + display: block; + text-align: center; + text-decoration: none; + padding: 14px 16px; +} + +.navbar ul { + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; + background-color: black; +} + + +input[type=text] { + float: left; + padding: 6px; + border: none; + margin-top: 8px; + margin-right: 16px; + font-size: 17px; +} + +.navbar li { + float:left; +} + +.navbar li a:hover { + background-color: white; + color:black; +} + +*{ + text-align: center; + font-family: sans-serif; +} + +h1{ + color: black; + font-size: 30px; +} + +.error{ + text-decoration: none; + color:red; + font-size: 30px; +} \ No newline at end of file diff --git a/store/templates/account.html b/store/templates/account.html new file mode 100644 index 0000000..f341255 --- /dev/null +++ b/store/templates/account.html @@ -0,0 +1,9 @@ +{%extends 'base.html' %} + +{% block content %} + {% block title %} Account{% endblock %} + <h1>account Information</h1> + <ul> + <li><a href="{{ url_for('accountDetails', user_id=current_user.id)}}">View my Account details</a></li> + </ul> +{% endblock %} diff --git a/store/templates/accountDetails.html b/store/templates/accountDetails.html new file mode 100644 index 0000000..3853450 --- /dev/null +++ b/store/templates/accountDetails.html @@ -0,0 +1,10 @@ +{%extends 'base.html' %} + +{% block content %} + {% block title %} Account{% endblock %} + <h1>Account Details</h1> + <h1>Welcome, {{ user.username }}</h1> + <p>Your email address is: {{ user.email }}</p> + <p>Your Phone Number is: {{ user.phone_number }}</p> + +{% endblock %} diff --git a/store/templates/base.html b/store/templates/base.html index c5651ee..fd45e13 100644 --- a/store/templates/base.html +++ b/store/templates/base.html @@ -3,35 +3,58 @@ <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>{% block title %}{% endblock%}</title> - <link rel="stylesheet" type="text/css" href="../static/main.css"> <!-- Load the CSS. --> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}"> <!-- Load the CSS. --> </head> <body> - <header> - - <a class="logo" href="{{ url_for('index')}}">ANTIQUES ONLINE</a></li> + <header class="header"> + <a class="logo" href="{{ url_for('index')}}">ANTIQUES ONLINE</a> </header> - <div> - <ul> - <li><a href="{{ url_for('basket')}}">Basket</a></li> - <li><a href="{{ url_for('items')}}">Items</a></li> - <li><a href="{{ url_for('itemSets')}}">Item Sets</a></li> - <li><a href="{{ url_for('login')}}">Login</a></li>Register - <li><a href="{{ url_for('register')}}">Register</a></li> + <nav class="navbar"> + <ul class="navbar-list"> + <li><a href="{{ url_for('basket')}}">Basket</a></li> + <li><a href="{{ url_for('items')}}">Items</a></li> + <li><a href="{{ url_for('itemSets')}}">Item Sets</a></li> + + {% if current_user.is_authenticated %} + <li><a href="{{ url_for('account')}}">Account</a></li> + <li><a href="{{ url_for('logout')}}">Logout</a></li> + <li><a class="welcome">Welcome, {{ current_user.username }}!</a></li> + {% else %} + <li><a href="{{ url_for('login')}}">Login</a></li> + <li><a href="{{ url_for('register')}}">Register</a></li> + {% endif %} + + <li class="search"> + <form> + <button type="submit"><i class="fa fa-search"></i></button> + <input type="text" placeholder="Search..."> + </form> + </li> + </ul> + </nav> + + <div class="container"> + {% with messages = get_flashed_messages() %} + {% if messages %} + <ul class="flashes"> + {% for message in messages %} + <li class="error">{{ message }}</li> + {% endfor %} + </ul> + {% endif %} + {% endwith %} + + {% block content %} - <input type="text" placeholder="Search..."> - </ul> - </div> - - {% block content %} - - {% endblock %} <!-- Where HTML will go when extended. --> - - <footer> - <p>Contact Info: mail@mail.com + {% endblock %} <!-- Where HTML will go when extended. --> + </div> + + <footer class="footer"> + <p>Contact Info: mail@mail.com <br> Phone Number 0000 000 0000</p> - </footer> + </footer> </body> </html> diff --git a/store/templates/login.html b/store/templates/login.html index ecb8f69..b66a932 100644 --- a/store/templates/login.html +++ b/store/templates/login.html @@ -1,5 +1,24 @@ -{%extends 'base.html' %} + +{%extends 'base.html' %} {% block content %} - {% block title %} Login | Antiques Online {% endblock %} + {% block title %} login | Antiques Online {% endblock %} + + +<form method="POST" action="{{ url_for('login') }}" style="float: center; text-align: center;"> + + <div class="container"> + <h1>Login</h1> + + <label for="username"><b>username</b></label> + <input type="username" placeholder="Enter username" name="username" id="username" required> + + <label for="password"><b>Password</b></label> + <input type="password" placeholder="Enter Password" name="password" id="password" required> + <a href="{{ url_for('reset_password')}}">Forgot my Password</a> + <input class="button" type="submit" value="Login" > + + </div> + + </form> {% endblock %} \ No newline at end of file diff --git a/store/templates/register.html b/store/templates/register.html index 3646bb8..77f4f42 100644 --- a/store/templates/register.html +++ b/store/templates/register.html @@ -8,10 +8,21 @@ <form method="POST" action="{{ url_for('register') }}" style="float: center; text-align: center;"> <div class="container"> + <h1>Register</h1> + + {% if error %} + <p class=error><strong>Error:</strong> {{ error }} + {% endif %} <label for="username"><b>username</b></label> <input type="username" placeholder="Enter username" name="username" id="username" required> + + <label for="email"><b>E-mail</b></label> + <input type="email" placeholder="Enter E-mail" name="email" id="email" required> + + <label for="phone_number"><b>Phone Number</b></label> + <input type="phone_number" placeholder="Enter Number" name="phone_number" id="phone_number" required> <label for="password"><b>Password</b></label> <input type="password" placeholder="Enter Password" name="password" id="password" required> diff --git a/store/templates/reset_password.html b/store/templates/reset_password.html new file mode 100644 index 0000000..74f003d --- /dev/null +++ b/store/templates/reset_password.html @@ -0,0 +1,21 @@ + + +{%extends 'base.html' %} +{% block content %} + {% block title %} Reset code {% endblock %} + + +<form method="POST" action="{{ url_for('reset_password') }}" style="float: center; text-align: center;"> + + <div class="container"> + <h1>email verify</h1> + + <label for="email"><b>Enter your email</b></label> + <input type="email" placeholder="Enter your email" name="email" id="email" required> + + <input class="button" type="submit" value="Reset Password" > + + </div> + + </form> +{% endblock %} \ No newline at end of file diff --git a/store/templates/reset_password_confirm.html b/store/templates/reset_password_confirm.html new file mode 100644 index 0000000..72ece7e --- /dev/null +++ b/store/templates/reset_password_confirm.html @@ -0,0 +1,26 @@ + +{%extends 'base.html' %} +{% block content %} + {% block title %} Verify reset Password {% endblock %} + + + <form method="POST" action="{{ url_for('reset_password_confirm') }}" style="float: center; text-align: center;"> + + <div class="container"> + + <h1>Reset Password</h1> + + + <label for="password"><b>Password</b></label> + <input type="password" placeholder="Enter Password" name="password" id="password" required> + + + <label for="confirm_password"><b>confirm password</b></label> + <input type="confirm_password" placeholder="confirm password" name="confirm_password" id="confirm_password" required> + + <input class="button" type="submit" value="confirm password" > + + </div> + + </form> +{% endblock %} \ No newline at end of file diff --git a/store/templates/verify_code.html b/store/templates/verify_code.html new file mode 100644 index 0000000..8022e30 --- /dev/null +++ b/store/templates/verify_code.html @@ -0,0 +1,21 @@ + + +{%extends 'base.html' %} +{% block content %} + {% block title %} Verify reset Password {% endblock %} + + +<form method="POST" action="{{ url_for('verify_code') }}" style="float: center; text-align: center;"> + + <div class="container"> + <h1>Login</h1> + + <label for="verification_code"><b>Enter your code </b></label> + <input type="verification_code" placeholder="Enter your code " name="verification_code" id="verification_code" required> + + <input class="button" type="submit" value="Reset Password" > + + </div> + + </form> +{% endblock %} \ No newline at end of file diff --git a/store/utility.py b/store/utility.py index 4d5b895..85c943c 100644 --- a/store/utility.py +++ b/store/utility.py @@ -3,7 +3,8 @@ from store.models import * from sqlalchemy import select from store import * - +import random +import string # for autegenarating letters # Difference between filter and filter_by: https://stackoverflow.com/a/31560897 def get_unsold_items(): @@ -25,12 +26,4 @@ def get_itemsets_by_item_id(item_id): item_set_contained_id.append(item_set) return item_set_contained_id -# def get_itemsets_by_item_id(item_id): -# item_sets = select(ItemSet).where(ItemSet.items.any(Item.id==item_id)) -# flask_item_sets = db.session.execute(item_sets).all() -# flask_item_set = flask_item_sets[0][0] - - -# return 0 - - \ No newline at end of file + -- GitLab