Importación de feature/registration

This commit is contained in:
2025-09-05 00:45:16 +00:00
parent 25876e733b
commit cbcea72848
5 changed files with 178 additions and 14 deletions
+3 -1
View File
@@ -22,7 +22,9 @@
"express": "^5.1.0",
"express-ejs-layouts": "^2.5.1",
"pg": "^8.16.3",
"pg-format": "^1.0.4"
"pg-format": "^1.0.4",
"openid-client": "^5.6.5",
"cookie-session": "^2.0.0"
},
"keywords": [],
"description": ""
+77
View File
@@ -6,6 +6,9 @@ import cors from 'cors';
import { Pool } from 'pg';
import bcrypt from'bcrypt';
import { Issuer, generators } from 'openid-client';
import cookieSession from 'cookie-session';
// Rutas
import path from 'path';
import { fileURLToPath } from 'url';
@@ -39,6 +42,14 @@ app.set('trust proxy', true);
app.use(express.static(path.join(__dirname, 'pages')));
app.use(cookieSession({
name: 'sid',
secret: process.env.SESSION_SECRET,
httpOnly: true,
sameSite: 'lax',
secure: false // en prod detrás de https: true
}));
// Configuración de conexión PostgreSQL
const dbConfig = {
@@ -65,6 +76,20 @@ async function verificarConexion() {
}
}
// Descubrimiento OIDC (una sola vez)
let oidcClient;
async function getClient() {
if (oidcClient) return oidcClient;
const ISSUER = process.env.OIDC_ISSUER_INTERNAL; // ej: http://authentik:9000/application/o/suitecoffee/
const issuer = await Issuer.discover(`${ISSUER}.well-known/openid-configuration`);
oidcClient = new issuer.Client({
client_id: process.env.OIDC_CLIENT_ID,
client_secret: process.env.OIDC_CLIENT_SECRET,
redirect_uris: [`${process.env.BASE_URL}${process.env.OIDC_REDIRECT_PATH}`],
response_types: ['code']
});
return oidcClient;
}
// === Servir páginas estáticas ===
@@ -178,6 +203,58 @@ app.post('/api/login', async (req, res) => {
});
// --- login: redirige a Authentik con PKCE
app.get('/auth/login', async (req, res) => {
const client = await getClient();
const state = generators.state();
const code_verifier = generators.codeVerifier();
const code_challenge = generators.codeChallenge(code_verifier);
req.session.state = state;
req.session.code_verifier = code_verifier;
const authUrl = client.authorizationUrl({
scope: 'openid profile email',
state,
code_challenge,
code_challenge_method: 'S256'
});
res.redirect(authUrl);
});
// --- callback: intercambia code por tokens y guarda sesión mínima
app.get(process.env.OIDC_REDIRECT_PATH || '/auth/callback', async (req, res) => {
const client = await getClient();
const { state, code } = req.query;
if (!state || state !== req.session.state) {
return res.status(400).send('state inválido');
}
const params = { state, code, code_verifier: req.session.code_verifier };
const tokenSet = await client.callback(`${process.env.BASE_URL}${process.env.OIDC_REDIRECT_PATH}`, params, { state });
// Guarda lo que necesites para pruebas (id_token y claims)
req.session.user = tokenSet.claims();
req.session.id_token = tokenSet.id_token;
req.session.access_token = tokenSet.access_token;
// Redirigí a donde quieras (página de bienvenida)
res.redirect('/auth/me');
});
// --- ver quién soy (para probar)
app.get('/auth/me', (req, res) => {
if (!req.session?.user) return res.status(401).json({ error: 'no autenticado' });
res.json({ user: req.session.user });
});
// --- logout simple (borra cookie)
app.post('/auth/logout', (req, res) => {
req.session = null;
res.status(204).end();
});
// Colores personalizados
let primaryColor = chalk.hex('#'+`${process.env.COL_PRI}`);
let secondaryColor = chalk.hex('#'+`${process.env.COL_SEC}`);