Forgot password and reset password
This commit is contained in:
		
							parent
							
								
									fdb8d7a777
								
							
						
					
					
						commit
						83ba6ca330
					
				@ -18,6 +18,8 @@ import  modules.public.register as public_register
 | 
			
		||||
import  modules.public.notme    as public_notme
 | 
			
		||||
import  modules.public.verify   as public_verify
 | 
			
		||||
import  modules.public.login    as public_login
 | 
			
		||||
import  modules.public.forgot   as public_forgot
 | 
			
		||||
import  modules.public.reset    as public_reset
 | 
			
		||||
 | 
			
		||||
import  modules.api.auth        as api_auth
 | 
			
		||||
 | 
			
		||||
@ -69,6 +71,24 @@ def index():
 | 
			
		||||
    }
 | 
			
		||||
    return public_login.login().html(params)
 | 
			
		||||
 | 
			
		||||
@app.route('/forgot')
 | 
			
		||||
def index():
 | 
			
		||||
    params = {
 | 
			
		||||
        "mako"  : {
 | 
			
		||||
            "website" : template_public.main(directory.page["public"], "forgot")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return public_forgot.forgot().html(params)
 | 
			
		||||
 | 
			
		||||
@app.route('/reset', method='GET')
 | 
			
		||||
def index():
 | 
			
		||||
    params = {
 | 
			
		||||
        "mako"  : {
 | 
			
		||||
            "website" : template_public.main(directory.page["public"], "reset")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return public_reset.reset().html(params)
 | 
			
		||||
 | 
			
		||||
@app.route('/logout')
 | 
			
		||||
def index():
 | 
			
		||||
    beaker_session = request.environ.get('beaker.session')
 | 
			
		||||
@ -174,3 +194,24 @@ def index():
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(str(e))
 | 
			
		||||
        return json.dumps({}, indent = 2).encode()
 | 
			
		||||
 | 
			
		||||
@app.route('/api/auth/password/forgot/<type>', method='POST')
 | 
			
		||||
def index(type):
 | 
			
		||||
    try:
 | 
			
		||||
        params = request.json
 | 
			
		||||
        params["type"] = type
 | 
			
		||||
        if type == "send":
 | 
			
		||||
            params["mako"] = {
 | 
			
		||||
                "email" : template_email.main(directory.page["email"], "reset")
 | 
			
		||||
            }
 | 
			
		||||
        elif type == "change":
 | 
			
		||||
            params["mako"] = {
 | 
			
		||||
                "email" : template_email.main(directory.page["email"], "message")
 | 
			
		||||
            }
 | 
			
		||||
        else:
 | 
			
		||||
            pass
 | 
			
		||||
        response.content_type = 'application/json'
 | 
			
		||||
        return json.dumps(api_auth.auth().forgot(params), indent = 2).encode()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(str(e))
 | 
			
		||||
        return json.dumps({}, indent = 2).encode()
 | 
			
		||||
 | 
			
		||||
@ -471,14 +471,16 @@ class auth:
 | 
			
		||||
        type        = params["type"     ] # POST: send / change
 | 
			
		||||
        self.cursor.execute("BEGIN;")
 | 
			
		||||
        try:
 | 
			
		||||
            loggorilla.fyinf(APIADDR, f"type: {type}")
 | 
			
		||||
            if type == "send":
 | 
			
		||||
                loggorilla.prcss(APIADDR, "Define parameters inside decision")
 | 
			
		||||
                email = params["email"].lower()
 | 
			
		||||
                loggorilla.prcss(APIADDR, "Get dependency data")
 | 
			
		||||
                self.cursor.execute(f"SELECT COUNT(*) AS `count`, auth_profile.token, auth_profile.email FROM auth_profile_verification INNER JOIN auth_profile ON auth_profile.id = auth_profile_verification.auth_profile WHERE auth_profile.email = %s AND auth_profile_verification.type = 'email' AND auth_profile_verification.verified = 1 ; ", (email,) )
 | 
			
		||||
                result_verified = self.cursor.fetchone()
 | 
			
		||||
                token = result_verified["token"].decode()
 | 
			
		||||
                if result_verified["count"] >= 1:
 | 
			
		||||
                    loggorilla.prcss(APIADDR, "Get token")
 | 
			
		||||
                    token = result_verified["token"].decode()
 | 
			
		||||
                    loggorilla.prcss(APIADDR, "Generate URL")
 | 
			
		||||
                    # TODO: set expired time
 | 
			
		||||
                    expired = datetime.datetime.now() + datetime.timedelta(minutes=30) # Can be hours or minutes
 | 
			
		||||
@ -493,14 +495,13 @@ class auth:
 | 
			
		||||
                    loggorilla.prcss(APIADDR, "Sending email")
 | 
			
		||||
                    self.smtpconfig['subject'   ] = f"{globalvar.title} forgot password"
 | 
			
		||||
                    self.smtpconfig['to'        ] = email
 | 
			
		||||
                    self.smtpconfig['text'      ] = f"Please visit this link to change password: {change_forgot_url}. Avoid the link if you are not request this."
 | 
			
		||||
                    self.smtpconfig['html'      ] = Template(params["mako"]["email"]['template']).render(
 | 
			
		||||
                    self.smtpconfig['text'      ] = f"Please visit this link to reset password: {change_forgot_url}. Avoid the link if you are not request this."
 | 
			
		||||
                    self.smtpconfig['html'      ] = Template(params["mako"]["email"]['index']).render(
 | 
			
		||||
                        title       = globalvar.title,
 | 
			
		||||
                        heading     = self.smtpconfig['subject'],
 | 
			
		||||
                        image       = "https://colorlib.com/etc/email-template/10/images/email.png",
 | 
			
		||||
                        unsubscribe = "#",
 | 
			
		||||
                        header      = globalvar.title,
 | 
			
		||||
                        copyright   = globalvar.copyright,
 | 
			
		||||
                        container   = Template(params["mako"]["email"]['container']).render(
 | 
			
		||||
                            change = change_forgot_url
 | 
			
		||||
                            reset = change_forgot_url
 | 
			
		||||
            			)
 | 
			
		||||
                    )
 | 
			
		||||
                    sendwave.smtp(self.smtpconfig)
 | 
			
		||||
@ -544,11 +545,10 @@ class auth:
 | 
			
		||||
                    self.smtpconfig['subject'   ] = f"{globalvar.title} password change success"
 | 
			
		||||
                    self.smtpconfig['to'        ] = email
 | 
			
		||||
                    self.smtpconfig['text'      ] = f"You had change your password."
 | 
			
		||||
                    self.smtpconfig['html'      ] = Template(params["mako"]["email"]['template']).render(
 | 
			
		||||
                    self.smtpconfig['html'      ] = Template(params["mako"]["email"]['index']).render(
 | 
			
		||||
                        title       = globalvar.title,
 | 
			
		||||
                        heading     = self.smtpconfig['subject'],
 | 
			
		||||
                        image       = "https://colorlib.com/etc/email-template/10/images/email.png",
 | 
			
		||||
                        unsubscribe = "#",
 | 
			
		||||
                        header      = globalvar.title,
 | 
			
		||||
                        copyright   = globalvar.copyright,
 | 
			
		||||
                        container   = Template(params["mako"]["email"]['container']).render(
 | 
			
		||||
                            message = f"You had change your password."
 | 
			
		||||
            			)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								app/modules/public/forgot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/modules/public/forgot.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
from    mako.template       import  Template
 | 
			
		||||
from    config              import  globalvar
 | 
			
		||||
from    bottle              import  request
 | 
			
		||||
 | 
			
		||||
class forgot:
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def html(self, params):
 | 
			
		||||
        active_page     = "Forgot"
 | 
			
		||||
        user_roles      = [0]
 | 
			
		||||
        beaker_session  = request.environ.get('beaker.session')
 | 
			
		||||
        jwt             = beaker_session["token"] if "token" in beaker_session else None
 | 
			
		||||
        if jwt is not None:
 | 
			
		||||
            return redirect('/')
 | 
			
		||||
        else:
 | 
			
		||||
            return Template(params["mako"]["website"]['index']).render(
 | 
			
		||||
                title	= globalvar.title,
 | 
			
		||||
                header	= globalvar.header,
 | 
			
		||||
                navbar	= Template(params["mako"]["website"]['navbar']).render(
 | 
			
		||||
                    menu		= globalvar.menu['public']['navbar'],
 | 
			
		||||
                    user_roles	= user_roles,
 | 
			
		||||
                    active_page	= active_page
 | 
			
		||||
                ),
 | 
			
		||||
                footer	= Template(params["mako"]["website"]['footer']).render(
 | 
			
		||||
                    copyright	= globalvar.copyright,
 | 
			
		||||
                ),
 | 
			
		||||
                container	= Template(params["mako"]["website"]['container']).render()
 | 
			
		||||
            )
 | 
			
		||||
							
								
								
									
										30
									
								
								app/modules/public/reset.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								app/modules/public/reset.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
from    mako.template       import  Template
 | 
			
		||||
from    config              import  globalvar
 | 
			
		||||
from    bottle              import  request
 | 
			
		||||
 | 
			
		||||
class reset:
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def html(self, params):
 | 
			
		||||
        active_page     = "Reset"
 | 
			
		||||
        user_roles      = [0]
 | 
			
		||||
        beaker_session  = request.environ.get('beaker.session')
 | 
			
		||||
        jwt             = beaker_session["token"] if "token" in beaker_session else None
 | 
			
		||||
        if jwt is not None:
 | 
			
		||||
            return redirect('/')
 | 
			
		||||
        else:
 | 
			
		||||
            return Template(params["mako"]["website"]['index']).render(
 | 
			
		||||
                title	= globalvar.title,
 | 
			
		||||
                header	= globalvar.header,
 | 
			
		||||
                navbar	= Template(params["mako"]["website"]['navbar']).render(
 | 
			
		||||
                    menu		= globalvar.menu['public']['navbar'],
 | 
			
		||||
                    user_roles	= user_roles,
 | 
			
		||||
                    active_page	= active_page
 | 
			
		||||
                ),
 | 
			
		||||
                footer	= Template(params["mako"]["website"]['footer']).render(
 | 
			
		||||
                    copyright	= globalvar.copyright,
 | 
			
		||||
                ),
 | 
			
		||||
                container	= Template(params["mako"]["website"]['container']).render()
 | 
			
		||||
            )
 | 
			
		||||
							
								
								
									
										6
									
								
								app/pages/email/reset.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/pages/email/reset.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<h2>Forgot Password</h2>
 | 
			
		||||
 | 
			
		||||
<p>Please visit this link below to reset password. <b>Avoid the link if you are not request this.</b> </p>
 | 
			
		||||
<a href="${reset}" class="button">
 | 
			
		||||
  Reset password
 | 
			
		||||
</a>
 | 
			
		||||
							
								
								
									
										15
									
								
								app/pages/public/forgot.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/pages/public/forgot.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
<h1>Forgot Password</h1>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript" src="/js/carrack.js"></script>
 | 
			
		||||
 | 
			
		||||
<!-- FORM -->
 | 
			
		||||
<input required type="email"    id="form-email"     placeholder="Email"> <br>
 | 
			
		||||
 | 
			
		||||
<button onclick="onSubmit()">Submit</button>
 | 
			
		||||
 | 
			
		||||
<!-- RESPONSE -->
 | 
			
		||||
<div id="alert-response" role="alert">
 | 
			
		||||
  <b id="alert-status">Loading...</b> <span id="alert-desc">Please wait...</span>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript" src="/js/auth/forgot.js"></script>
 | 
			
		||||
@ -4,7 +4,9 @@
 | 
			
		||||
 | 
			
		||||
<input required type="text"     id="form-username"  placeholder="Username" > <br>
 | 
			
		||||
<input required type="password" id="form-password"  placeholder="Password" > <br>
 | 
			
		||||
<button type="button" onclick="onSubmit()">Login</button>
 | 
			
		||||
<button type="button" onclick="onSubmit()">Login</button> <br>
 | 
			
		||||
 | 
			
		||||
<a href="/forgot">Forgot password</a>
 | 
			
		||||
 | 
			
		||||
<div id="alert-response" role="alert">
 | 
			
		||||
  <b id="alert-status">Loading...</b> <span id="alert-desc">Please wait...</span>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								app/pages/public/reset.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								app/pages/public/reset.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
<h1>Reset Password</h1>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript" src="/js/carrack.js"></script>
 | 
			
		||||
 | 
			
		||||
<!-- FORM -->
 | 
			
		||||
<div id="form">
 | 
			
		||||
  <input required type="password"    id="form-password"     placeholder="New Password"> <br>
 | 
			
		||||
  <button onclick="onSubmit()">Submit</button>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<!-- RESPONSE -->
 | 
			
		||||
<div id="alert-response" role="alert">
 | 
			
		||||
  <b id="alert-status">Loading...</b> <span id="alert-desc">Please wait...</span>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript" src="/js/auth/reset.js"></script>
 | 
			
		||||
							
								
								
									
										42
									
								
								app/static/js/auth/forgot.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/static/js/auth/forgot.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
function flushResponse() {
 | 
			
		||||
  document.getElementById("alert-response"  ).style.display = 'none';
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-success'  );
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-danger'   );
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-primary'  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function loadingResponse() {
 | 
			
		||||
  flushResponse();
 | 
			
		||||
  document.getElementById("alert-status"  ).innerHTML = "Loading...";
 | 
			
		||||
  document.getElementById("alert-desc"    ).innerHTML = "Please wait...";
 | 
			
		||||
  document.getElementById("alert-response").classList.add('alert-primary');
 | 
			
		||||
  document.getElementById("alert-response").style.display = 'block';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function responseAlert(response) {
 | 
			
		||||
  flushResponse();
 | 
			
		||||
  const obj = JSON.parse(response);
 | 
			
		||||
  if (obj.status == "success" ) document.getElementById("alert-response").classList.add('alert-success' );
 | 
			
		||||
  if (obj.status == "failed"  ) document.getElementById("alert-response").classList.add('alert-danger'  );
 | 
			
		||||
  document.getElementById("alert-status"  ).innerHTML     = obj.status;
 | 
			
		||||
  document.getElementById("alert-desc"    ).innerHTML     = obj.desc;
 | 
			
		||||
  document.getElementById("alert-response").style.display = 'block';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onSubmit() {
 | 
			
		||||
  loadingResponse();
 | 
			
		||||
  var email     = document.getElementById("form-email"    ).value;
 | 
			
		||||
  var url       = "/api/auth/password/forgot/send";
 | 
			
		||||
  var payload   = {
 | 
			
		||||
    "email"     : email
 | 
			
		||||
  };
 | 
			
		||||
  sendHttpRequest(url, "POST", payload, function (error, response) {
 | 
			
		||||
    if (error) console.error("Error:", error);
 | 
			
		||||
    else {
 | 
			
		||||
      console.log("JSON Response:", response);
 | 
			
		||||
      responseAlert(response);
 | 
			
		||||
    }
 | 
			
		||||
  }, "application/json");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
flushResponse();
 | 
			
		||||
							
								
								
									
										49
									
								
								app/static/js/auth/reset.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/static/js/auth/reset.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
function flushResponse() {
 | 
			
		||||
  document.getElementById("alert-response"  ).style.display = 'none';
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-success'  );
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-danger'   );
 | 
			
		||||
  document.getElementById("alert-response"  ).classList.remove('alert-primary'  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function loadingResponse() {
 | 
			
		||||
  flushResponse();
 | 
			
		||||
  document.getElementById("alert-status"  ).innerHTML = "Loading...";
 | 
			
		||||
  document.getElementById("alert-desc"    ).innerHTML = "Please wait...";
 | 
			
		||||
  document.getElementById("alert-response").classList.add('alert-primary');
 | 
			
		||||
  document.getElementById("alert-response").style.display = 'block';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function responseAlert(response) {
 | 
			
		||||
  flushResponse();
 | 
			
		||||
  const obj = JSON.parse(response);
 | 
			
		||||
  if (obj.status == "success" ) {
 | 
			
		||||
    document.getElementById("form").style.display = 'none';
 | 
			
		||||
    document.getElementById("alert-response").classList.add('alert-success' );
 | 
			
		||||
  }
 | 
			
		||||
  if (obj.status == "failed"  ) document.getElementById("alert-response").classList.add('alert-danger'  );
 | 
			
		||||
  document.getElementById("alert-status"  ).innerHTML     = obj.status;
 | 
			
		||||
  document.getElementById("alert-desc"    ).innerHTML     = obj.desc;
 | 
			
		||||
  document.getElementById("alert-response").style.display = 'block';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onSubmit() {
 | 
			
		||||
  loadingResponse();
 | 
			
		||||
  const queryString = window.location.search;
 | 
			
		||||
  const urlParams   = new URLSearchParams(queryString);
 | 
			
		||||
  const token       = urlParams.get('token')
 | 
			
		||||
  var password     = document.getElementById("form-password").value;
 | 
			
		||||
  var url     = "/api/auth/password/forgot/change";
 | 
			
		||||
  var payload = {
 | 
			
		||||
    "token" : token,
 | 
			
		||||
    "password" : password
 | 
			
		||||
  };
 | 
			
		||||
  sendHttpRequest(url, "POST", payload, function (error, response) {
 | 
			
		||||
    if (error) console.error("Error:", error);
 | 
			
		||||
    else {
 | 
			
		||||
      console.log("JSON Response:", response);
 | 
			
		||||
      responseAlert(response);
 | 
			
		||||
    }
 | 
			
		||||
  }, "application/json");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
flushResponse();
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user