Login system with routing and data filtering by user
I am trying to make a Web app using Apps Script. At the moment I am trying to implement a login to at least get a username and password, but I can't get it to enter the page and that form of login is not very secure since you can see the credentials in the code
I place several parts of the code so that it can be interpreted as I move between the different options
Before trying to login I entered like this to access the page
and so I select with buttons in the nav the pages through which the user moves through buttons in the menuNav
EDIT POST COMMENST--------->Main.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
<style>
.nav-link {
cursor:pointer;
}
body{
margin-top:20px;
// background: #ededed;
background: rgba(255,255,255,1));
//background: linear-gradient(325deg, rgba(6,0,0,1) 0%, rgba(255,255,255,1) 30%);
}
.bg-gradient {
background-image: var(.bg-dark.bg-gradient);
}
.bg-success {
--bs-bg-opacity: 1;
background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;
}
.update-nag{
display: inline-block;
font-size: 14px;
text-align: left;
background-color: #fff;
height: 40px;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.2);
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
margin-bottom: 10px;
}
.update-nag:hover{
cursor: pointer;
-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.4);
box-shadow: 0 1px 1px 0 rgba(0,0,0,.3);
}
.update-nag > .update-split{
background: #337ab7;
width: 33px;
float: left;
color: #fff!important;
height: 100%;
text-align: center;
}
.update-nag > .update-split > .glyphicon{
position:relative;
top: calc(50% - 9px)!important; /* 50% - 3/4 of icon height */
}
.update-nag > .update-split.update-success{
background: #5cb85c!important;
}
.update-nag > .update-split.update-danger{
background: #d9534f!important;
}
.update-nag > .update-split.update-info{
background: #5bc0de!important;
}
.update-nag > .update-text{
line-height: 19px;
padding-top: 11px;
padding-left: 45px;
padding-right: 20px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="xxxxxxx" class="rounded me-2" alt="" width="70" height="35">
<strong class="me-auto">Panel Instancias</strong>
<small>1seg ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body text-dark">
Menu activado.
</div>
</div>
</div>
<!-- Content here -->
<div class="row g-1 ">
<div class="col-sm-1 col-md-1 position-relative">
<button class="btn btn-outline-dark shadow position-absolute top-50 start-50 translate-middle" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBothOptions" id="liveToastBtn" aria-controls="offcanvasWithBothOptions">Menu</button>
</div>
<div class="col-1 col-md-1">
<a class="navbar-brand">
<img src="xxxxxx" alt="" width="270" height="70" class="d-inline-block align-text-middle"> </a>
</div>
<p class="fw-bold"><h5> </h5></p>
</div>
<div class="offcanvas offcanvas-start shadow show text-bg-dark bg-dark " data-bs-scroll="true" tabindex="1" id="offcanvasWithBothOptions" aria-labelledby="offcanvasWithBothOptionsLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasWithBothOptionsLabel">Menu</h5>
<button type="button" class="btn-close btn-close-white" id="liveToastBtn" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body p-3 mb-2 bg-dark pe-auto text-white ">
<div class="dropdown pe-auto">
<button class="btn btn-light dropdown-toggle" type="button" class="bi bi-send-plus" data-bs-toggle="dropdown" aria-expanded="false">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-send-plus" viewBox="0 0 16 16">
<path d="M15.964.686a.5.5 0 0 0-.65-.65L.767 5.855a.75.75 0 0 0-.124 1.329l4.995 3.178 1.531 2.406a.5.5 0 0 0 .844-.536L6.637 10.07l7.494-7.494-1.895 4.738a.5.5 0 1 0 .928.372l2.8-7Zm-2.54 1.183L5.93 9.363 1.591 6.602l11.833-4.733Z"/>
<path d="M16 12.5a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Zm-3.5-2a.5.5 0 0 0-.5.5v1h-1a.5.5 0 0 0 0 1h1v1a.5.5 0 0 0 1 0v-1h1a.5.5 0 0 0 0-1h-1v-1a.5.5 0 0 0-.5-.5Z"/>
</svg>
Crear Instancia Nueva
</button>
<ul class="dropdown-menu pe-auto" class="pe-auto">
<li><a class="dropdown-item" target="_blank" href="https://www.totoprayogo.com/" >Marketing</a></li>
<li><a class="dropdown-item">RRHH</a></li>
<li><a class="dropdown-item">Operaciones</a></li>
<li><a class="dropdown-item">Contabilidad</a></li>
<li><a class="dropdown-item">Compras</a></li>
<li><a class="dropdown-item">Mantenimiento</a></li>
<li>
<hr class="dropdown-divider">
</li>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Eres Nuevo? no te preocupes</strong> Selecciona a que departamento quieres crear una instancia.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</ul>
</div>
<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
<button type="button" class="btn btn-dark"id="noticias-link">Noticias</button>
<button type="button" class="btn btn-dark"id="instancias-link">Buscador</button>
<button type="button" class="btn btn-dark"id="addinstancias-link">Añadir Instancias</button>
<button type="button" class="btn btn-dark"id="modal2-link">Modal2 test</button>
<button type="button" class="btn btn-dark" tabindex="-1" aria-disabled="true">Sueño Humedo</button>
<button type="button" class="btn btn-dark invisible"id="editarinstancias-link">Editar Instancias</button>
</div>
<div class="card text-bg-light mb-3" style="max-width: 18rem;">
<div class="card-header">Ayuda</div>
<div class="card-body">
<h5 class="card-title">ATENCION!!!</h5>
<p class="card-text">xxxxxxxxxxx.</p>
</div>
</div>
<div class="alert alert-warning" role="alert">
Selecciona la opcion que mas te convenga
</div>
</div>
</div>
</div>
<div id="app"></div>
<div id="loading"></div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.min.js" integrity="sha384-7VPbUDkoPSGFnVtYi0QogXtr74QeVeeIs99Qfg5YCF+TidwNdjvaKZX19NZ/e6oz" crossorigin="anonymous"></script>-->
<script>
var data;
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')
if (toastTrigger) {
toastTrigger.addEventListener('click', () => {
const toast = new bootstrap.Toast(toastLiveExample)
toast.show()
})
}
function loadView(options){
var id = typeof options.id === "undefined" ? "app" : options.id;
var cb = typeof options.callback === "undefined" ? function(){} : options.callback;
google.script.run.withSuccessHandler(function(html){
document.getElementById(id).innerHTML = html;
typeof options.params === "undefined" ? cb() : cb(options.params);
})[options.func]();
}
function setDataForSearch(){
google.script.run.withSuccessHandler(function(dataReturned){
data = dataReturned.slice();
}).getDataForSearch();
}
function search(){
var searchInput = document.getElementById("searchInput").value.toString().toLowerCase().trim();
var searchWords = searchInput.split(/\s+/);
var searchColumns = [1,2,3,4,5,6,7,8,9];
// and or
var resultsArray = searchInput === "" ? [] : data.filter(function(r){
return searchWords.every(function(word){
return searchColumns.some(function(colIndex){
return r[colIndex].toString().toLowerCase().indexOf(word) !== -1
});
});
});
var searchResultsBox = document.getElementById("searchResults");
var templateBox = document.getElementById("rowTemplate");
var template = templateBox.content;
searchResultsBox.innerHTML = "";
resultsArray.forEach(function(r){
var tr = template.cloneNode(true);
var custIDColumn = tr.querySelector(".custID");
var idInstColumn = tr.querySelector(".idInst");
var localColumn = tr.querySelector(".local");
var contactoColumn = tr.querySelector(".contacto");
var departamentoColumn = tr.querySelector(".departamento");
var tipoColumn = tr.querySelector(".tipo");
var deleteButton = tr.querySelector(".delete-button");
var editButton = tr.querySelector(".edit-button");
var procesoButton = tr.querySelector(".proceso-button");
var terminadaButton = tr.querySelector(".terminada-button");
custIDColumn.textContent = r[0];
deleteButton.dataset.customerId = r[0];
editButton.dataset.customerId = r[0];
procesoButton.dataset.customerId = r[0];
terminadaButton.dataset.customerId = r[0];
localColumn.textContent = r[1];
contactoColumn.textContent = r[2];
departamentoColumn.textContent = r[3];
tipoColumn.textContent = r[4];
idInstColumn.textContent = r[11];
searchResultsBox.appendChild(tr);
});
}
/*
var tipoColumn = tr.querySelector(".tipo");
var espcifico1Column = tr.querySelector(".espcifico1");
var especifico2Column = tr.querySelector(".especifico2");
var refColumn = tr.querySelector(".ref");
var timestampColumn = tr.querySelector(".timestamp");
*/
/*
tipoColumn.textContent = r[6];
espcifico1Column.textContent = r[7];
espcifico2Column.textContent = r[8];
refColumn.textContent = r[9];
timestampColumn.textContent = r[10];
*/
function displayConfirmationDelete(e){
if(e.target.dataset.buttonState === "delete"){
e.target.previousElementSibling.classList.remove("d-none");
e.target.textContent = "Cancelar";
e.target.dataset.buttonState = "cancel";
} else {
e.target.previousElementSibling.classList.add("d-none");
e.target.textContent = "Delete";
e.target.dataset.buttonState = "delete";
}
}
function displayConfirmationEstado(e){
if(e.target.dataset.buttonState === "estado"){
e.target.previousElementSibling.classList.remove("d-none");
e.target.nextElementSibling.classList.remove("d-none");
e.target.textContent = "Cancelar";
e.target.dataset.buttonState = "cancel";
} else {
e.target.previousElementSibling.classList.add("d-none");
e.target.nextElementSibling.classList.add("d-none");
e.target.textContent = "Estado";
e.target.dataset.buttonState = "estado";
}
}
function deleteCustomer(e){
var custID = e.target.dataset.customerId;
google.script.run.withSuccessHandler(function(){
e.target.closest(".result-box").remove();
var ids = data.map(function(r){return r[0].toString().toLowerCase() });
var index = ids.indexOf(custID.toString().toLowerCase());
data.splice(index,1);
}).deleteById(custID);
}
function afterEditViewLoads(params){
//{custID: 32}
document.getElementById("customer-id").value = params.custID;
google.script.run.withSuccessHandler(function(customerInfo){
document.getElementById("local").value = customerInfo.local;
document.getElementById("contacto").value = customerInfo.contacto;
document.getElementById("departamento").value = customerInfo.departamento;
}).getCustomerById(params.custID);
}
function editCustomer(){
var customerInfo = {};
customerInfo.local = document.getElementById("local").value;
customerInfo.contacto = document.getElementById("contacto").value;
customerInfo.departamento = document.getElementById("departamento").value;
var id = document.getElementById("customer-id").value;
google.script.run.withSuccessHandler(function(res){
document.getElementById("editar-message").classList.remove("invisible");
setTimeout(function(){
document.getElementById("editar-message").classList.add("invisible");
},2000);
}).editCustomerById(id,customerInfo);
}
function addCustomer(){
var customerInfo = {};
customerInfo.local = document.getElementById("local").value;
customerInfo.contacto = document.getElementById("contacto").value;
customerInfo.departamento = document.getElementById("departamento").value;
google.script.run.withSuccessHandler(function(){
document.getElementById("local").value = "" ;
document.getElementById("contacto").value = "" ;
document.getElementById("departamento").value = "" ;
document.getElementById("add-message").classList.remove("invisible");
setTimeout(function(){
document.getElementById("add-message").classList.add("invisible");
},2000);
}).addCustomer(customerInfo);
}
function loadInstanciasView(){
loadView({func: "loadInstanciasView", callback: setDataForSearch });
}
function loadAddInstanciasView(){
loadView({func: "loadAddInstanciasView"});
}
function loadEditarInstanciasView(){
loadView({func: "loadEditarInstanciasView"});
}
function loadNoticiasView(){
loadView({func: "loadNoticiasView"});
}
function loadModal2View(){
loadView({func: "loadModal2View"});
}
// function loadmainView(){
// loadView({func: "loadmainView"});
//}
document.getElementById("instancias-link").addEventListener("click",loadInstanciasView);
document.getElementById("addinstancias-link").addEventListener("click",loadAddInstanciasView);
document.getElementById("editarinstancias-link").addEventListener("click",loadEditarInstanciasView);
document.getElementById("noticias-link").addEventListener("click",loadNoticiasView);
document.getElementById("modal2-link").addEventListener("click",loadModal2View);
//document.getElementById("main-link").addEventListener("click",loadmainView);
function inputEventHandler(e){
if(e.target.matches("#searchInput")){
search();
}
}
function clickEventHandler(e){
if(e.target.matches(".delete-button")){
deleteCustomer(e);
}
if(e.target.matches(".before-delete-button")){
displayConfirmationDelete(e);
}
if(e.target.matches(".terminada-button")){
terminadaCustomer(e);
}
if(e.target.matches(".proceso-button")){
procesoCustomer(e);
}
if(e.target.matches(".before-estado-button")){
displayConfirmationEstado(e);
}
if(e.target.matches(".edit-button")){
loadView({func: "loadEditarInstanciasView", callback: afterEditViewLoads, params: {custID: e.target.dataset.customerId} });
}
if(e.target.matches("#save-changes")){
editCustomer();
}
if(e.target.matches("#cancel-changes")){
loadInstanciasView();
}
if(e.target.matches("#add-customer-button")){
addCustomer();
}
}
document.getElementById("app").addEventListener("input",inputEventHandler);
document.getElementById("app").addEventListener("click",clickEventHandler);
</script>
</div>
</body>
</html>
Instancias.html----->
<p class="fw-bold"><h1>Buscador</h1></p>
<form>
<div class="mb-3">
<input type="text" class="form-control border-success border" list="datalistOptions" id="searchInput" placeholder="Escribe lo que necesites....">
<datalist id="datalistOptions">
<option value="RRHH">
<option value="Mkt">
<option value="Operaciones">
<option value="Mantenimiento">
<option value="Informatica">
</datalist>
<div id="AyudaBusqueda" class="form-text">formulario de busqueda.</div>
</div>
<table class="table table-hover align-middle table-striped table-responsive-xxl overflow-scroll shadow-lg rounded ">
<thead class="table-dark align-middle text-center shadow-lg ">
<tr>
<th scope="col">CustID</th>
<th scope="col">IdInst</th>
<th scope="col">Local</th>
<th scope="col">Contacto</th>
<th scope="col">Departamento</th>
<th scope="col">Tipo</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="searchResults">
</tbody>
</table>
<template id="rowTemplate">
<tr class="result-box shadow-sm table-responsive-xxl rounded align-middle" >
<th class="custID text-center" scope="row"></th>
<td class="idInst"></td>
<td class="local text-center"></td>
<td class="contacto text-center"></td>
<td class="departamento text-center"></td>
<td class="tipo text-center"></td>
<td>
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-success shadow-sm terminada-button d-none">Terminada</button>
<button type="button" class="btn btn-outline-dark shadow-sm before-estado-button" data-button-state="estado">Estado</button>
<button type="button" class="btn btn-outline-warning shadow-sm proceso-button d-none">Proceso</button>
</div>
</td>
<td>
<button type="button" class="btn btn-outline-dark shadow-sm edit-button">Editar</button></td>
<td>
<div class="btn-group" role="group">
<button type="button" class="btn btn-danger shadow-sm delete-button d-none">Confirmar</button>
<button type="button" class="btn btn-outline-dark shadow-sm before-delete-button" data-button-state="delete">Borrar</button>
</div>
</td>
</tr>
</template>
<!--
<th scope="col">tipo</th>
<th scope="col">especifico1</th>
<th scope="col">especifico2</th>
<th scope="col">ref</th>
<th scope="col">timestamp</th>
-->
<!--
<td class="tipo"></td>
<td class="especifico1"></td>
<td class="especifico2"></td>
<td class="ref"></td>
<td class="timestamp"></td>
-->
Loadpartials.html----->
function loadPartialHTML_(partial) {
const htmlServ = HtmlService.createTemplateFromFile(partial);
return htmlServ.evaluate().getContent();
}
function loadInstanciasView(){
return loadPartialHTML_("instancias");
}
function loadAddInstanciasView(){
return loadPartialHTML_("addinstancias");
}
function loadEditarInstanciasView(){
return loadPartialHTML_("editarinstancias");
}
function loadNoticiasView(){
return loadPartialHTML_("noticiasview");
}
ServerSideFuncs.gs----->
function getDataForSearch() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("1");
return ws.getRange(2, 1, ws.getLastRow()-1, 12).getDisplayValues();
}
function deleteById(id){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("1");
const custIds = ws.getRange(2, 1, ws.getLastRow()-1, 1).getValues().map(r => r[0].toString().toLowerCase());
const posIndex = custIds.indexOf(id.toString().toLowerCase());
const rowNumber = posIndex === -1 ? 0 : posIndex + 2;
ws.deleteRow(rowNumber);
}
function getCustomerById(id){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("1");
const custIds = ws.getRange(2, 1, ws.getLastRow()-1, 1).getDisplayValues().map(r => r[0].toString().toLowerCase());
const posIndex = custIds.indexOf(id.toString().toLowerCase());
const rowNumber = posIndex === -1 ? 0 : posIndex + 2;
const customerInfo = ws.getRange(rowNumber, 1, 1, 4).getDisplayValues()[0];
//[[45,"Joe"]]
return { custID: customerInfo[0], local: customerInfo[1], contacto: customerInfo[2], departamento: customerInfo[3] };
}
function editCustomerById(id,customerInfo){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("1");
const custIds = ws.getRange(2, 1, ws.getLastRow()-1, 1).getDisplayValues().map(r => r[0].toString().toLowerCase());
const posIndex = custIds.indexOf(id.toString().toLowerCase());
const rowNumber = posIndex === -1 ? 0 : posIndex + 2;
ws.getRange(rowNumber, 2,1,3).setValues([[
customerInfo.local,
customerInfo.contacto,
customerInfo.departamento
]]);
return true;
}
function addCustomer(customerInfo){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("1");
const uniqueIDs = ws.getRange(2, 1, ws.getLastRow()-1, 1).getValues();
var maxNum = 0;
uniqueIDs.forEach(r => {
maxNum = r[0] > maxNum ? r[0] : maxNum
});
var newID = maxNum +1;
ws.appendRow([
newID,
customerInfo.local,
customerInfo.contacto,
customerInfo.departamento
]);
}
loadforms.gs----->
function loadMainForm() {
const htmlServ = HtmlService.createTemplateFromFile("main");
const html = htmlServ.evaluate();
html.setHeight(1200).setWidth (2000);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(html, "xxxxxxxxxx");
}
function loadForm2() {
const htmlForSidebar = HtmlService.createTemplateFromFile("uform2");
const htmlOutput = htmlForSidebar.evaluate();
const ui = SpreadsheetApp.getUi();
ui.showSidebar(htmlOutput);
}
function createMenu_(){
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("InstanciasPrueba");
menu.addItem("Instancia", "loadMainForm");
menu.addItem("Instancia2", "loadForm2");
menu.addItem("URL", "testNew");
menu.addToUi();
}
function onOpen(){
createMenu_();
}
//function doGet() {
//let layout = HtmlService.createTemplateFromFile("main");
//return layout.evaluate();
//}
function doGet(request) {
return HtmlService.createTemplateFromFile('main').evaluate()
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function testNew(){
showAnchor('Stackoverflow','http://stackoverflow.com/questions/tagged/google-apps-script');
}
function showAnchor(name,url) {
var html = '<html><body><a href="'+url+'" target="blank" onclick="google.script.host.close()">'+name+'</a></body></html>';
var ui = HtmlService.createHtmlOutput(html)
SpreadsheetApp.getUi().showModelessDialog(ui,"demo");
}
As I have mentioned before, I am starting from scratch to program and in a self-taught way, I know that I have mistakes and I know that I have errors, but that is why I am here, to learn to do things better
Comments
Post a Comment