Scriptcaser
Formulário de Troca de Senha Robusto

Formulário de Troca de Senha Robusto no Scriptcase

A aplicação padrão do scriptcase de formulário de troca de senha do tipo control (aquela que é gerada junto com o módulo de segurança) é funcional e atende até um determinado ponto; a questão é que já não era mais suficiente para mim.

Eu queria um formulário de troca de senha mais robusto, que eu pudesse definir os critérios para se criar uma nova senha, que fosse bonito, que tivesse instruções e que os critérios fossem validados a medida que a senha era digitada, sendo tudo processado sem a necessidade de submeter o formulário para validação dos critérios, consumindo menos tempo e recursos do servidor. Sim, estou falando de adicionar um pouquinho de javascript no scriptcase.

Esse formulário de troca de senha faz parte de um projeto de rastreamento veicular, com frontend em scriptcase, backend em nodejs e php utilizando a biblioteca socket do ReactPHP e o aplicativo android. Gostaria de mostrar todo o desenvolvimento do sistema ao passo em que fosse criando novas aplicações e fazendo correções, portanto este será o meu diário.

Legal né? Então mãos à obra.

Primeiro é criar uma aplicação do tipo blank para substituir a control padrão gerada pelo módulo segurança, dei o nome a minha de app_change_pswd.

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Troca de Senha | <?php echo (strlen(getConfigOneKey('geral', 'geral_nomesistema')) > 0) ? getConfigOneKey('geral', 'geral_nomesistema') : 'BrTrak'; ?> &ndash; Sistema de Rastreamento Veicular</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <!-- VENDOR CSS -->
    <link rel="stylesheet" href="<?php echo sc_url_library("prj", "assets", "vendor/bootstrap/css/bootstrap.min.css"); ?>">
    <link rel="stylesheet" href="<?php echo sc_url_library("prj", "assets", "vendor/toastr/toastr.min.css"); ?>">
    <link rel="stylesheet" href="<?php echo sc_url_library("prj", "assets", "vendor/fontawesome-free/css/all.min.css"); ?>">
    <!-- CUSTOM CSS -->
    <link rel="stylesheet" href="<?php echo sc_url_library("prj", "assets", "css/login-custom.css"); ?>">
    <!-- ICONS -->
    <link rel="apple-touch-icon" sizes="76x76" href="<?php echo sc_url_library("prj", "assets", "img/apple-icon.png"); ?>">
    <link rel="icon" type="image/png" sizes="96x96" href="<?php echo sc_url_library("prj", "assets", "img/favicon.png"); ?>">
</head>
<body>
<!-- WRAPPER -->
<div class="container-fluid">
    <div class="row no-gutter">
        <div class="col-sm-12 col-md-6 offset-md-3 col-lg-6 offset-lg-3">
            <div class="login d-flex align-items-center py-5">
                <div class="container">
                    <div class="row">
		        <h6 class="login-heading mb-4 text-center">Insira sua nova senha, confirme a senha e clique em "Alterar Senha". O botão "Alterar Senha" só é ativado quando todos os critérios são atendidos.</h6>
			<form method="POST" class="mx-auto d-block" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
		        <div class="form-label-group">
			    <input type="password" id="pswd" name="pswd" class="form-control" placeholder="Nova Senha" required autofocus>
			    <label for="pswd">Nova Senha</label>
			</div>
			<div class="row mb-3">
			    <div class="col-sm-6">
				<i id="8char" class="fas fa-fw fa-times" style="color:#FF0004;"></i> Maior que 8 caracteres <br>
			        <i id="ucase" class="fas fa-fw fa-times" style="color:#FF0004;"></i> Uma letra maiúscula
			    </div>
			    <div class="col-sm-6">
			        <i id="lcase" class="fas fa-fw fa-times" style="color:#FF0004;"></i> Uma letra minúscula <br>
			        <i id="num" class="fas fa-fw fa-times" style="color:#FF0004;"></i> Um número
			    </div>
			</div>
                        <div class="form-label-group">
			    <input type="password" id="cpswd" name="cpswd" class="form-control" placeholder="Confirme a Senha" required>
			    <label for="cpswd">Confirme a Senha</label>
			</div>
			<i id="pwmatch" class="fas fa-fw fa-times mb-3" style="color:#FF0004;"></i> Senhas coincidem
                        <input name="user" id="user" type="hidden" value="<?php echo strlen([login]) > 0 ? [login] :  $_SESSION['usr_login']; ?>">
			<input name="token" id="token" type="hidden" value="<?php echo strlen([act_code]) > 0 ? [act_code] : ''; ?>">
			<button id="submit" class="btn btn-lg btn-success btn-block btn-login text-uppercase font-weight-bold mb-2" type="submit" disabled>Alterar Senha</button>
			<div id="back_btn" class="text-center" style="display: none">
			    <a class="small" href="//<?php echo get_base_dir() . 'app_Login/'; ?>">Voltar para o login</a>
			</div>
		        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- END WRAPPER -->
