@reldens/cms 0.51.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/architecture-guide.md +450 -0
- package/.claude/security-guide.md +102 -0
- package/.claude/seo-guide.md +167 -0
- package/.claude/templating-system-guide.md +29 -0
- package/CLAUDE.md +93 -540
- package/bin/reldens-cms-generate-entities.js +3 -31
- package/bin/reldens-cms-update-password.js +2 -17
- package/install/index.html +4 -0
- package/lib/admin-manager/router-contents.js +1 -0
- package/lib/frontend/content-renderer.js +1 -0
- package/lib/frontend/template-cache.js +1 -1
- package/lib/frontend/template-resolver.js +7 -2
- package/lib/frontend.js +38 -6
- package/lib/manager.js +11 -1
- package/lib/mysql-installer.js +2 -1
- package/lib/sitemap-loader.js +101 -0
- package/lib/template-engine/collections-transformer.js +43 -6
- package/lib/template-engine.js +1 -5
- package/migrations/default-blocks.sql +1 -1
- package/migrations/default-entity-access.sql +1 -1
- package/migrations/default-forms.sql +0 -1
- package/migrations/default-homepage.sql +7 -7
- package/migrations/default-sitemaps-and-robots.sql +44 -0
- package/migrations/default-user.sql +1 -1
- package/migrations/users-authentication.sql +1 -1
- package/package.json +2 -2
- package/templates/layouts/raw.html +1 -0
- package/templates/raw.html +1 -0
- package/templates/robots.txt +3 -0
- package/templates/sitemap.xml +9 -0
package/CLAUDE.md
CHANGED
|
@@ -5,6 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
5
5
|
## Package Overview
|
|
6
6
|
|
|
7
7
|
**@reldens/cms** is a comprehensive Content Management System package for Reldens. It provides a complete web application framework with:
|
|
8
|
+
|
|
8
9
|
- Database-driven content management with entity access control
|
|
9
10
|
- Multi-domain support with domain-specific templates
|
|
10
11
|
- Powerful template engine with Mustache integration
|
|
@@ -32,560 +33,126 @@ npx reldens-cms-update-password --email=admin@example.com
|
|
|
32
33
|
npm run generate-entities
|
|
33
34
|
```
|
|
34
35
|
|
|
35
|
-
##
|
|
36
|
+
## Quick Start
|
|
36
37
|
|
|
37
|
-
###
|
|
38
|
+
### Password Management
|
|
38
39
|
|
|
39
|
-
The CMS
|
|
40
|
+
The CMS automatically encrypts passwords using PBKDF2 (100k iterations, SHA-512) when saving user records through the admin panel.
|
|
40
41
|
|
|
42
|
+
**CLI Password Update:**
|
|
41
43
|
```bash
|
|
42
|
-
# Interactive mode (recommended
|
|
44
|
+
# Interactive mode (recommended)
|
|
43
45
|
npx reldens-cms-update-password --email=admin@example.com
|
|
44
|
-
|
|
45
|
-
# By username
|
|
46
|
-
npx reldens-cms-update-password --username=admin
|
|
47
|
-
|
|
48
|
-
# With password in command (less secure)
|
|
49
|
-
npx reldens-cms-update-password --email=admin@example.com --password=newPassword123
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
**Options**:
|
|
53
|
-
- `--email=[email]` - User email address
|
|
54
|
-
- `--username=[username]` - User username
|
|
55
|
-
- `--password=[password]` - New password (prompted if not provided)
|
|
56
|
-
- `--help` or `-h` - Show this help message
|
|
57
|
-
|
|
58
|
-
**Notes**:
|
|
59
|
-
- Works with any storage driver (prisma, objection-js, mikro-orm)
|
|
60
|
-
- Uses `RELDENS_STORAGE_DRIVER` environment variable to detect the driver
|
|
61
|
-
- Automatically loads entities and Prisma client (if using Prisma)
|
|
62
|
-
|
|
63
|
-
### Automatic Password Encryption
|
|
64
|
-
|
|
65
|
-
The CMS automatically encrypts passwords when saving user records through the admin panel using the `PasswordEncryptionHandler`:
|
|
66
|
-
|
|
67
|
-
- Listens to `reldens.adminBeforeEntitySave` event
|
|
68
|
-
- Detects password field changes in users entity
|
|
69
|
-
- Encrypts passwords using PBKDF2 (100k iterations, SHA-512)
|
|
70
|
-
- Stores passwords in `salt:hash` format
|
|
71
|
-
- **Enabled by default** - can be disabled with `enablePasswordEncryption: false` in Manager config
|
|
72
|
-
|
|
73
|
-
**Password Encryption Algorithm**:
|
|
74
|
-
- **Method**: PBKDF2 (Password-Based Key Derivation Function 2)
|
|
75
|
-
- **Iterations**: 100,000
|
|
76
|
-
- **Key Length**: 64 bytes
|
|
77
|
-
- **Digest**: SHA-512
|
|
78
|
-
- **Salt Length**: 32 bytes (randomly generated)
|
|
79
|
-
- **Storage Format**: `salt:hash` (192 characters total)
|
|
80
|
-
|
|
81
48
|
See `.claude/password-management-guide.md` for comprehensive password management documentation.
|
|
82
49
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
The CMS follows a modular architecture with specialized classes following SOLID principles:
|
|
86
|
-
|
|
87
|
-
### Core Orchestrators
|
|
88
|
-
|
|
89
|
-
**lib/manager.js** - Main CMS orchestrator
|
|
90
|
-
- Initializes all services (data server, admin, frontend)
|
|
91
|
-
- Handles configuration and environment variables
|
|
92
|
-
- Manages multi-domain setup and security
|
|
93
|
-
- Coordinates service lifecycle
|
|
94
|
-
- Initializes password encryption handler
|
|
95
|
-
|
|
96
|
-
**lib/frontend.js** - Frontend orchestrator
|
|
97
|
-
- Coordinates all frontend operations
|
|
98
|
-
- Manages template engine, cache, and rendering
|
|
99
|
-
- Handles search and dynamic forms
|
|
100
|
-
- Routes requests to appropriate handlers
|
|
101
|
-
|
|
102
|
-
**lib/admin-manager.js** - Admin panel orchestrator
|
|
103
|
-
- Manages admin panel routes and authentication
|
|
104
|
-
- Handles entity CRUD operations
|
|
105
|
-
- Processes file uploads
|
|
106
|
-
- Builds admin UI from entity configurations
|
|
107
|
-
|
|
108
|
-
**lib/password-encryption-handler.js** - Password encryption handler
|
|
109
|
-
- Automatic password encryption for users entity
|
|
110
|
-
- Event-driven architecture
|
|
111
|
-
- PBKDF2 encryption with 100k iterations
|
|
112
|
-
- Detects and skips already-encrypted passwords
|
|
113
|
-
- Configurable entity and field names
|
|
114
|
-
|
|
115
|
-
**lib/admin-manager/router-contents.js** - Admin routing and form handling
|
|
116
|
-
- Password field handling (type="password", empty on edit)
|
|
117
|
-
- Password updates optional (skip if empty when editing)
|
|
118
|
-
- Configurable password field names via `passwordFieldNames`
|
|
119
|
-
|
|
120
|
-
### Installation & Setup
|
|
121
|
-
|
|
122
|
-
**lib/installer.js** - Installation orchestrator
|
|
123
|
-
- Web-based installer with subprocess management
|
|
124
|
-
- Dependency checking and installation
|
|
125
|
-
- Database schema creation
|
|
126
|
-
- Environment file generation
|
|
127
|
-
- Post-installation callbacks
|
|
128
|
-
|
|
129
|
-
**lib/mysql-installer.js** - Database-specific installation
|
|
130
|
-
- MySQL schema creation
|
|
131
|
-
- Schema migration support
|
|
132
|
-
- Database validation
|
|
133
|
-
|
|
134
|
-
**lib/prisma-subprocess-worker.js** - Subprocess worker
|
|
135
|
-
- Handles Prisma client generation
|
|
136
|
-
- Progress tracking for long operations
|
|
137
|
-
|
|
138
|
-
### Frontend Architecture (lib/frontend/)
|
|
139
|
-
|
|
140
|
-
**template-resolver.js** - Template discovery
|
|
141
|
-
- Domain-aware template resolution
|
|
142
|
-
- Fallback system (domain → default → base)
|
|
143
|
-
- Layout and partial template lookup
|
|
144
|
-
- Path-to-template mapping
|
|
145
|
-
|
|
146
|
-
**template-cache.js** - Template caching
|
|
147
|
-
- Loads and caches partials
|
|
148
|
-
- Domain-specific template management
|
|
149
|
-
- Partial inheritance and overrides
|
|
150
|
-
|
|
151
|
-
**request-processor.js** - Request routing
|
|
152
|
-
- Route database lookup
|
|
153
|
-
- Domain extraction from requests
|
|
154
|
-
- Path normalization
|
|
155
|
-
- Cache key generation
|
|
156
|
-
|
|
157
|
-
**entity-access-manager.js** - Entity access control
|
|
158
|
-
- Loads entity access rules
|
|
159
|
-
- Public/private entity validation
|
|
160
|
-
- Entity lookup by path
|
|
161
|
-
|
|
162
|
-
**content-renderer.js** - Content generation
|
|
163
|
-
- Main content rendering logic
|
|
164
|
-
- Route-based content generation
|
|
165
|
-
- Template processing
|
|
166
|
-
- Meta field handling
|
|
167
|
-
|
|
168
|
-
**response-manager.js** - Response handling
|
|
169
|
-
- HTTP response management
|
|
170
|
-
- Cache integration
|
|
171
|
-
- Error handling (404, 500)
|
|
172
|
-
|
|
173
|
-
### Template Engine (lib/template-engine.js & lib/template-engine/)
|
|
174
|
-
|
|
175
|
-
**template-engine.js** - Core template processor
|
|
176
|
-
- Orchestrates all template transformers
|
|
177
|
-
- System variables injection
|
|
178
|
-
- Event-driven rendering pipeline
|
|
179
|
-
- Mustache integration
|
|
180
|
-
|
|
181
|
-
**Template Transformers:**
|
|
182
|
-
- **entities-transformer.js** - Single entity rendering `<entity name="cmsBlocks" field="name" value="header"/>`
|
|
183
|
-
- **collections-transformer.js** - Collection loops with pagination
|
|
184
|
-
- **collections-single-transformer.js** - Single field collections
|
|
185
|
-
- **partials-transformer.js** - Partial template processing
|
|
186
|
-
- **forms-transformer.js** - Dynamic forms rendering `<cmsForm key="contact"/>`
|
|
187
|
-
- **url-transformer.js** - URL generation `[url(/path)]`
|
|
188
|
-
- **asset-transformer.js** - Asset URLs `[asset(/img/logo.png)]`
|
|
189
|
-
- **cdn-transformer.js** - CDN URL transformation
|
|
190
|
-
- **date-transformer.js** - Date formatting `[date(now, Y-m-d)]`
|
|
191
|
-
- **translate-transformer.js** - Internationalization `[translate(key)]`
|
|
192
|
-
|
|
193
|
-
**system-variables-provider.js** - System variables
|
|
194
|
-
- Current request context (host, path, protocol)
|
|
195
|
-
- Current route data
|
|
196
|
-
- Current domain information
|
|
197
|
-
- System information (environment, timestamp)
|
|
198
|
-
|
|
199
|
-
**translation-service.js** - Translation loading
|
|
200
|
-
- JSON translation file management
|
|
201
|
-
- Locale detection
|
|
202
|
-
- Fallback handling
|
|
203
|
-
|
|
204
|
-
### Dynamic Forms System
|
|
205
|
-
|
|
206
|
-
**lib/dynamic-form.js** - Form validation and processing
|
|
207
|
-
- Schema-based validation
|
|
208
|
-
- Honeypot protection
|
|
209
|
-
- Rate limiting integration
|
|
210
|
-
- Data sanitization
|
|
211
|
-
- Database storage
|
|
212
|
-
|
|
213
|
-
**lib/dynamic-form-renderer.js** - Form template rendering
|
|
214
|
-
- Domain-aware form templates
|
|
215
|
-
- Field type templates
|
|
216
|
-
- Error display
|
|
217
|
-
- Form attribute handling
|
|
218
|
-
|
|
219
|
-
**lib/dynamic-form-request-handler.js** - Form request handling
|
|
220
|
-
- POST request processing
|
|
221
|
-
- Validation orchestration
|
|
222
|
-
- Success/error redirects
|
|
223
|
-
- JSON response support
|
|
224
|
-
|
|
225
|
-
### Search System
|
|
226
|
-
|
|
227
|
-
**lib/search.js** - Search functionality
|
|
228
|
-
- Multi-entity search
|
|
229
|
-
- Custom search sets
|
|
230
|
-
- Query parameter parsing
|
|
231
|
-
- Pagination support
|
|
232
|
-
|
|
233
|
-
**lib/search-renderer.js** - Search result rendering
|
|
234
|
-
- Template-based result display
|
|
235
|
-
- Custom column classes
|
|
236
|
-
- Domain-aware templates
|
|
237
|
-
|
|
238
|
-
**lib/search-request-handler.js** - Search request handling
|
|
239
|
-
- Query processing
|
|
240
|
-
- Template data support
|
|
241
|
-
- Error handling
|
|
242
|
-
|
|
243
|
-
### Cache System (lib/cache/)
|
|
244
|
-
|
|
245
|
-
**cache-manager.js** - Cache orchestrator
|
|
246
|
-
- Domain and path-based caching
|
|
247
|
-
- Cache invalidation
|
|
248
|
-
- Enable/disable functionality
|
|
249
|
-
|
|
250
|
-
**cache-routes-handler.js** - Cache admin routes
|
|
251
|
-
- Cache clearing endpoints
|
|
252
|
-
- Cache management UI integration
|
|
253
|
-
|
|
254
|
-
**add-cache-button-subscriber.js** - Cache UI integration
|
|
255
|
-
- Adds cache buttons to admin panel
|
|
256
|
-
- Event-driven cache controls
|
|
257
|
-
|
|
258
|
-
### Admin System (lib/admin-manager/)
|
|
259
|
-
|
|
260
|
-
**router.js** - Admin routing
|
|
261
|
-
- Authentication middleware
|
|
262
|
-
- Session management
|
|
263
|
-
- CRUD route setup
|
|
264
|
-
- File upload handling
|
|
265
|
-
|
|
266
|
-
**router-contents.js** - Admin content generation
|
|
267
|
-
- List view generation
|
|
268
|
-
- Edit form generation
|
|
269
|
-
- Relation handling
|
|
270
|
-
- Save/delete processing
|
|
271
|
-
|
|
272
|
-
**contents-builder.js** - Admin UI builder
|
|
273
|
-
- Sidebar navigation
|
|
274
|
-
- Entity list/edit views
|
|
275
|
-
- Form field generation
|
|
276
|
-
- Branding and styling
|
|
277
|
-
|
|
278
|
-
**admin-filters-manager.js** - Entity filtering
|
|
279
|
-
- Filter UI generation
|
|
280
|
-
- Query building
|
|
281
|
-
|
|
282
|
-
**default-translations.js** - Admin translations
|
|
283
|
-
- Default English labels
|
|
284
|
-
- Extensible translation system
|
|
285
|
-
|
|
286
|
-
### Utility Classes
|
|
287
|
-
|
|
288
|
-
**lib/entities-loader.js** - Entity loading from files
|
|
289
|
-
**lib/loaded-entities-processor.js** - Entity configuration processing
|
|
290
|
-
**lib/admin-entities-generator.js** - Admin entity configuration
|
|
291
|
-
**lib/admin-templates-loader.js** - Admin template loading
|
|
292
|
-
**lib/templates-to-path-mapper.js** - Template path mapping
|
|
293
|
-
**lib/templates-list.js** - Template file list
|
|
294
|
-
**lib/json-fields-parser.js** - JSON field parsing
|
|
295
|
-
**lib/pagination-handler.js** - Pagination logic
|
|
296
|
-
**lib/template-reloader.js** - Development template reloading
|
|
297
|
-
**lib/cms-pages-route-manager.js** - CMS page routing
|
|
298
|
-
**lib/admin-manager-validator.js** - Admin config validation
|
|
299
|
-
**lib/admin-dist-helper.js** - Admin asset distribution
|
|
300
|
-
**lib/mime-types.js** - File type definitions
|
|
301
|
-
**lib/allowed-extensions.js** - Upload extension whitelist
|
|
302
|
-
|
|
303
|
-
## Database Schema
|
|
304
|
-
|
|
305
|
-
The CMS uses these core tables:
|
|
306
|
-
|
|
307
|
-
### Content Tables
|
|
308
|
-
- **routes** - URL routing with SEO metadata (title, description, keywords)
|
|
309
|
-
- **cms_pages** - Page content with layout assignments
|
|
310
|
-
- **cms_blocks** - Reusable content blocks (by name identifier)
|
|
311
|
-
- **cms_forms** - Dynamic form configurations with JSON schema
|
|
312
|
-
- **cms_forms_submitted** - Form submission storage with JSON data
|
|
313
|
-
|
|
314
|
-
### Access Control
|
|
315
|
-
- **entities_access** - Entity visibility and operation rules
|
|
316
|
-
- **entities_meta** - Generic metadata storage
|
|
317
|
-
- **cms_pages_meta** - Page-specific metadata
|
|
318
|
-
|
|
319
|
-
### User Management (Optional)
|
|
320
|
-
- **users** - User authentication (with encrypted passwords)
|
|
321
|
-
- **roles** - Role definitions
|
|
322
|
-
|
|
323
|
-
## Template System
|
|
324
|
-
|
|
325
|
-
### Template Directory Structure
|
|
326
|
-
```
|
|
327
|
-
templates/
|
|
328
|
-
├── domains/ # Domain-specific templates
|
|
329
|
-
│ └── example.com/
|
|
330
|
-
│ ├── layouts/ # Domain layouts
|
|
331
|
-
│ ├── partials/ # Domain partials
|
|
332
|
-
│ ├── cms_forms/ # Domain form templates
|
|
333
|
-
│ └── page.html # Domain page wrapper
|
|
334
|
-
├── layouts/ # Default layouts (body content only)
|
|
335
|
-
│ ├── default.html
|
|
336
|
-
│ └── full-width.html
|
|
337
|
-
├── partials/ # Default partials
|
|
338
|
-
├── cms_forms/ # Default form templates
|
|
339
|
-
│ ├── form.html
|
|
340
|
-
│ ├── field_text.html
|
|
341
|
-
│ └── field_email.html
|
|
342
|
-
├── translations/ # i18n files
|
|
343
|
-
│ ├── en.json
|
|
344
|
-
│ └── es.json
|
|
345
|
-
├── page.html # Base HTML wrapper
|
|
346
|
-
└── 404.html # Error page
|
|
347
|
-
```
|
|
50
|
+
### Architecture
|
|
348
51
|
|
|
349
|
-
|
|
350
|
-
1. Domain-specific: `templates/domains/{domain}/template.html`
|
|
351
|
-
2. Default: `templates/template.html`
|
|
352
|
-
3. Base: Package default templates
|
|
52
|
+
The CMS follows a modular architecture with specialized classes:
|
|
353
53
|
|
|
354
|
-
|
|
54
|
+
- **Manager** - Main CMS orchestrator
|
|
55
|
+
- **Frontend** - Frontend operations coordinator
|
|
56
|
+
- **Admin Manager** - Admin panel orchestrator
|
|
57
|
+
- **Template Engine** - Template processing and rendering
|
|
58
|
+
- **Dynamic Forms** - Form validation and processing
|
|
59
|
+
- **Search** - Multi-entity search functionality
|
|
60
|
+
- **Cache** - Domain and path-based caching
|
|
355
61
|
|
|
356
|
-
|
|
357
|
-
```html
|
|
358
|
-
<entity name="cmsBlocks" field="name" value="header-main"/>
|
|
359
|
-
<entity name="articles" id="123"/>
|
|
360
|
-
```
|
|
62
|
+
See `.claude/architecture-guide.md` for detailed architecture documentation.
|
|
361
63
|
|
|
362
|
-
|
|
363
|
-
```html
|
|
364
|
-
<collection name="articles" filters="{featured: true}" data="{limit: 5, sortBy: 'created_at', sortDirection: 'desc'}">
|
|
365
|
-
<div class="article">
|
|
366
|
-
<h3>{{row.title}}</h3>
|
|
367
|
-
<p>{{row.summary}}</p>
|
|
368
|
-
</div>
|
|
369
|
-
</collection>
|
|
370
|
-
```
|
|
64
|
+
### SEO: Sitemaps and Robots.txt
|
|
371
65
|
|
|
372
|
-
|
|
373
|
-
```html
|
|
374
|
-
<collection name="articles" filters="{}" data="{limit: 10}" pagination="articles-list" container="pagedCollection" prevPages="2" nextPages="2">
|
|
375
|
-
<article>{{row.title}}</article>
|
|
376
|
-
</collection>
|
|
377
|
-
```
|
|
66
|
+
The CMS provides built-in support for dynamic robots.txt and sitemap.xml generation:
|
|
378
67
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
<cmsForm key="contactForm" fields="name,email,message" submitButtonText="Send Message"/>
|
|
382
|
-
```
|
|
68
|
+
- `/robots.txt` - Static template with sitemap reference
|
|
69
|
+
- `/sitemap.xml` - Dynamic sitemap with automatic domain filtering
|
|
383
70
|
|
|
384
|
-
|
|
385
|
-
```html
|
|
386
|
-
<partial name="hero"
|
|
387
|
-
title="Welcome"
|
|
388
|
-
subtitle="To our site"
|
|
389
|
-
imageUrl="/img/hero.jpg"/>
|
|
390
|
-
```
|
|
71
|
+
See `.claude/seo-guide.md` for detailed SEO documentation.
|
|
391
72
|
|
|
392
|
-
|
|
393
|
-
```html
|
|
394
|
-
{{>cardView -{row}-}}
|
|
395
|
-
{{>hero -{title: "Welcome", subtitle: "To our site"}-}}
|
|
396
|
-
```
|
|
73
|
+
### Template System
|
|
397
74
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
{{currentDomain.current}}
|
|
404
|
-
{{systemInfo.timestamp}}
|
|
405
|
-
{{currentEntity.title}} <!-- In child blocks -->
|
|
406
|
-
```
|
|
75
|
+
Templates use a three-layer rendering system:
|
|
76
|
+
|
|
77
|
+
1. **Content Processing** - Variables, collections, entities, and forms
|
|
78
|
+
2. **Layout Wrapping** - Header, sidebar, footer structure
|
|
79
|
+
3. **Template Wrapping** - Final HTML document structure
|
|
407
80
|
|
|
408
81
|
**Template Functions:**
|
|
409
82
|
```html
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
[
|
|
83
|
+
<entity name="cmsBlocks" field="name" value="header-main"/>
|
|
84
|
+
<collection name="articles" filters="{featured: true}">
|
|
85
|
+
<h3>{{row.title}}</h3>
|
|
86
|
+
</collection>
|
|
87
|
+
<cmsForm key="contactForm"/>
|
|
88
|
+
[url(/articles)]
|
|
89
|
+
[cdn(/css/styles.css)]
|
|
90
|
+
[asset(/web/logo.png)]
|
|
91
|
+
[date(now, Y-m-d)]
|
|
92
|
+
[translate(welcome.message)]
|
|
416
93
|
```
|
|
417
94
|
|
|
418
|
-
|
|
419
|
-
- `[url()]` - Application routes (never uses CDN)
|
|
420
|
-
- `[cdn()]` - Static assets outside `/assets` (CSS, JS, fonts)
|
|
421
|
-
- `[asset()]` - Static assets inside `/assets` folder (images, media)
|
|
422
|
-
|
|
423
|
-
See `.claude/templating-system-guide.md` for detailed URL transformer documentation.
|
|
95
|
+
See `.claude/templating-system-guide.md` for detailed template documentation.
|
|
424
96
|
|
|
425
|
-
|
|
97
|
+
### Configuration
|
|
426
98
|
|
|
427
|
-
|
|
99
|
+
**Environment Variables (.env):**
|
|
428
100
|
```bash
|
|
429
|
-
# Server
|
|
430
101
|
RELDENS_APP_HOST=http://localhost
|
|
431
102
|
RELDENS_APP_PORT=8080
|
|
432
|
-
|
|
433
|
-
# Admin
|
|
434
103
|
RELDENS_ADMIN_ROUTE_PATH=/admin
|
|
435
104
|
RELDENS_ADMIN_SECRET=your-secret-key
|
|
436
|
-
|
|
437
|
-
# Database
|
|
438
105
|
RELDENS_DB_CLIENT=mysql
|
|
439
|
-
RELDENS_DB_HOST=localhost
|
|
440
|
-
RELDENS_DB_PORT=3306
|
|
441
|
-
RELDENS_DB_NAME=cms_db
|
|
442
|
-
RELDENS_DB_USER=username
|
|
443
|
-
RELDENS_DB_PASSWORD=password
|
|
444
106
|
RELDENS_STORAGE_DRIVER=prisma
|
|
445
|
-
|
|
446
|
-
# Multi-domain
|
|
447
|
-
RELDENS_DEFAULT_DOMAIN=example.com
|
|
448
|
-
RELDENS_DOMAIN_MAPPING={"dev.example.com":"development"}
|
|
449
|
-
RELDENS_SITE_KEY_MAPPING={"example.com":"main"}
|
|
450
|
-
RELDENS_DOMAIN_PUBLIC_URL_MAPPING={"example.com":"https://cdn.example.com"}
|
|
451
|
-
RELDENS_DOMAIN_CDN_MAPPING={"example.com":"https://cdn.example.com"}
|
|
452
107
|
```
|
|
453
108
|
|
|
454
|
-
|
|
109
|
+
**Manager Configuration:**
|
|
455
110
|
```javascript
|
|
456
111
|
const { Manager } = require('@reldens/cms');
|
|
457
112
|
|
|
458
113
|
const cms = new Manager({
|
|
459
114
|
projectRoot: process.cwd(),
|
|
460
|
-
|
|
461
|
-
// Entity access control
|
|
462
115
|
entityAccess: {
|
|
463
|
-
articles: { public: true, operations: ['read'] }
|
|
464
|
-
cmsPages: { public: true, operations: ['read'] },
|
|
465
|
-
users: { public: false }
|
|
116
|
+
articles: { public: true, operations: ['read'] }
|
|
466
117
|
},
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
authenticationMethod: 'db-users', // or 'custom'
|
|
470
|
-
authenticationCallback: async (email, password, roleId) => {
|
|
471
|
-
// Custom auth logic
|
|
472
|
-
},
|
|
473
|
-
adminRoleId: 99,
|
|
474
|
-
|
|
475
|
-
// Password encryption (enabled by default)
|
|
476
|
-
enablePasswordEncryption: true, // Set to false to disable
|
|
477
|
-
|
|
478
|
-
// Performance
|
|
118
|
+
authenticationMethod: 'db-users',
|
|
119
|
+
enablePasswordEncryption: true,
|
|
479
120
|
cache: true,
|
|
480
|
-
reloadTime: -1,
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
// Multi-domain
|
|
484
|
-
defaultDomain: 'example.com',
|
|
485
|
-
domainMapping: {'dev.example.com': 'development'},
|
|
486
|
-
siteKeyMapping: {'example.com': 'main'},
|
|
487
|
-
|
|
488
|
-
// Custom entities and translations
|
|
489
|
-
entitiesConfig: {},
|
|
490
|
-
entitiesTranslations: {},
|
|
491
|
-
adminTranslations: {}
|
|
121
|
+
reloadTime: -1,
|
|
122
|
+
defaultDomain: 'example.com'
|
|
492
123
|
});
|
|
493
124
|
|
|
494
125
|
await cms.start();
|
|
495
126
|
```
|
|
496
127
|
|
|
497
|
-
|
|
128
|
+
See `.claude/configuration-guide.md` for detailed configuration documentation.
|
|
129
|
+
|
|
130
|
+
### Event System
|
|
498
131
|
|
|
499
132
|
The CMS provides extensive event hooks for customization:
|
|
500
133
|
|
|
501
|
-
|
|
134
|
+
**Manager Events:**
|
|
502
135
|
- `reldens.cmsManagerInitializeServices` - Before service initialization
|
|
503
136
|
- `reldens.manager.initializeAdminManager` - Before admin initialization
|
|
504
137
|
|
|
505
|
-
|
|
138
|
+
**Template Events:**
|
|
506
139
|
- `reldens.afterVariablesCreated` - Modify system variables
|
|
507
140
|
- `reldens.beforeContentProcess` - Before template processing
|
|
508
141
|
- `reldens.afterContentProcess` - After template processing
|
|
509
142
|
|
|
510
|
-
|
|
511
|
-
- `reldens.
|
|
512
|
-
- `reldens.formsTransformer.afterRender` - After form rendering
|
|
513
|
-
- `reldens.dynamicForm.beforeValidation` - Before validation
|
|
514
|
-
- `reldens.dynamicForm.afterValidation` - After validation
|
|
515
|
-
- `reldens.dynamicForm.beforeSave` - Before saving
|
|
516
|
-
- `reldens.dynamicForm.afterSave` - After successful save
|
|
517
|
-
- `reldens.dynamicFormRequestHandler.beforeSave` - Before request save
|
|
518
|
-
|
|
519
|
-
### Admin Events
|
|
520
|
-
- `reldens.setupAdminRouter` - Setup admin routes
|
|
521
|
-
- `reldens.setupAdminRoutes` - After route setup
|
|
522
|
-
- `reldens.setupAdminManagers` - After manager setup
|
|
523
|
-
- `reldens.adminBeforeEntitySave` - Before entity save (used by password encryption handler)
|
|
143
|
+
**Admin Events:**
|
|
144
|
+
- `reldens.adminBeforeEntitySave` - Before entity save
|
|
524
145
|
- `reldens.adminAfterEntitySave` - After entity save
|
|
525
|
-
- `reldens.adminViewPropertiesPopulation` - Add content to view pages
|
|
526
|
-
- `reldens.adminEditPropertiesPopulation` - Add content to edit pages
|
|
527
|
-
- `reldens.adminListPropertiesPopulation` - Add content to list pages
|
|
528
|
-
|
|
529
|
-
### Template Reloading Events
|
|
530
|
-
- `reldens.templateReloader.templatesChanged` - Templates changed
|
|
531
|
-
|
|
532
|
-
See `.claude/advanced-usage-guide.md` for comprehensive event-driven customization patterns and examples.
|
|
533
|
-
|
|
534
|
-
## Development Workflow
|
|
535
146
|
|
|
536
|
-
|
|
537
|
-
Set `reloadTime: -1` in Manager configuration for development:
|
|
538
|
-
- Admin templates reload automatically when files change
|
|
539
|
-
- Frontend templates reload on next page load
|
|
540
|
-
- No server restart needed
|
|
541
|
-
- Zero performance impact in production (`reloadTime: 0`)
|
|
147
|
+
See `.claude/advanced-usage-guide.md` for comprehensive event-driven customization patterns.
|
|
542
148
|
|
|
543
|
-
### Entity
|
|
544
|
-
```bash
|
|
545
|
-
# Generate entities from database schema
|
|
546
|
-
npx reldens-cms-generate-entities
|
|
547
|
-
|
|
548
|
-
# Or programmatically
|
|
549
|
-
await dataServer.generateEntities();
|
|
550
|
-
```
|
|
149
|
+
### Entity Config Overrides
|
|
551
150
|
|
|
552
|
-
|
|
553
|
-
Define custom entity configurations in `entitiesConfig`:
|
|
554
|
-
```javascript
|
|
555
|
-
{
|
|
556
|
-
articles: {
|
|
557
|
-
listProperties: ['title', 'status', 'created_at'],
|
|
558
|
-
showProperties: ['title', 'content', 'author'],
|
|
559
|
-
editProperties: ['title', 'content', 'author_id'],
|
|
560
|
-
filterProperties: ['status', 'author_id'],
|
|
561
|
-
titleProperty: 'title',
|
|
562
|
-
parentItemLabel: 'Content',
|
|
563
|
-
properties: {
|
|
564
|
-
title: { type: 'string', isRequired: true },
|
|
565
|
-
content: { type: 'text' },
|
|
566
|
-
author_id: { type: 'reference', reference: 'users' },
|
|
567
|
-
featured_image: {
|
|
568
|
-
type: 'string',
|
|
569
|
-
isUpload: true,
|
|
570
|
-
allowedTypes: 'image',
|
|
571
|
-
bucket: 'uploads'
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
```
|
|
151
|
+
Override generated entity configurations without editing generated files:
|
|
577
152
|
|
|
578
|
-
### Entity Config Overrides
|
|
579
|
-
Override generated entity configurations without editing generated files using `entitiesConfigOverride`:
|
|
580
153
|
```javascript
|
|
581
154
|
class CmsPagesOverride
|
|
582
155
|
{
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* @param {Object} baseConfig
|
|
586
|
-
* @param {Object} props
|
|
587
|
-
* @returns {Object}
|
|
588
|
-
*/
|
|
589
156
|
static propertiesConfig(baseConfig, props)
|
|
590
157
|
{
|
|
591
158
|
baseConfig.properties.meta_og_image = {
|
|
@@ -597,61 +164,19 @@ class CmsPagesOverride
|
|
|
597
164
|
};
|
|
598
165
|
return baseConfig;
|
|
599
166
|
}
|
|
600
|
-
|
|
601
167
|
}
|
|
602
168
|
|
|
603
169
|
const manager = new Manager({
|
|
604
170
|
entitiesConfigOverride: {
|
|
605
|
-
'cmsPages': CmsPagesOverride
|
|
171
|
+
'cmsPages': CmsPagesOverride
|
|
606
172
|
}
|
|
607
173
|
});
|
|
608
174
|
```
|
|
609
175
|
|
|
610
|
-
**CRITICAL
|
|
611
|
-
- Use camelCase: `'cmsPages'`, `'cmsBlocks'`, `'cmsForms'`
|
|
612
|
-
- NOT kebab-case: `'cms-pages'`, `'cms-blocks'`, `'cms-forms'`
|
|
613
|
-
|
|
614
|
-
Supports three override patterns:
|
|
615
|
-
- **Class-based**: Class with static `propertiesConfig(baseConfig, props)` method
|
|
616
|
-
- **Function-based**: Function that receives `(baseConfig, props)` and returns modified config
|
|
617
|
-
- **Object-based**: Plain object that gets deep merged with base config
|
|
618
|
-
|
|
619
|
-
**Upload Field Configuration:**
|
|
620
|
-
- `allowedTypes`: Must be a STRING ('image', 'audio', 'text'), NOT an array
|
|
621
|
-
- `bucket`: Relative path from projectRoot (e.g., 'public/assets/media')
|
|
622
|
-
- `bucketPath`: URL path for display (e.g., '/assets/media/')
|
|
623
|
-
- Do NOT use spread syntax - replace entire property object
|
|
624
|
-
- Do NOT use FileHandler.joinPaths() - bucket paths are relative to projectRoot
|
|
625
|
-
|
|
626
|
-
**Upload Field Removal:**
|
|
627
|
-
- Admin edit pages automatically show an "X" button before uploaded filenames
|
|
628
|
-
- Clicking X creates hidden input `clear_fieldname=1` in form
|
|
629
|
-
- Server detects this and sets field to null in database
|
|
630
|
-
- File remains on disk - only database field is cleared
|
|
631
|
-
- Template: `admin/templates/fields/edit/file-claude.html`
|
|
632
|
-
- Client JS: `admin/reldens-admin-client-claude.js` (remove upload functionality)
|
|
633
|
-
- Server handling: `lib/admin-manager/router-contents-claude.js` (clear_ parameter detection)
|
|
634
|
-
|
|
635
|
-
**Example subscribers**: See `lib/cache/add-cache-button-subscriber.js` and `lib/cache/save-and-clear-cache-subscriber.js` for complete working examples of event-driven UI customizations.
|
|
176
|
+
**CRITICAL:** Entity keys must match exactly as defined in `generated-entities/entities-config.js` (use camelCase: `'cmsPages'`, NOT kebab-case: `'cms-pages'`).
|
|
636
177
|
|
|
637
178
|
See `.claude/advanced-usage-guide.md` for detailed examples.
|
|
638
179
|
|
|
639
|
-
## Security Features
|
|
640
|
-
|
|
641
|
-
- **Authentication** - Role-based admin access
|
|
642
|
-
- **Password Encryption** - PBKDF2 with 100k iterations, SHA-512
|
|
643
|
-
- **Automatic Password Encryption** - Event-driven encryption on save (enabled by default)
|
|
644
|
-
- **CSRF Protection** - Via session tokens
|
|
645
|
-
- **File Upload Validation** - MIME type and extension checking
|
|
646
|
-
- **Entity Access Control** - Public/private entity rules
|
|
647
|
-
- **Honeypot Protection** - Bot detection in forms
|
|
648
|
-
- **Rate Limiting** - Via @reldens/server-utils
|
|
649
|
-
- **XSS Protection** - Input sanitization via @reldens/server-utils
|
|
650
|
-
- **SQL Injection Prevention** - Via Prisma ORM
|
|
651
|
-
- **Path Validation** - File path security
|
|
652
|
-
- **CSP Headers** - Content Security Policy via Helmet
|
|
653
|
-
- **HTTPS Support** - SSL/TLS configuration
|
|
654
|
-
|
|
655
180
|
## Important Implementation Notes
|
|
656
181
|
|
|
657
182
|
1. **Always use specialized tools over bash** for file operations (Read, Edit, Write)
|
|
@@ -666,6 +191,10 @@ See `.claude/advanced-usage-guide.md` for detailed examples.
|
|
|
666
191
|
10. **Multi-domain requires proper configuration** - set up domain mapping correctly
|
|
667
192
|
11. **Password encryption is automatic** - enabled by default for users entity
|
|
668
193
|
12. **Never store plain text passwords** - always use Encryptor.encryptPassword()
|
|
194
|
+
13. **Template extensions are consistent** - Manager, Frontend, TemplateResolver, and TemplateCache all use the same default extensions: `['.html', '.mustache', '.template', '.txt', '.xml', '.json']`
|
|
195
|
+
14. **Template names omit extensions** - Database template/layout fields should never include file extensions; the resolver automatically tries all configured extensions
|
|
196
|
+
15. **Sitemap generation is event-driven** - SitemapLoader listens to `reldens.afterVariablesCreated` and populates `sitemapPages` variable; data is cached on `req.sitemapPages` to avoid duplicate queries during multi-pass template rendering
|
|
197
|
+
16. **buildEnhancedRenderData merges all system variables** - Any custom variables added to `eventData.variables` in event listeners will automatically be available in templates via Mustache
|
|
669
198
|
|
|
670
199
|
## Common File Paths
|
|
671
200
|
|
|
@@ -681,27 +210,35 @@ See `.claude/advanced-usage-guide.md` for detailed examples.
|
|
|
681
210
|
|
|
682
211
|
## Troubleshooting
|
|
683
212
|
|
|
684
|
-
### Installation
|
|
213
|
+
### Installation
|
|
214
|
+
|
|
685
215
|
- Check database connection in `.env`
|
|
686
216
|
- Ensure Prisma schema is valid
|
|
687
217
|
- Verify Node.js version >= 20.0.0
|
|
688
218
|
|
|
689
|
-
###
|
|
690
|
-
|
|
219
|
+
### Templates
|
|
220
|
+
|
|
221
|
+
- Check logs for "Template not found" or "Template file not found" messages
|
|
222
|
+
- Verify template files exist in correct locations (domain → default → base)
|
|
223
|
+
- Ensure template names in database do NOT include file extensions
|
|
224
|
+
- Check `templateExtensions` configuration includes required extensions
|
|
691
225
|
- Verify domain mapping configuration
|
|
692
|
-
- Enable template reloading for development
|
|
226
|
+
- Enable template reloading for development (`reloadTime: -1`)
|
|
227
|
+
|
|
228
|
+
### Forms
|
|
693
229
|
|
|
694
|
-
### Form Issues
|
|
695
230
|
- Validate JSON schema syntax
|
|
696
231
|
- Check form key matches database
|
|
697
232
|
- Verify field names in schema
|
|
698
233
|
|
|
699
|
-
###
|
|
234
|
+
### Entities
|
|
235
|
+
|
|
700
236
|
- Regenerate entities after schema changes
|
|
701
237
|
- Check entity access configuration
|
|
702
238
|
- Verify relationship mappings
|
|
703
239
|
|
|
704
|
-
###
|
|
240
|
+
### Passwords
|
|
241
|
+
|
|
705
242
|
- Verify password is encrypted (contains `:` and is 192 chars)
|
|
706
243
|
- Check `enablePasswordEncryption` is `true` in Manager config
|
|
707
244
|
- Use CLI command for password updates: `npx reldens-cms-update-password`
|
|
@@ -717,6 +254,22 @@ See `.claude/advanced-usage-guide.md` for detailed examples.
|
|
|
717
254
|
|
|
718
255
|
## Additional Resources
|
|
719
256
|
|
|
257
|
+
**Comprehensive Guides:**
|
|
258
|
+
- `.claude/installation-guide.md` - Installation and setup
|
|
259
|
+
- `.claude/architecture-guide.md` - Detailed architecture documentation
|
|
260
|
+
- `.claude/configuration-guide.md` - Configuration options and examples
|
|
261
|
+
- `.claude/database-schema.md` - Database tables and schema
|
|
262
|
+
- `.claude/templating-system-guide.md` - Template system and functions
|
|
263
|
+
- `.claude/forms-system-guide.md` - Dynamic forms system
|
|
264
|
+
- `.claude/search-guide.md` - Search functionality
|
|
265
|
+
- `.claude/multi-domain-i18n-guide.md` - Multi-domain and internationalization
|
|
266
|
+
- `.claude/password-management-guide.md` - Password management
|
|
267
|
+
- `.claude/seo-guide.md` - SEO, sitemaps, and robots.txt
|
|
268
|
+
- `.claude/security-guide.md` - Security features and best practices
|
|
269
|
+
- `.claude/advanced-usage-guide.md` - Advanced customization and event patterns
|
|
270
|
+
- `.claude/api-reference.md` - API reference documentation
|
|
271
|
+
|
|
272
|
+
**Other Resources:**
|
|
720
273
|
- Main README.md for user documentation
|
|
721
274
|
- Package.json for dependency versions
|
|
722
275
|
- License: MIT
|