Actualizaciones de archivo.
Modificaciones pequeñas
This commit is contained in:
parent
f9bf5f4824
commit
97db600b1f
@ -17,12 +17,15 @@ services:
|
|||||||
- "81:81" # UI de administración NPM
|
- "81:81" # UI de administración NPM
|
||||||
- "443:443" # HTTPS público
|
- "443:443" # HTTPS público
|
||||||
volumes:
|
volumes:
|
||||||
- npm_data:/data # config + DB (SQLite)
|
- dev-npm_data:/data # config + DB (SQLite)
|
||||||
- npm_letsencrypt:/etc/letsencrypt
|
- dev-npm_letsencrypt:/etc/letsencrypt
|
||||||
networks:
|
networks:
|
||||||
- suitecoffee-net
|
- suitecoffee-net
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
suitecoffee-app:
|
suitecoffee-app:
|
||||||
|
image: node:20-bookworm
|
||||||
container_name: suitecoffee-app
|
container_name: suitecoffee-app
|
||||||
depends_on:
|
depends_on:
|
||||||
suitecoffee-db:
|
suitecoffee-db:
|
||||||
@ -31,9 +34,11 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
|
working_dir: /app
|
||||||
|
user: "${UID:-1000}:${GID:-1000}"
|
||||||
volumes:
|
volumes:
|
||||||
- ./services/app:/app
|
- ./services/app:/app:rw
|
||||||
- /app/node_modules
|
- ./node_modules:/app/node_modules
|
||||||
env_file:
|
env_file:
|
||||||
- ./services/app/.env.development
|
- ./services/app/.env.development
|
||||||
environment:
|
environment:
|
||||||
@ -50,16 +55,22 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- suitecoffee-net
|
- suitecoffee-net
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
suitecoffee-auth:
|
suitecoffee-auth:
|
||||||
|
image: node:20-bookworm
|
||||||
container_name: suitecoffee-auth
|
container_name: suitecoffee-auth
|
||||||
depends_on:
|
depends_on:
|
||||||
suitecoffee-db:
|
suitecoffee-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ports:
|
ports:
|
||||||
- 4000:4000
|
- 4000:4000
|
||||||
|
working_dir: /app
|
||||||
|
user: "${UID:-1000}:${GID:-1000}"
|
||||||
volumes:
|
volumes:
|
||||||
- ./services/auth:/app
|
- ./services/app:/app:rw
|
||||||
- /app/node_modules
|
- ./node_modules:/app/node_modules
|
||||||
env_file:
|
env_file:
|
||||||
- ./services/auth/.env.development
|
- ./services/auth/.env.development
|
||||||
environment:
|
environment:
|
||||||
@ -83,9 +94,9 @@ services:
|
|||||||
POSTGRES_USER: ${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
POSTGRES_PASSWORD: ${DB_PASS}
|
POSTGRES_PASSWORD: ${DB_PASS}
|
||||||
ports:
|
ports:
|
||||||
- 54321:5432
|
- ${DB_LOCAL_PORT}:${DB_DOCKER_PORT}
|
||||||
volumes:
|
volumes:
|
||||||
- suitecoffee-data:/var/lib/postgresql/data
|
- dev-suitecoffee-data:/var/lib/postgresql/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
|
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
|
||||||
@ -104,9 +115,9 @@ services:
|
|||||||
POSTGRES_USER: ${TENANTS_DB_USER}
|
POSTGRES_USER: ${TENANTS_DB_USER}
|
||||||
POSTGRES_PASSWORD: ${TENANTS_DB_PASS}
|
POSTGRES_PASSWORD: ${TENANTS_DB_PASS}
|
||||||
volumes:
|
volumes:
|
||||||
- tenants-data:/var/lib/postgresql/data
|
- dev-tenants-data:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
- 54322:5432
|
- ${TENANTS_DB_LOCAL_PORT}:${TENANTS_DB_DOCKER_PORT}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${TENANTS_DB_USER} -d ${TENANTS_DB_NAME}"]
|
test: ["CMD-SHELL", "pg_isready -U ${TENANTS_DB_USER} -d ${TENANTS_DB_NAME}"]
|
||||||
@ -129,8 +140,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 8978:8978
|
- 8978:8978
|
||||||
volumes:
|
volumes:
|
||||||
- dbeaver_logs:/opt/cloudbeaver/logs
|
- dev-dbeaver_logs:/opt/cloudbeaver/logs
|
||||||
- dbeaver_workspace:/opt/cloudbeaver/workspace
|
- dev-dbeaver_workspace:/opt/cloudbeaver/workspace
|
||||||
networks:
|
networks:
|
||||||
- suitecoffee-net
|
- suitecoffee-net
|
||||||
|
|
||||||
@ -149,12 +160,12 @@ services:
|
|||||||
# - suitecoffee-net
|
# - suitecoffee-net
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
tenants-data:
|
dev-tenants-data:
|
||||||
suitecoffee-data:
|
dev-suitecoffee-data:
|
||||||
npm_data:
|
dev-npm_data:
|
||||||
npm_letsencrypt:
|
dev-npm_letsencrypt:
|
||||||
dbeaver_logs:
|
dev-dbeaver_logs:
|
||||||
dbeaver_workspace:
|
dev-dbeaver_workspace:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
suitecoffee-net:
|
suitecoffee-net:
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"app": "file:services/app"
|
"app": "file:services/app",
|
||||||
|
"auth": "file:services/auth"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"watch": ["src"],
|
|
||||||
"ext": "js,json",
|
|
||||||
"ignore": [
|
|
||||||
"node_modules/**/node_modules",
|
|
||||||
"node_modules/",
|
|
||||||
".git"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"exec": "node ./src/index.js"
|
|
||||||
}
|
|
||||||
2
services/app/package-lock.json
generated
2
services/app/package-lock.json
generated
@ -9,7 +9,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.5.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "suitecoffee_aplication_service",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "NODE_ENV=production node ./src/index.js",
|
"start": "NODE_ENV=production node ./src/index.js",
|
||||||
"dev": "npx nodemon",
|
"dev": "NODE_ENV=development npx nodemon ./src/index.js",
|
||||||
"test": "NODE_ENV=stage node ./src/index.js"
|
"test": "NODE_ENV=stage node ./src/index.js"
|
||||||
},
|
},
|
||||||
"author": "Mateo Saldain",
|
"author": "Mateo Saldain",
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"nodemon": "^3.1.10"
|
"nodemon": "^3.1.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.5.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"watch": ["src"],
|
|
||||||
"ext": "js,json",
|
|
||||||
"ignore": [
|
|
||||||
"node_modules/**/node_modules",
|
|
||||||
"node_modules/",
|
|
||||||
".git"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"exec": "node ./src/index.js"
|
|
||||||
}
|
|
||||||
2
services/auth/package-lock.json
generated
2
services/auth/package-lock.json
generated
@ -10,7 +10,7 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.5.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "auth",
|
"name": "suitecoffee_authentication_service",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "NODE_ENV=production node ./src/index.js",
|
"start": "NODE_ENV=production node ./src/index.js",
|
||||||
"dev": "npx nodemon",
|
"dev": "NODE_ENV=development npx nodemon ./src/index.js",
|
||||||
"test": "NODE_ENV=stage node ./src/index.js"
|
"test": "NODE_ENV=stage node ./src/index.js"
|
||||||
},
|
},
|
||||||
"author": "Mateo Saldain",
|
"author": "Mateo Saldain",
|
||||||
@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.5.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>SuiteCoffee - Autenticación</title>
|
<title>SuiteCoffee - Autenticación</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-light d-flex justify-content-center align-items-center vh-100">
|
<body class="bg-light d-flex justify-content-center align-items-center vh-100">
|
||||||
|
|
||||||
<div class="card shadow p-4" style="width: 100%; max-width: 400px;">
|
<div class="card shadow p-4" style="width: 100%; max-width: 400px;">
|
||||||
@ -51,101 +53,103 @@
|
|||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
<button class="btn btn-link btn-sm" id="toggle-mode">¿No tienes cuenta? Regístrate</button>
|
<button class="btn btn-link btn-sm" id="toggle-mode">¿No tienes cuenta? Regístrate</button>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Hola!</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const form = document.getElementById('formulario');
|
const form = document.getElementById('formulario');
|
||||||
const mensaje = document.getElementById('mensaje');
|
const mensaje = document.getElementById('mensaje');
|
||||||
const toggleModeBtn = document.getElementById('toggle-mode');
|
const toggleModeBtn = document.getElementById('toggle-mode');
|
||||||
const registroExtra = document.getElementById('registro-extra');
|
const registroExtra = document.getElementById('registro-extra');
|
||||||
const formTitle = document.getElementById('form-title');
|
const formTitle = document.getElementById('form-title');
|
||||||
const btnSubmit = document.getElementById('btn-submit');
|
const btnSubmit = document.getElementById('btn-submit');
|
||||||
|
|
||||||
let modoRegistro = false;
|
let modoRegistro = false;
|
||||||
|
|
||||||
toggleModeBtn.addEventListener('click', () => {
|
toggleModeBtn.addEventListener('click', () => {
|
||||||
modoRegistro = !modoRegistro;
|
modoRegistro = !modoRegistro;
|
||||||
registroExtra.style.display = modoRegistro ? 'block' : 'none';
|
registroExtra.style.display = modoRegistro ? 'block' : 'none';
|
||||||
formTitle.textContent = modoRegistro ? 'Registrar Cuenta' : 'Iniciar Sesión';
|
formTitle.textContent = modoRegistro ? 'Registrar Cuenta' : 'Iniciar Sesión';
|
||||||
btnSubmit.textContent = modoRegistro ? 'Registrarse' : 'Entrar';
|
btnSubmit.textContent = modoRegistro ? 'Registrarse' : 'Entrar';
|
||||||
toggleModeBtn.textContent = modoRegistro ? '¿Ya tienes cuenta? Inicia sesión' : '¿No tienes cuenta? Regístrate';
|
toggleModeBtn.textContent = modoRegistro ? '¿Ya tienes cuenta? Inicia sesión' : '¿No tienes cuenta? Regístrate';
|
||||||
|
|
||||||
if (modoRegistro) {
|
if (modoRegistro) {
|
||||||
cargarPlanes(); // ✅ ahora sí se ejecutará correctamente
|
cargarPlanes(); // ✅ ahora sí se ejecutará correctamente
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
form.addEventListener('submit', async (e) => {
|
form.addEventListener('submit', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
mensaje.classList.add('d-none');
|
mensaje.classList.add('d-none');
|
||||||
|
|
||||||
const datos = {
|
const datos = {
|
||||||
correo: document.getElementById('correo').value,
|
correo: document.getElementById('correo').value,
|
||||||
clave_acceso: document.getElementById('clave').value
|
clave_acceso: document.getElementById('clave').value
|
||||||
};
|
};
|
||||||
|
|
||||||
if (modoRegistro) {
|
if (modoRegistro) {
|
||||||
Object.assign(datos, {
|
Object.assign(datos, {
|
||||||
nombre_empresa: document.getElementById('nombre_empresa').value,
|
nombre_empresa: document.getElementById('nombre_empresa').value,
|
||||||
rut: document.getElementById('rut').value,
|
rut: document.getElementById('rut').value,
|
||||||
telefono: document.getElementById('telefono').value,
|
telefono: document.getElementById('telefono').value,
|
||||||
direccion: document.getElementById('direccion').value,
|
direccion: document.getElementById('direccion').value,
|
||||||
logo: document.getElementById('logo').value,
|
logo: document.getElementById('logo').value,
|
||||||
plan_id: document.getElementById('plan_id').value
|
plan_id: document.getElementById('plan_id').value
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const url = modoRegistro ? '/api/registro' : '/api/login';
|
|
||||||
const res = await fetch(url, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(datos)
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultado = await res.json();
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error(resultado.error || 'Error inesperado');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mensaje.className = 'alert alert-success';
|
try {
|
||||||
mensaje.textContent = resultado.message || (modoRegistro ? 'Registro exitoso' : 'Inicio exitoso');
|
const url = modoRegistro ? '/api/registro' : '/api/login';
|
||||||
mensaje.classList.remove('d-none');
|
const res = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(datos)
|
||||||
|
});
|
||||||
|
|
||||||
if (!modoRegistro) {
|
const resultado = await res.json();
|
||||||
// Redirigir a dashboard, por ejemplo
|
|
||||||
// window.location.href = `/dashboard?tenant=${resultado.uuid}`;
|
if (!res.ok) {
|
||||||
|
throw new Error(resultado.error || 'Error inesperado');
|
||||||
|
}
|
||||||
|
|
||||||
|
mensaje.className = 'alert alert-success';
|
||||||
|
mensaje.textContent = resultado.message || (modoRegistro ? 'Registro exitoso' : 'Inicio exitoso');
|
||||||
|
mensaje.classList.remove('d-none');
|
||||||
|
|
||||||
|
if (!modoRegistro) {
|
||||||
|
// Redirigir a dashboard, por ejemplo
|
||||||
|
// window.location.href = `/dashboard?tenant=${resultado.uuid}`;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
mensaje.className = 'alert alert-danger';
|
||||||
|
mensaje.textContent = err.message;
|
||||||
|
mensaje.classList.remove('d-none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ Ahora la función está declarada correctamente
|
||||||
|
async function cargarPlanes() {
|
||||||
|
const select = document.getElementById('plan_id');
|
||||||
|
select.innerHTML = '<option value="">Cargando planes...</option>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/planes');
|
||||||
|
const planes = await res.json();
|
||||||
|
|
||||||
|
select.innerHTML = '<option value="">Seleccione un plan</option>';
|
||||||
|
planes.forEach(plan => {
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = plan.id;
|
||||||
|
opt.textContent = plan.nombre.charAt(0).toUpperCase() + plan.nombre.slice(1);
|
||||||
|
select.appendChild(opt);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
select.innerHTML = '<option value="">Error al cargar planes</option>';
|
||||||
|
console.error('Error cargando planes:', err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
mensaje.className = 'alert alert-danger';
|
|
||||||
mensaje.textContent = err.message;
|
|
||||||
mensaje.classList.remove('d-none');
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// ✅ Ahora la función está declarada correctamente
|
|
||||||
async function cargarPlanes() {
|
|
||||||
const select = document.getElementById('plan_id');
|
|
||||||
select.innerHTML = '<option value="">Cargando planes...</option>';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch('/planes');
|
|
||||||
const planes = await res.json();
|
|
||||||
|
|
||||||
select.innerHTML = '<option value="">Seleccione un plan</option>';
|
|
||||||
planes.forEach(plan => {
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.value = plan.id;
|
|
||||||
opt.textContent = plan.nombre.charAt(0).toUpperCase() + plan.nombre.slice(1);
|
|
||||||
select.appendChild(opt);
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
select.innerHTML = '<option value="">Error al cargar planes</option>';
|
|
||||||
console.error('Error cargando planes:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user