Replace raw `console.log`/`console.error` calls across CLI, API
handlers, and module files with structured logger functions (`step`,
`done`, `warn`, `fail`) from the shared logger library.
This improves log consistency, readability, and makes it easier to
control output formatting and log levels from a single place.
- Add `./modules/storage` package export pointing to `modules.storage.js`
- Add `modules/*/config.js` to tsup build entries for server-only configs
- Add `@zen/core/modules/storage` to external dependencies in tsup config
- Add `src/modules/modules.storage.js` to the second tsup build target
- Update storage handler to import via `@zen/core/modules/storage` alias
- Rename unused `request` param to `_request` in `handleGetFile`
Refactor storage access control to use dynamic public prefixes
sourced from `getAllStoragePublicPrefixes()` instead of a hardcoded
`blog` check. Each module can now declare its own public storage
prefixes via `defineModule()` storagePublicPrefixes, making the
system extensible without modifying the core handler.
Also adds a `posts` path handler requiring admin access for private
post types, removes the deprecated `version` API endpoint and its
rate-limit exemption, and minor whitespace/comment cleanup.
Replace the single `ZEN_APP_URL` environment variable with the
existing `NEXT_PUBLIC_URL` and `NEXT_PUBLIC_URL_DEV` variables for
CSRF origin resolution.
- Add `resolveAppUrl()` helper that prefers `NEXT_PUBLIC_URL_DEV`
in development and falls back to `NEXT_PUBLIC_URL` in production
- Update `passesCsrfCheck()` to use the new helper
- Update error log messages to reference the new variable names
- Rename `getModuleMetadata` to `getModuleMetadataGenerator` in registry,
index, and client exports to clarify its purpose (returns a generator
function, not a metadata object)
- Add new `getModuleMetadata` and `getMetadataGenerator` exports from
`modules.metadata.js` for server-side metadata object retrieval
- Update route auth format in docs from `requireAuth`/`requireAdmin`
flags to a single `auth` field with values: `'admin'`, `'user'`,
or `'public'`
- Fix `isModuleEnabledInEnv` to replace hyphens with underscores in
env var names (e.g. `my-module` → `ZEN_MODULE_MY_MODULE`)
- Replace `useState` initializer in `ZenProvider` with `useRef` guard
to avoid React strict mode double-invocation issues
Replace the project directory tree and PR integration/versioning
sections with a new "Philosophie de développement" section covering
the NASA Power of Ten rules and security-by-design principles.
Add `typescript@^6.0.2` as an explicit devDependency instead of
relying on it being pulled in transitively. This ensures consistent
TypeScript version usage across the project and makes the dependency
requirement clear.
- Remove `react-email`, `react-grid-layout` from dependencies
- Remove `tailwindcss`, `@tailwindcss/cli`, `@tailwindcss/postcss`,
`autoprefixer`, `postcss`, and `typescript` from devDependencies
- Update package-lock.json to reflect dependency removals
- Bump package version from 1.3.5 to 1.3.6
- Sanitize route handler errors: only surface known auth messages
('Unauthorized', 'Admin access required'); log all other exceptions
server-side and return a generic 'Internal Server Error' to clients
- Derive profile picture content-type from validated file extension
instead of attacker-controlled file.type to prevent MIME spoofing
- Always emit explicit Content-Disposition headers on file responses;
serve known image types as 'inline', force download for all others
to prevent in-browser rendering of potentially dangerous content
- Add X-Content-Type-Options: nosniff and X-Frame-Options: DENY to
file response headers
- **CSRF**: Change missing `ZEN_APP_URL` behavior from bypass (return
`true`) to enforced deny (return `false`) with an error-level log,
preventing unauthenticated access when the env var is misconfigured
- **Version endpoint**: Require authentication on the `/version` route
by passing `request` to `handleVersion`; add session/token validation
inside the handler so version info is no longer publicly accessible
- **Storage handler**: Enforce a minimum path depth of 3 segments for
public blog file access to prevent unintentional root-prefix exposure;
strip raw storage error messages (bucket names, keys) from all client
responses, logging full details server-side only
- **SQL injection hardening**: Wrap the whitelisted `sortColumn`
identifier in double-quotes in the `handleListUsers` query to enforce
identifier boundaries and prevent any edge case from being interpreted
as SQL syntax
- **Misc**: Improve log clarity for orphaned profile picture deletion
failures; add inline comments explaining security rationale throughout
- Add `passesCsrfCheck()` to both `router.js` and `dynamic-router.js`
to block cross-site request forgery on state-mutating methods
(POST/PUT/PATCH/DELETE) by validating Origin/Referer headers against
`ZEN_APP_URL`
- Apply global IP-based rate limiting in `dynamic-router.js` mirroring
the policy already present in `router.js`; exempt health and version
GET endpoints from throttling
- Sanitize 404 response in `dynamic-router.js` to prevent route
structure enumeration
- Strip internal error details from user-facing error messages (e.g.
profile picture deletion) to avoid information leakage
- Remove `zen-setup` binary from package.json and package-lock.json
- Replace manual setup steps with `npx @zen/start` CLI command
- Simplify INSTALL.md by reducing steps from 6 to 4
- Update DEV.md to reflect removal of zen-setup from CLI scripts
- Fix relative path to `.env.example` in documentation
Remove the `ZEN_DESCRIPTION` environment variable from `.env.example`
and its usage in `generateMetadata`. The description field is no longer
needed in the default metadata configuration.
Add three documentation files for the posts module:
- `api.md`: public API reference (list, slug, categories, images)
- `admin-api.md`: admin API reference with all CRUD endpoints
- `integration.md`: Next.js integration examples with code snippets
Update all references across source files, documentation, and
configuration to reflect the new package scope and name. This includes
updating `.npmrc` registry config, install instructions, module
examples, and all import path comments throughout the codebase.
Removes the `./setup` export entry from `package.json` and the
corresponding `src/features/setup/index.js` entry point from
`tsup.config.js`, eliminating the standalone setup feature module
from the public API and build output.
Move `database` and `setup` CLI scripts from their respective feature
directories into a unified `src/cli/` directory. Update `tsup.config.js`
build entries and `package.json` bin paths to reflect the new locations.
- Translate all installation instructions from English to French
- Add new step to configure the npm registry with a `.npmrc` file
- Renumber steps accordingly (now 6 steps instead of 5)
- Add `./modules/define` export path pointing to `defineModule.js`
- Implement `registerExternalModules()` to handle modules passed via `zen.config.js`, with env var gating (`ZEN_MODULE_<NAME>=true`)
- Extract `buildAdminConfig()` helper to consolidate admin navigation/page config building
- Refactor `loadModuleConfig()` to use `buildAdminConfig()` and simplify public routes check
- Improve `initializeModuleTables()` to gracefully skip modules without `db.js` instead of erroring
- Update module discovery JSDoc to reflect external module registration support
Strips out built-in clients, invoice, and nuage modules from core
handlers, module initializers, and action registries. This cleans up
hardcoded module dependencies, leaving only the posts module as a
reference implementation for the modular architecture.