feat: Update default admin credentials and organization branding, refactor admin creation in install script to direct database insertion, disable rate limiting, and update documentation.

This commit is contained in:
2026-03-13 13:24:06 -03:00
parent c49a49dc19
commit 3167723a89
4 changed files with 96 additions and 35 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ LMS_DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms
# General fallback
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms
# JWT Secret
# JWT Secret (generate with ./generate_jwt_secret.sh)
JWT_SECRET=supersecret
# Logging
@@ -37,8 +37,8 @@ EXTERNAL_TABLE_GRADES=notas
EXTERNAL_ID_TIPO_NOTA=1
# Branding Defaults
DEFAULT_ORG_NAME="OpenCCB"
DEFAULT_PLATFORM_NAME="OpenCCB Learning"
DEFAULT_ORG_NAME="Norteamericano"
DEFAULT_PLATFORM_NAME="Norteamericano Learning"
DEFAULT_LOGO_URL=""
DEFAULT_FAVICON_URL=""
DEFAULT_PRIMARY_COLOR="#3B82F6"
+39
View File
@@ -278,6 +278,14 @@ NEXT_PUBLIC_CMS_API_URL=http://localhost:3001
NEXT_PUBLIC_LMS_API_URL=http://localhost:3002
```
### Default Credentials
After running `./install.sh`, the default admin user is:
- **Email**: `admin@norteamericano.cl`
- **Password**: `Admin123!`
You can customize these during installation.
## Testing
### E2E Tests (Playwright)
@@ -340,6 +348,37 @@ cargo test -p common
## Common Issues
### CORS Errors (Login/Registro)
Si ves errores de CORS al intentar loguearte:
```
Access to fetch at 'http://localhost:3001/auth/login' from origin 'http://localhost:3000'
has been blocked by CORS policy
```
**Solución**: Asegúrate de que el rate limiter NO esté aplicado a las rutas de autenticación.
En `services/cms-service/src/main.rs`, el `GovernorLayer` debe estar solo en `protected_routes`,
no en `public_routes`.
### Rate Limiter Bloqueando Peticiones
**Estado actual**: El rate limiter (`tower_governor`) está **deshabilitado** debido a problemas de compatibilidad con el middleware de autenticación.
Si quieres habilitarlo en producción:
1. Agrega `GovernorLayer` solo a rutas protegidas usando `.route_layer()`
2. Configúralo después del middleware de autenticación
3. Ajusta los límites (por defecto: 10 req/s, burst 50)
```rust
.protected_routes
.route_layer(middleware::from_fn(org_extractor_middleware))
.route_layer(GovernorLayer { config: governor_conf })
```
**Advertencia**: Si el rate limiter está mal configurado, las peticiones a `/courses`, `/auth/login`, etc. pueden fallar con error 500 sin logs.
### Port Conflicts
If port 5432 is occupied, the setup uses 5433:
+52 -21
View File
@@ -241,13 +241,13 @@ if [ "$ADMIN_EXISTS" != "t" ]; then
echo "👤 Configurar Administrador Inicial"
read -p "Nombre Completo [Administrador del Sistema]: " ADMIN_NAME
ADMIN_NAME=${ADMIN_NAME:-Administrador del Sistema}
read -p "Email del Administrador [admin@example.com]: " ADMIN_EMAIL
ADMIN_EMAIL=${ADMIN_EMAIL:-admin@example.com}
read -s -p "Contraseña del Administrador [password123]: " ADMIN_PASS
ADMIN_PASS=${ADMIN_PASS:-password123}
read -p "Email del Administrador [admin@norteamericano.cl]: " ADMIN_EMAIL
ADMIN_EMAIL=${ADMIN_EMAIL:-admin@norteamericano.cl}
read -s -p "Contraseña del Administrador [Admin123!]: " ADMIN_PASS
ADMIN_PASS=${ADMIN_PASS:-Admin123!}
echo ""
read -p "Nombre de la Organización [OpenCCB]: " ORG_NAME
ORG_NAME=${ORG_NAME:-OpenCCB}
read -p "Nombre de la Organización [Norteamericano]: " ORG_NAME
ORG_NAME=${ORG_NAME:-Norteamericano}
fi
# Selective Build/Rebuild
@@ -269,22 +269,12 @@ fi
if [ "$ADMIN_EXISTS" != "t" ]; then
echo "⏳ Esperando a que el API CMS esté listo..."
API_URL="http://localhost:3001"
PAYLOAD=$(cat <<EOF
{
"email": "$ADMIN_EMAIL",
"password": "$ADMIN_PASS",
"full_name": "$ADMIN_NAME",
"organization_name": "$ORG_NAME",
"role": "admin"
}
EOF
)
# Wait until the API actually responds (not just the port being open)
MAX_RETRIES=30
count=0
echo -n "Esperando API"
until curl -s -o /dev/null "$API_URL/auth/login" -H "Content-Type: application/json" -d '{}' 2>/dev/null; do
until curl -s -o /dev/null "$API_URL/health" 2>/dev/null; do
echo -n "."
sleep 2
count=$((count+1))
@@ -296,14 +286,50 @@ EOF
done
echo ""
RESPONSE=$(curl -s -X POST "$API_URL/auth/register" -H "Content-Type: application/json" -d "$PAYLOAD")
# Create admin user directly in database using pgcrypto
echo "🔐 Creando administrador en la base de datos..."
docker exec openccb-db-1 psql -U user -d openccb_cms -c "
CREATE EXTENSION IF NOT EXISTS pgcrypto;
SELECT * FROM fn_register_user(
'$ADMIN_EMAIL',
crypt('$ADMIN_PASS', gen_salt('bf', 12)),
'$ADMIN_NAME',
'admin',
'$ORG_NAME'
);
" 2>/dev/null
if echo "$RESPONSE" | grep -q "token"; then
if [ $? -eq 0 ]; then
echo "✅ ¡Éxito! Administrador creado."
API_KEY=$(docker exec openccb-db-1 psql -U user -d openccb_cms -t -c "SELECT api_key FROM organizations LIMIT 1;" | xargs)
API_KEY=$(docker exec openccb-db-1 psql -U user -d openccb_cms -t -c "SELECT api_key FROM organizations LIMIT 1;" | xargs 2>/dev/null)
echo "🔑 API Key Inicial: $API_KEY"
echo ""
echo "📋 Credenciales de acceso:"
echo " Email: $ADMIN_EMAIL"
echo " Contraseña: $ADMIN_PASS"
else
echo "⚠️ Fallo al crear el administrador. Respuesta: $RESPONSE"
echo "⚠️ Fallo al crear el administrador. Intentando con método alternativo..."
# Fallback: Try API endpoint
PAYLOAD=$(cat <<EOF
{
"email": "$ADMIN_EMAIL",
"password": "$ADMIN_PASS",
"full_name": "$ADMIN_NAME",
"organization_name": "$ORG_NAME",
"role": "admin"
}
EOF
)
RESPONSE=$(curl -s -X POST "$API_URL/auth/register" -H "Content-Type: application/json" -d "$PAYLOAD")
if echo "$RESPONSE" | grep -q "token"; then
echo "✅ ¡Éxito! Administrador creado vía API."
API_KEY=$(docker exec openccb-db-1 psql -U user -d openccb_cms -t -c "SELECT api_key FROM organizations LIMIT 1;" | xargs 2>/dev/null)
echo "🔑 API Key Inicial: $API_KEY"
else
echo "⚠️ Fallo al crear el administrador. Respuesta: $RESPONSE"
fi
fi
else
echo "✅ El administrador ya existe. Saltando registro."
@@ -316,3 +342,8 @@ echo "===================================================="
echo "Studio (Admin/CMS): http://localhost:3000"
echo "Experience (LMS): http://localhost:3003"
echo "===================================================="
echo ""
echo "📋 Notas:"
echo " - Rate limiter: DESHABILITADO (problemas de compatibilidad)"
echo " - Para producción, configura tower_governor en services/cms-service/src/main.rs"
echo "===================================================="
+2 -11
View File
@@ -20,10 +20,7 @@ use dotenvy::dotenv;
use sqlx::postgres::PgPoolOptions;
use std::env;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tower_governor::governor::GovernorConfigBuilder;
use tower_governor::GovernorLayer;
use tower_http::cors::{Any, CorsLayer};
use tower_http::set_header::SetResponseHeaderLayer;
use tower_http::trace::TraceLayer;
@@ -99,14 +96,8 @@ async fn main() {
.allow_methods(Any)
.allow_headers(Any);
// Rate limiting configuration
let governor_conf = Arc::new(
GovernorConfigBuilder::default()
.per_second(10)
.burst_size(50)
.finish()
.unwrap(),
);
// Rate limiting: Deshabilitado temporalmente por problemas de compatibilidad con tower-governor
// Para habilitar en producción, configurar con GovernorLayer y ajustar los límites apropiadamente
// Rutas protegidas que requieren autenticación y contexto de organización
let protected_routes = Router::new()