Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65295c9fe1 | ||
|
|
05d4be1af0 | ||
|
|
ac6c8e1fbd | ||
|
|
34db92d5f7 | ||
|
|
bfb6f8df5b | ||
|
|
db7d85133a | ||
|
|
730237d1b9 | ||
|
|
586679d84e | ||
|
|
d00697ca36 | ||
|
|
9526443b4a | ||
|
|
c51c5222d5 | ||
|
|
555d2cb3c1 | ||
|
|
50a0bb9549 | ||
|
|
a90f3e1ef2 | ||
|
|
ec98ea6038 | ||
|
|
383f4bbda0 | ||
|
|
6d3d904aa6 | ||
|
|
8f38d9ea7d | ||
|
|
14c69ed0d2 | ||
|
|
dee931f100 | ||
|
|
adfbc1ded6 | ||
|
|
a0a14921cf | ||
|
|
fe0db50d12 | ||
|
|
490fe6104a | ||
|
|
84690ce1d3 |
@@ -0,0 +1,27 @@
|
|||||||
|
# Escaneo de secretos en cada push y pull request. Este repo es PUBLICO.
|
||||||
|
# Falla si gitleaks encuentra una clave en los commits nuevos.
|
||||||
|
name: gitleaks
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gitleaks:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Instalar gitleaks
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
VERSION=8.21.2
|
||||||
|
curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" -o /tmp/gitleaks.tgz
|
||||||
|
tar -xzf /tmp/gitleaks.tgz -C /tmp gitleaks
|
||||||
|
sudo install -m 755 /tmp/gitleaks /usr/local/bin/gitleaks
|
||||||
|
gitleaks version
|
||||||
|
|
||||||
|
- name: Escanear el historial
|
||||||
|
run: gitleaks git --no-banner --redact --verbose .
|
||||||
Executable
+49
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Hook pre-push: bloquea el push si lo que se va a subir contiene secretos.
|
||||||
|
#
|
||||||
|
# Activar una vez por clon: git config core.hooksPath .githooks
|
||||||
|
#
|
||||||
|
# Este repo es PUBLICO: un secreto que llega al remoto queda expuesto aunque se
|
||||||
|
# borre en el commit siguiente (sigue en el historial). En 2026-03 se filtro asi
|
||||||
|
# una clave de API pegada en .claude/settings.json.
|
||||||
|
#
|
||||||
|
# Si gitleaks esta instalado (https://github.com/gitleaks/gitleaks) se usa el;
|
||||||
|
# si no, se aplica un escaneo minimo con grep sobre los formatos mas comunes.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
remote="$1"
|
||||||
|
z40=0000000000000000000000000000000000000000
|
||||||
|
fallo=0
|
||||||
|
|
||||||
|
while read -r local_ref local_sha remote_ref remote_sha; do
|
||||||
|
[ "$local_sha" = "$z40" ] && continue # borrado de rama: nada que escanear
|
||||||
|
if [ "$remote_sha" = "$z40" ]; then
|
||||||
|
rango="$local_sha" # rama nueva: todo lo alcanzable
|
||||||
|
else
|
||||||
|
rango="$remote_sha..$local_sha"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v gitleaks >/dev/null 2>&1; then
|
||||||
|
if ! gitleaks git --no-banner --redact --log-opts="$rango" . ; then
|
||||||
|
fallo=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Escaneo minimo: lineas AÑADIDAS en el rango con formatos de clave conocidos.
|
||||||
|
hits=$(git log -p --no-color "$rango" -- . ':!*.min.*' ':!*.lock' \
|
||||||
|
| grep -E '^\+' \
|
||||||
|
| grep -E 'AIza[0-9A-Za-z_-]{35}|sk_(live|test)_[0-9A-Za-z]{20,}|ghp_[0-9A-Za-z]{30,}|xox[bp]-[0-9A-Za-z-]{10,}|AKIA[0-9A-Z]{16}|eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}|-----BEGIN [A-Z ]*PRIVATE KEY|(ANTHROPIC_AUTH_TOKEN|ANTHROPIC_API_KEY|OPENAI_API_KEY|API_KEY|SECRET|PASSWORD|TOKEN)["'"'"']?[[:space:]]*[:=][[:space:]]*["'"'"'][^"'"'"']{8,}' \
|
||||||
|
| grep -vE '\$\{?[A-Z_]+\}?|\*\*\*|EJEMPLO|EXAMPLE|placeholder' )
|
||||||
|
if [ -n "$hits" ]; then
|
||||||
|
echo "pre-push: posibles secretos en lo que vas a subir ($rango):" >&2
|
||||||
|
printf '%s\n' "$hits" | cut -c1-120 | sed 's/^/ /' >&2
|
||||||
|
echo "pre-push: instala gitleaks para un escaneo completo. Si es un falso positivo, --no-verify." >&2
|
||||||
|
fallo=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$fallo" -ne 0 ]; then
|
||||||
|
echo "pre-push: PUSH BLOQUEADO. Quita el secreto del commit (git commit --amend o rebase) y rota la clave si ya la has pegado en algun sitio." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# Configuracion LOCAL de Claude Code: aqui van las claves (env con ANTHROPIC_*,
|
||||||
|
# tokens de proveedores...). NUNCA en .claude/settings.json, que es la plantilla
|
||||||
|
# versionada y este repo es PUBLICO. En 2026-03 se filtro una clave por ahi.
|
||||||
|
.claude/settings.local.json
|
||||||
|
|
||||||
|
# Secretos y entorno
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
|
||||||
|
# Ruido de sistema
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -4,9 +4,9 @@ This is an Acai CMS website project. Follow these instructions when working with
|
|||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
- The site runs in Docker, typically at **http://localhost:8080**
|
- The site runs on Acai Forge — get the live editable URL with the `get_web_url` MCP tool (never assume a fixed domain)
|
||||||
- You can make HTTP requests to test pages, APIs, or form submissions
|
- You can make HTTP requests to test pages, APIs, or form submissions against that URL
|
||||||
- If you need to inspect the live site, use browser tools (Playwright MCP) or HTTP requests to localhost:8080
|
- If you need to inspect the live site, use browser tools (Playwright MCP) or HTTP requests to the Forge URL
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
@@ -28,13 +28,7 @@ This is an Acai CMS website project. Follow these instructions when working with
|
|||||||
│ ├── data/schema/ # Database table schemas (JSON)
|
│ ├── data/schema/ # Database table schemas (JSON)
|
||||||
│ ├── lib/plugins/ # CMS plugins
|
│ ├── lib/plugins/ # CMS plugins
|
||||||
│ └── uploads/ # Uploaded media files
|
│ └── uploads/ # Uploaded media files
|
||||||
├── .acai # Project config (domain, tokens, DB credentials)
|
└── .acai # Project config (domain, tokens, DB credentials)
|
||||||
├── .docker/
|
|
||||||
│ ├── .env # Docker environment (DB credentials)
|
|
||||||
│ ├── docker-compose.yml
|
|
||||||
│ ├── tunnel-url.txt # Public tunnel URL (if active)
|
|
||||||
│ └── bore-db-url.txt # Database tunnel URL (if active)
|
|
||||||
└── database.sql # Database dump
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Concepts
|
## Key Concepts
|
||||||
@@ -89,28 +83,9 @@ Rule of thumb:
|
|||||||
|
|
||||||
See [docs/hooks-and-api.md](docs/hooks-and-api.md) for usage.
|
See [docs/hooks-and-api.md](docs/hooks-and-api.md) for usage.
|
||||||
|
|
||||||
## Database Access
|
|
||||||
|
|
||||||
When the site is running in Docker, you can connect to the database:
|
|
||||||
|
|
||||||
- **Host:** `127.0.0.1`
|
|
||||||
- **Port:** Check `.docker/docker-compose.yml` for the mapped port (usually 3307+)
|
|
||||||
- **Credentials:** Read from `.docker/.env`:
|
|
||||||
- `DB_USERNAME`
|
|
||||||
- `DB_PASSWORD`
|
|
||||||
- `DB_DATABASE`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker exec -it dw-<project-name>-db mysql -u root -p<password> <database>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Important:** Table names in CmsApi/Twig do NOT use the `cms_` prefix. The primary key is always `num`, never `id`.
|
|
||||||
|
|
||||||
## Acai Core (web-base)
|
## Acai Core (web-base)
|
||||||
|
|
||||||
The project workspace contains only the **customization layer** (modules, hooks, schemas, uploads). The CMS core (routing, rendering engine, admin panel, APIs) lives in a separate directory called **web-base** that is mounted as a Docker volume.
|
The project workspace contains only the **customization layer** (modules, hooks, schemas, uploads). The CMS core (routing, rendering engine, admin panel, APIs) lives in a separate, shared directory called **web-base**.
|
||||||
|
|
||||||
The web-base path can be obtained via: `GET http://localhost:9090/api/web-base-path`
|
|
||||||
|
|
||||||
Do NOT modify web-base files — they are shared across all projects.
|
Do NOT modify web-base files — they are shared across all projects.
|
||||||
|
|
||||||
@@ -129,6 +104,7 @@ Do NOT modify web-base files — they are shared across all projects.
|
|||||||
11. Twig concatenation uses `~` operator: `'value=' ~ variable`
|
11. Twig concatenation uses `~` operator: `'value=' ~ variable`
|
||||||
12. `enlace` (link) fields already include slashes — **NEVER modify an existing enlace** unless explicitly asked
|
12. `enlace` (link) fields already include slashes — **NEVER modify an existing enlace** unless explicitly asked
|
||||||
13. **NEVER modify the `controlador` field** of existing records — it defines whether a page is Builder or Standard
|
13. **NEVER modify the `controlador` field** of existing records — it defines whether a page is Builder or Standard
|
||||||
|
14. **This repository is PUBLIC. NEVER commit secrets** (API keys, `ANTHROPIC_*` tokens, passwords). Local Claude Code config with credentials goes in `.claude/settings.local.json` (git-ignored), never in `.claude/settings.json`. Enable the secret-scanning hook once per clone: `git config core.hooksPath .githooks`. A leaked key stays in git history even after deleting it: rotate it immediately.
|
||||||
|
|
||||||
## MCP Tools
|
## MCP Tools
|
||||||
|
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ El nombre del campo de imagen viene de `builder.json` → `vars.NOMBRE.relations
|
|||||||
- `tableName`: `"builder_custom"` (siempre, sin prefijo cms_)
|
- `tableName`: `"builder_custom"` (siempre, sin prefijo cms_)
|
||||||
- `recordId`: el `recordNum` del paso 1 (ej: `"778"`)
|
- `recordId`: el `recordNum` del paso 1 (ej: `"778"`)
|
||||||
- `fieldName`: el campo de relations del builder.json (ej: `"image1"`)
|
- `fieldName`: el campo de relations del builder.json (ej: `"image1"`)
|
||||||
- `imageUrl`: URL completa accesible desde Docker
|
- `imageUrl`: URL completa y públicamente accesible
|
||||||
3. `reorder_record_uploads` si es necesario — pasar array de upload IDs en el orden deseado
|
3. `reorder_record_uploads` si es necesario — pasar array de upload IDs en el orden deseado
|
||||||
4. `list_record_uploads` para verificar
|
4. `list_record_uploads` para verificar
|
||||||
|
|
||||||
|
|||||||
@@ -56,13 +56,15 @@ return [
|
|||||||
|
|
||||||
### Testing Hooks
|
### Testing Hooks
|
||||||
|
|
||||||
El Docker debe estar corriendo. Hacer curl al endpoint del hook:
|
Usa la URL editable de Forge del proyecto (`get_web_url`) — no hace falta ningún servidor local. Haz
|
||||||
|
`curl` al endpoint del hook contra esa URL:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8080/hooks/example_hook/
|
curl https://<tu-url-de-forge>/hooks/example_hook/
|
||||||
```
|
```
|
||||||
|
|
||||||
No usar X-Hooks-Token en desarrollo local.
|
Para diagnosticar sin depender del enrutado HTTP directo (que en Forge puede dar 404 — ver más abajo),
|
||||||
|
usa el patrón vía filtro `| hook` desde un módulo/página temporal.
|
||||||
|
|
||||||
### Cómo Llamar Hooks
|
### Cómo Llamar Hooks
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user