<!-- Javascript -->
<script src="<?php echo sc_url_library("prj", "assets", "vendor/jquery/jquery.min.js"); ?>"></script>
<script src="<?php echo sc_url_library("prj", "assets", "vendor/bootstrap/js/bootstrap.bundle.min.js"); ?>"></script>
<script src="<?php echo sc_url_library("prj", "assets", "vendor/toastr/toastr.min.js"); ?>"></script>
<script>
	toastr.options = {
		"closeButton": false,
		"debug": false,
		"newestOnTop": false,
		"positionClass": "toast-top-right",
		"preventDuplicates": false,
		"onclick": null,
		"showDuration": "300",
		"hideDuration": "1000",
		"timeOut": "3000",
		"extendedTimeOut": "1000",
		"showEasing": "swing",
		"hideEasing": "linear",
		"showMethod": "fadeIn",
		"hideMethod": "fadeOut"
	}
	
	$("#pswd").keyup(function(){
		var ucase = new RegExp("[A-Z]+");
		var lcase = new RegExp("[a-z]+");
		var num = new RegExp("[0-9]+");

		if($(this).val().length >= 8) {
			$("#8char").removeClass("fa-times");
			$("#8char").addClass("fa-check");
			$("#8char").css("color","#00A41E");
		} else {
			$("#8char").removeClass("fa-check");
			$("#8char").addClass("fa-times");
			$("#8char").css("color","#FF0004");
		}

		if(ucase.test($(this).val())) {
			$("#ucase").removeClass("fa-times");
			$("#ucase").addClass("fa-check");
			$("#ucase").css("color","#00A41E");
		} else {
			$("#ucase").removeClass("fa-check");
			$("#ucase").addClass("fa-times");
			$("#ucase").css("color","#FF0004");
		}

		if(lcase.test($(this).val())) {
			$("#lcase").removeClass("fa-times");
			$("#lcase").addClass("fa-check");
			$("#lcase").css("color","#00A41E");
		} else {
			$("#lcase").removeClass("fa-check");
			$("#lcase").addClass("fa-times");
			$("#lcase").css("color","#FF0004");
		}

		if(num.test($(this).val())) {
			$("#num").removeClass("fa-times");
			$("#num").addClass("fa-check");
			$("#num").css("color","#00A41E");
		} else {
			$("#num").removeClass("fa-check");
			$("#num").addClass("fa-times");
			$("#num").css("color","#FF0004");
		}
	});
	
	$("#cpswd").keyup(function(){
		if($(this).val() == $("#pswd").val()) {
			$("#pwmatch").removeClass("fa-times");
			$("#pwmatch").addClass("fa-check");
			$("#pwmatch").css("color","#00A41E");
			$("#submit").attr('disabled', false);
		} else {
			$("#pwmatch").removeClass("fa-check");
			$("#pwmatch").addClass("fa-times");
			$("#pwmatch").css("color","#FF0004");
			$("#submit").attr('disabled', true);
		}
	});
</script>
</body>
</html>
<?php

if(isset($_POST['user']) && !empty($_POST['user']) && isset($_POST['pswd']) && !empty($_POST['pswd'])) {
	// change password
	$result = change_pswd($_POST['user'], hash('md5', $_POST['pswd']));
	
	if(isset($_POST['token']) && !empty($_POST['token'])) {
		
		// set activation code NULL
		$sql = "UPDATE sec_users SET activation_code = NULL WHERE id = {$_POST['user']}";
		sc_exec_sql($sql);
		
		// reset globals
		sc_reset_global([login], [act_code]);
		
		$result = array("message" => "Senha alterada com sucesso! Clique em voltar para o login e insira sua nova senha para acessar o sistema.", "event" => "success");
		?>
		<script>
		    // display back to login button
		    $('#back_btn').show();
		</script>
		<?php
	}
}

if(isset($result) && !empty($result)) { ?>
    <script>
	let response = <?php echo json_encode($result); ?>;
	if(response.event == 'success')
	    toastr.success(response.message);
        else
	    toastr.error(response.message);
    </script> 
<?php }

Esse formulário servirá para mudança de senha interna ou através de link externo enviado por e-mail com token de ativação.

Para que eu não me alongue e vá direto ao essencial, vou presumir que você já sabe como utilizar o as bibliotecas externas, já saiba da rotina de “esqueci minha senha” padrão do scriptcase e que já tenha pelo menos um pouco de conhecimento em javascript e jquery. O código abaixo é o que nos interessa:

