Open-source static portal and lightweight Node.js API for a GCWeb/Canada.ca-style government website.
This is a clean sample/open-source edition. It does not include live deployment secrets, real accounts, service requests, votes, audit logs, sessions, or production databases.
- English and German public site
- Canada.ca/GCWeb-inspired layout
- Public services and records pages
- Public account sign-in flow
- Dashboard UI
- Content editing
- Public record request workflow
- Service request workflow
- Emergency Alert System
- Official Campaigns / Public Notices
- Election ballot / voting system
- Status dashboard
- Backups and audit views
- Caddy reverse proxy example
- SQLite or JSON fallback runtime storage
- Dashboard support-beam self-repair from bundled example data
public/ Static website and dashboard UI
server/ Node.js API server
scripts/ Generic install, upgrade and repair scripts
examples/ Example configs and sample data
docs/ Open-source/deployment notes
Caddyfile.example Example Caddy config
.env.example Example environment file
LICENSE MIT license
npm install
node server/index.jsThen serve public/ with your web server.
For Caddy:
cp Caddyfile.example CaddyfileIf Easy Mode, Advanced JSON, Translation Checker, campaigns, alerts, elections, or news are empty:
./scripts/repair-dashboard-content.sh
./scripts/check-public-content-counts.shThe repair fills missing public sample arrays from:
public/assets/data/site-data.bundled-example.json
It does not touch runtime DB files.
PORT=8787
DB_MODE=sqlite
DATA_DIR=./data
DATA_FILE=./public/assets/data/site-data.json
DB_FILE=./data/separated-kingdom.sqlite
BUNDLED_CONTENT_FILE=./public/assets/data/site-data.bundled-example.json
Do not commit:
data/
*.sqlite
.env
Caddyfile
backup-*/
real site-data.json containing private records
account/session/vote/request/audit data
See docs/OPEN_SOURCE_NOTES.md.
Code is released under the MIT License.
Bundled SVG assets and external image references may have separate licensing considerations. See docs/IMAGE_CREDITS.md.
Fixed:
- Dashboard pages were loading only
site.jsand the wrongpublic-records.js. - Dashboard pages now load their correct page-specific JavaScript:
dashboard-advanced.jsdashboard-easy.jsdashboard-translation-check.jsdashboard-security.jsdashboard-campaigns.jsdashboard-alerts.jsdashboard-elections.js- plus accounts, requests, audit, backups and status scripts.
Verify:
./scripts/verify-dashboard-scripts.sh
./scripts/check-public-content-counts.shFixed:
- Easy Mode editor form labels and legends were cramped/colliding.
- EN/DE bilingual editor columns now have cleaner spacing.
- Inputs and textareas use better readable sizing.
- Long titles/descriptions no longer visually break the form.
- CSS/JS cache-busted to oss4.
This is a visual/form styling fix only.
Changed:
- Removed traditional browser Basic Auth prompt from dashboard/API routing.
- Added web login pages:
/dashboard/login//dashboard/de/login/
- Added app cookie auth endpoints:
POST /admin-auth/loginGET /admin-auth/meGET /admin-auth/checkPOST /admin-auth/logout
- Dashboard/API routes are protected by Caddy
forward_authplus server-side/api/*auth checks. - Admin/editor/viewer accounts created in the dashboard account database can now sign in to the dashboard.
- A bootstrap
adminaccount is created only when no dashboard admin/editor/viewer account exists. - The bootstrap password is generated and stored on the server at:
data/admin-initial-password.txt
- Delete the bootstrap password file after saving the password securely.
Verify:
./scripts/verify-dashboard-auth.sh
./scripts/verify-dashboard-scripts.sh
./scripts/verify-dashboard-style.shAdded:
- Login rate limiting by IP and username.
- Account lockout after repeated failed dashboard login attempts.
- CSRF token enforcement for admin/API mutating requests.
- Server-side dashboard session expiry.
- Role permissions:
- admin: full access
- editor: content/workflow changes only
- viewer: read-only dashboard access
- Forced password change for bootstrap and newly created dashboard accounts.
- Password change/security settings page:
/dashboard/change-password//dashboard/de/change-password/
- Optional TOTP two-factor authentication.
- Safer content saving via server-side string sanitization.
- Node API binds to
127.0.0.1by default throughHOST. - CORS allowlist now includes
X-CSRF-Tokenfor same-origin admin requests. - Sensitive MFA secret is not returned by normal user/account APIs.
Verify:
./scripts/verify-dashboard-auth.sh
./scripts/verify-security-hardening.sh
./scripts/verify-dashboard-scripts.sh
./scripts/verify-dashboard-style.shAdded:
- Persistent dashboard quick navigation bar on all dashboard pages.
- Back button.
- Dashboard home shortcut.
- Quick links to Easy Mode, Advanced JSON, Accounts, Requests, Campaigns, Alerts, Elections and Security.
- Public site shortcut.
- English and German labels.
- Mobile-friendly wrapping.
Verify:
./scripts/verify-dashboard-nav.shAdded:
./scripts/reset-admin-password.sh./scripts/verify-admin-reset.sh
Why:
data/admin-initial-password.txtis only generated when the server creates a bootstrap admin.- If a dashboard admin/editor/viewer account already exists, the bootstrap password file is not generated.
- This script creates or resets the
adminaccount and writes a recovery password file.
Use:
./scripts/reset-admin-password.shThe reset admin is forced to change password after login.
Removed:
- Visible “First-time setup” box from
/dashboard/login/. - Visible “Ersteinrichtung” box from
/dashboard/de/login/.
Admin recovery now belongs in the server-side script:
./scripts/reset-admin-password.shVerify:
./scripts/verify-login-clean.shImproved:
- Modern two-column login layout.
- Large secure administration portal hero panel.
- Cleaner sign-in card.
- Better spacing, labels, focus rings and mobile layout.
- Security trust chips.
- No visible setup/recovery notes on the login page.
Verify:
./scripts/verify-login-style.shChanged:
- Replaced the modern/SaaS-style dashboard login with a GCWeb-style layout.
- Uses standard container, rows, form groups, well and panel elements.
- Removed the large custom hero panel.
- Kept dashboard web-login, MFA field, CSRF/session security and admin reset support.
Verify:
./scripts/verify-login-gcweb.shFixed:
- Added public Request centre:
/en/requests//de/requests/
- Added public request status lookup:
/en/request-status//de/request-status/
- Added
/account-api/request-statusendpoint. - Record requests now clearly separate public records and private/case records.
- Record request form includes a record tag/case number/file number field.
- Request forms now show a clear success message with reference number and status-check button.
- Services page now points users to the request centre instead of confusing category hunting.
- Dashboard requests page now shows details, record tags and decision notes that users can see on status lookup.
Verify:
./scripts/verify-request-workflow.shFixed:
- Re-added the GCWeb-style menu block to public pages that were created/rewritten without it.
- Added Request centre and Request status to the public menu.
- Added
./scripts/verify-public-menu.sh.
Verify:
./scripts/verify-public-menu.shPatched public pages missing menu block:
/de/records/index.html
/de/services/index.html
/de/requests/index.html
/de/request-status/index.html
/de/services/transit-access-permit/index.html
/de/services/report-infrastructure-issue/index.html
/de/records/request/index.html
/en/records/index.html
/en/services/index.html
/en/requests/index.html
/en/request-status/index.html
/en/services/transit-access-permit/index.html
/en/services/report-infrastructure-issue/index.html
/en/records/request/index.html
Fixed:
- Most requested strip was too visually loud and looked broken.
- Homepage visited links no longer turn overpowering purple in the quick-link/topic sections.
- Services and information grid has tighter spacing and more GCWeb-like link colour.
- Corrected confusing German copy introduced by earlier replacement.
Verify:
./scripts/verify-homepage-cleanup.shFixed:
- German homepage now gets a stronger visited-link colour override.
- German most-requested strip has tighter German-specific spacing.
- Removed remaining broken German wording from earlier replacements.
- Cache-busted CSS/JS to oss15.
Verify:
./scripts/verify-de-homepage-cleanup.shFixed:
- German homepage Services and information section no longer uses Bootstrap float wrapping.
- Topic cards now use a real responsive CSS grid.
- This removes the large vertical gap caused by long German headings wrapping to two lines.
Verify:
./scripts/verify-homepage-topic-grid.shFixed:
- Bootstrap
.row::beforeand.row::afterclearfix pseudo-elements were being treated as invisible CSS-grid items. - That pushed the first real topic card into column 2 and made the German and English homepages look broken.
- The homepage topics grid now disables those pseudo-elements inside
.sk-ca-topicsonly.
Verify:
./scripts/verify-homepage-clearfix-grid.sh
./scripts/verify-homepage-topic-grid.shAdded:
- Dashboard Records Registry:
/dashboard/records-registry//dashboard/de/records-registry/
- Create public, private and restricted records.
- Auto case-number generation:
PUB-YYYY-XXXXXXfor public recordsPRV-YYYY-XXXXXXfor private/case recordsRST-YYYY-XXXXXXfor restricted records
- Published public registry records automatically appear on
/records/. - Private/restricted records stay hidden from
/records/. - Public status lookup now supports request reference numbers and registry case numbers.
- Dashboard quick navigation includes Records Registry.
Verify:
./scripts/verify-records-registry.sh