Commit Graph
46 Commits
Author SHA1 Message Date
Jordan Diaz 6397abfabb fix(AcaiAPI): fecha vacia, sellado de auditoria y escapado de ids
1) Un campo `date` con valor vacio rompia TODA insercion en la tabla.

   MySQL rechaza la cadena vacia en una columna datetime ("Incorrect datetime
   value") tanto si es NOT NULL como si es nullable, y bajo el sql_mode
   TRADITIONAL que fuerza Db.php no hay ningun valor "vacio" valido: '' falla,
   NULL falla si la columna es NOT NULL, '0000-00-00' falla por NO_ZERO_DATE y
   omitir la columna falla por no tener default. Bastaba UN campo fecha para que
   dejara de entrar cualquier registro, con un 400 "Error al insertar" sin
   detalle.

   El Admin clasico nunca se topa con esto porque ya lo resuelve:
   menus/default/save.php:287 pone la fecha actual cuando el campo no viene
   ("default date fields to current date"). AcaiAPI nunca replico esa regla —
   coerceValue tiene casos para checkbox, list y multitext, pero no para date.
   Ahora en INSERT hace lo mismo que el Admin; en UPDATE omite la columna, para
   no pisar con "hoy" un valor ya guardado solo porque venga la clave vacia.

   Se descarto la alternativa de crear la columna como NULL DEFAULT NULL: no
   arregla ninguna de las tablas ya existentes (el sync copia ficheros, no
   ejecuta ALTER) y ademas '' seguiria fallando igual.

2) Auditoria: `updatedDate`/`updatedByUserNum` pasan a respetar el valor que
   traiga el caller y generarse solo si no viene. Antes se pisaban siempre
   ("not overridable by the caller"). Alineado con la intencion del cambio de
   Anael en core_client, pero con los guards FUERA del if ($isInsert): dentro,
   un UPDATE se quedaba sin sellar la fecha porque no actuaba ninguna rama.
   No hay doble escritura: cuando el caller lo trae, lo escribe el bucle de
   campos y el guard evita que el bloque de auditoria lo repita en el SET.

3) Seguridad: los ids de las relaciones se escapan antes de interpolarlos en el
   IN (...). Salen del valor guardado de un campo `list`, que es un mediumtext
   sin validacion, asi que era una inyeccion SQL de segundo orden. Ya estaba
   corregido en core_client y faltaba aqui.