$("#pswd").keyup(function(){
		var ucase = new RegExp("[A-Z]+");
		var lcase = new RegExp("[a-z]+");
		var num = new RegExp("[0-9]+");

		if($(this).val().length >= 8) {
			$("#8char").removeClass("fa-times");
			$("#8char").addClass("fa-check");
			$("#8char").css("color","#00A41E");
		} else {
			$("#8char").removeClass("fa-check");
			$("#8char").addClass("fa-times");
			$("#8char").css("color","#FF0004");
		}

		if(ucase.test($(this).val())) {
			$("#ucase").removeClass("fa-times");
			$("#ucase").addClass("fa-check");
			$("#ucase").css("color","#00A41E");
		} else {
			$("#ucase").removeClass("fa-check");
			$("#ucase").addClass("fa-times");
			$("#ucase").css("color","#FF0004");
		}

		if(lcase.test($(this).val())) {
			$("#lcase").removeClass("fa-times");
			$("#lcase").addClass("fa-check");
			$("#lcase").css("color","#00A41E");
		} else {
			$("#lcase").removeClass("fa-check");
			$("#lcase").addClass("fa-times");
			$("#lcase").css("color","#FF0004");
		}

		if(num.test($(this).val())) {
			$("#num").removeClass("fa-times");
			$("#num").addClass("fa-check");
			$("#num").css("color","#00A41E");
		} else {
			$("#num").removeClass("fa-check");
			$("#num").addClass("fa-times");
			$("#num").css("color","#FF0004");
		}
	});
	
	$("#cpswd").keyup(function(){
		if($(this).val() == $("#pswd").val()) {
			$("#pwmatch").removeClass("fa-times");
			$("#pwmatch").addClass("fa-check");
			$("#pwmatch").css("color","#00A41E");
			$("#submit").attr('disabled', false);
		} else {
			$("#pwmatch").removeClass("fa-check");
			$("#pwmatch").addClass("fa-times");
			$("#pwmatch").css("color","#FF0004");
			$("#submit").attr('disabled', true);
		}
	});

O mais importante desse código é como ele começa; um eventListener do tipo keyup no elemento “pswd” é adicionado, ou seja, toda vez um botão no teclado é apertado o script dispara uma ação.

Segundo passo é criar três variáveis do tipo RegExp para validar as letras maiúsculas, as letras minúsculas e os numerais.

var ucase = new RegExp("[A-Z]+");
var lcase = new RegExp("[a-z]+");
var num = new RegExp("[0-9]+");

Se você não sabe como utilizar as expressões regulares indico a leitura desse post.

É hora de programar a primeira regra, que é verificar se a senha tem 8 ou mais caracteres.

if($(this).val().length >= 8) {
    $("#8char").removeClass("fa-times");
    $("#8char").addClass("fa-check");
    $("#8char").css("color","#00A41E");
} else {
    $("#8char").removeClass("fa-check");
    $("#8char").addClass("fa-times");
    $("#8char").css("color","#FF0004");
}

Como pode observar, utilizo a biblioteca gratuita de ícones da font awesome para exibir visualmente ao usuário se os critérios estão ou não sendo atendidos.

A instrução acima é bastante simples: verifica se o tamanho da senha dentro do elemento “pswd” é maior ou igual a 8; caso sim o ícone é substituído e sua cor alterada.

A segunda regra é verificar se existe alguma letra maiúscula dentro do campo através do método test do objeto do tipo RegExp.

if(ucase.test($(this).val())) {
    $("#ucase").removeClass("fa-times");
    $("#ucase").addClass("fa-check");
    $("#ucase").css("color","#00A41E");
} else {
    $("#ucase").removeClass("fa-check");
    $("#ucase").addClass("fa-times");
    $("#ucase").css("color","#FF0004");
}

O método test retorna um boolean , caso true substitui o ícone e altera a cor do elemento “ucase”, caso false mantém-se como está.

A terceira e quarta regra seguem a lógica anterior, com a diferença que nesse caso se verificará se há alguma letra minúscula e se há algum numeral, respectivamente.

Por fim a última regra é verificar se os valores dos campos “senha” e “confirmar senha” coincidem; se sim o botão “alterar senha” é desbloqueado e o usuário poderá alterar sua senha.

$("#cpswd").keyup(function(){
    if($(this).val() == $("#pswd").val()) {
        $("#pwmatch").removeClass("fa-times");
	$("#pwmatch").addClass("fa-check");
	$("#pwmatch").css("color","#00A41E");
	$("#submit").attr('disabled', false);
    } else {
	$("#pwmatch").removeClass("fa-check");
	$("#pwmatch").addClass("fa-times");
	$("#pwmatch").css("color","#FF0004");
	$("#submit").attr('disabled', true);
    }
});

Esse são os meus critérios de mudança de senha, você pode mudá-los de acordo com o que você precisa, fique livre para fazer as alterações que necessita.

Você pode desconsiderar toda a parte do código que não for do javascript de validação de senha; eu tenho certeza que se você copiar e colar o primeiro bloco na integra ele não funcionará, pois ali existem bibliotecas externas que você deverá importar para o seu projeto, tais quais o bootstrap, o toastr, o jquery e o font awesome.

Espero que tenha gostado, comente! Diga se funcionou, onde enfrentou dificuldade, se o tutorial ficou claro. Em breve aqui terá toda a minha jornada pelo campo do rastreamento de veículos e tudo que utilizei para tornar este projeto possível.

scriptcaser

Add comment

Newsletter

Se inscreva na nossa newsletter
Se increva hoje na nossa lista de e-mail para receber atualizações, tutoriais e ofertas especiais!

Respeitarei sua privacidade. Seu e-mail nunca será compartilhado.