Ref: docs/escalados/estado.md 3.1 (repo acai-vscode-plugin)
2026-08-25 15:06:21 +00:00
Jordan Diaz 5861bac1da fix(security): sanear idioma de URL para cerrar XSS reflejado
El parametro ?idioma= llegaba crudo (la query string se reenvia entera a
slug.php via .htaccess) y se reflejaba sin escapar en RUTA_RAIZ/ROOT,
lang="..." y variables JS de las plantillas -> XSS reflejado explotable
en cualquier web (p.ej. ?idioma=';alert(document.cookie);// en contexto JS).

- variables.php: allowlist de idiomas antes de definir constantes/render;
  cualquier valor desconocido se descarta.
- footer.tpl/header.tpl: json_encode en los sinks JS (defensa en profundidad).
2026-07-29 11:48:05 +00:00
Jordan Diaz 46ecbb3f09 fix: tolerar null en $functions/$options de AcaiAPI (compat firma legacy CocoDB)
Los hooks legacy llaman CocoDB::updateRecords(..., null) y el nuevo
buildSetClause tipa $functions como array estricto: TypeError fatal en
PHP 8 (p.ej. pago por transferencia via IPNGenerica). Se normaliza en la
frontera publica (insert/update/get/delete).
2026-07-29 11:32:33 +00:00
Jordan Diaz 7d38e069cd Añadiendo las librerías de payments a sesion 2026-07-29 11:14:46 +00:00
Jordan Diaz 031ef33f9f fix: devolver valores como string en las lecturas (paridad mysql_* legacy)
PDO con prepares nativos devuelve tipos reales (depth=int 0) mientras que
mysql_* devolvia siempre strings. Los templates y codigo Acai comparan
estrictamente contra strings (is same as('0'), === '1'...) y con tipos
nativos esos filtros fallan en silencio — p.ej. el menu del header vacio
en webs importadas (impulse) porque el filtro depth is same as('0') no
matcheaba int(0). stringifyRows normaliza todos los escalares no-NULL a
string en los 5 paths de lectura que devuelven datos hacia fuera: get(),
uploads, cache de queries de relaciones, traducciones y pluginsConfig.
2026-07-22 11:14:55 +00:00
Jordan Diaz fe7e9ee2e6 fix: no inyectar campos de auditoria en tablas raw (ignoreSchema)
buildSetClause añadia siempre updatedDate/updatedByUserNum (y en inserts
createdDate/createdByUserNum), pero las tablas raw que se escriben con
ignoreSchema (aux_plg_config, uploads, traducciones...) no tienen esas
columnas y el INSERT/UPDATE moria con Unknown column — p.ej. guardar la
config de un plugin desde el dashboard fallaba con 'No se pudo guardar la
configuracion en la base de datos'. Se replica la semantica del CocoDB
legacy: prepareBaseSQL solo añadia auditoria y defaults cuando habia
schema cargado.
2026-07-22 09:40:13 +00:00
Jordan Diaz 34d1458f3a perf: self-provision the traducciones index required by batched t()
The batched translation preload requires the (tableName, recordNum,
prefix) index; without it the per-record query scans and is slower
than the legacy per-field lookup. t() now checks once per PHP process
(static) whether idx_tabla_registro_prefijo exists, creates it on the
fly when the DB user has ALTER rights (re-checking after a lost race),
and otherwise falls back to the legacy per-field query — never slower
than the original behavior on webs where the index cannot be created.

Verified live: dropped the index on villagrancanaria local, first
request recreated it automatically and subsequent renders stayed fast.
2026-07-21 18:34:10 +00:00
Jordan Diaz bcd21dd274 perf: batch per-record translation preload in t()
t() issued one SELECT per translated field (1,300+ queries on a typical
multilanguage home). It now preloads all translations of a (table,
record, language) in a single query and serves subsequent fields from
memory, preserving the previous LIMIT 1 semantics (first row per
fieldName). Measured on villagrancanaria: cold render -60% (en home)
/ -67% (es home), byte-identical output.

REQUIRES index (tableName, recordNum, prefix) on cms_traducciones —
without it the batched query scans and is SLOWER than before:
ALTER TABLE cms_traducciones ADD INDEX idx_tabla_registro_prefijo (tableName, recordNum, prefix);
2026-07-21 18:29:46 +00:00
Jordan Diaz 432130565b AcaiAPI data layer + CocoDB facade
AcaiAPI: PDO-based data access layer (prepared statements, JOIN relation
loading, batch upload fetching) developed on villagrancanaria.
CocoDB_alias declares the CocoDB facade delegating to AcaiAPI; the
legacy implementation stays available as CocoDB_old.
2026-07-21 17:29:51 +00:00
Jordan Diaz dd2657a5d3 CmsApi Libraries 2026-06-09 09:44:45 +00:00
Jordan 927888d0d9 Update CocoDB.php 2026-05-12 18:33:16 +01:00
Jordan 2471e9f3e1 Create cmsApiInit.js 2026-04-21 08:09:21 +01:00
Jordan a84eaff98b layout_header_footer 2026-04-20 22:40:47 +01:00
Jordan 130a84a093 dasdas 2026-04-15 20:00:09 +01:00
Jordan f64a790b9b dasdsa 2026-04-15 19:58:40 +01:00
Jordan 4f78c9276e detect 2026-04-15 19:56:57 +01:00
Jordan 6cd37bd2c1 Update funciones.php 2026-04-15 19:53:58 +01:00
Jordan e5948007da mas 2026-04-15 19:53:33 +01:00
Jordan bd1386890b error html 2026-04-15 19:49:59 +01:00
Jordan 7bb61b3691 Update slug.php 2026-04-15 19:28:57 +01:00
Jordan 628231a530 Update .htaccess 2026-04-11 16:33:46 +01:00
Jordan f4e1cb8135 Update .htaccess 2026-04-09 21:25:49 +01:00
Jordan 90f683ccf8 Update .htaccess 2026-04-09 21:24:36 +01:00
Jordan 407038c72f Update funciones.php 2026-04-09 18:32:48 +01:00
Jordan dfc5b7bc75 Update funciones.php 2026-04-09 18:28:54 +01:00
Jordan d64957cb6a Update footer.php 2026-04-09 18:15:11 +01:00
Jordan 9b627ae143 Quitando template/estandar/images 2026-04-08 13:31:51 +01:00
Jordan 8945934dff eliminando js 2026-03-31 14:02:56 +01:00
Jordan e69b25126a aliminamos esta carpeta de la base 2026-03-31 14:00:12 +01:00
Jordan 5f09794479 Update footer.php 2026-03-31 13:20:52 +01:00
Jordan 49db7b5701 Update footer.php 2026-03-31 13:19:27 +01:00
Jordan e50fc5deba Update footer.php 2026-03-31 12:56:46 +01:00
Jordan 3ff8e30b85 Update footer.php 2026-03-29 11:11:59 +01:00
Jordan a72755cffb update sesion.php 2026-03-22 13:13:40 +00:00
Jordan eb7ceef920 update sesion.php 2026-03-22 13:10:14 +00:00
Jordan 49ac4af10d update sesion.php 2026-03-06 18:11:52 +00:00
Jordan aaeeef2e0a update gitignore 2026-03-06 18:11:23 +00:00
Jordan 4e4bfde8a5 Quitando payments 2026-03-05 19:01:22 +00:00
Jordan 48fab839d0 Añadiendo los plugins base payments y cms_api 2026-03-05 18:31:21 +00:00
Jordan 83006dad83 Añadiendo claude a gitignore 2026-03-05 18:27:59 +00:00
JordanandClaude Opus 4.6 a88d61bec7 Add missing language routes and root path definitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:41:03 +00:00
JordanandClaude Opus 4.6 3f251f1d32 Add lib/variables.php without SMTP credentials
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:38:59 +00:00
JordanandClaude Opus 4.6 a3452623bf Add settings.dat.php as empty template for installations
Credentials and personal data cleared, kept as blank
template that gets filled during remote installations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:30:46 +00:00
JordanandClaude Opus 4.6 b16c17d7ce Update .gitignore to exclude sensitive files
Add rules for credentials, SQL dumps, and backup files
to prevent accidental exposure in public repository.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:23:31 +00:00
Jordan eec6c425c5 Añadiendo apartados a 404.php 2026-02-23 16:59:53 +00:00
Jordan 03acc5b013 Initial commit: plantilla base PHP para webs Acai CMS 2026-02-21 21:13:57 +00:00