Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
df2349b
Bump version to v0.9.7 BETA
ddrayko Jun 20, 2026
3499996
Replace Cloudflare Turnstile with self-hosted Cap CAPTCHA
ddrayko Jun 20, 2026
65d8b49
Update CSP: replace Cloudflare Turnstile URLs with Cap CAPTCHA URLs
ddrayko Jun 20, 2026
c2dedbd
Fix CSP: allow cdn.jsdelivr.net WASM loads and blob: workers for Cap
ddrayko Jun 20, 2026
8f45845
Apply home site DA (orange/brown theme) to dashboard
ddrayko Jun 22, 2026
610d079
Fix font: use variable font with italics and body, body * rule to mat…
ddrayko Jun 22, 2026
382ea51
Apply hero background (pure black + orange grid + noise) to dashboard…
ddrayko Jun 22, 2026
c3f232c
Improve egg category/option visual distinction in create server dropdown
ddrayko Jun 22, 2026
4670462
Fix /api/servers/eggs 500: resilient nest fetching + frontend error f…
ddrayko Jun 22, 2026
7f75843
Add padding between resources card and cap-widget, make cap-widget fu…
ddrayko Jun 22, 2026
735e45b
Force cap-widget full width with wrapping div and !important
ddrayko Jun 22, 2026
92cfb7b
Set cap-widget to dark theme with ZeroHost orange DA colors
ddrayko Jun 22, 2026
f2f417a
Fix cap-widget width: override --cap-widget-width default 230px to 100%
ddrayko Jun 22, 2026
fc4489d
Add nest 7 (Database) to egg list
ddrayko Jun 22, 2026
edf3da7
Replace native RGPD checkbox with custom styled button
ddrayko Jun 22, 2026
58598bd
Move CAPTCHA into centered modal with blur overlay on login/register
ddrayko Jun 22, 2026
927063f
Fix cap-widget not rendering in modal: set explicit width, use create…
ddrayko Jun 22, 2026
c24b0c3
Replace Pterodactyl with Pyrodactyl in sidebar labels
ddrayko Jun 22, 2026
782b779
Add server power state detection, resource bars, activity logging, se…
ddrayko Jun 22, 2026
f9b6aa8
Replace Pterodactyl API key form with account linking notice on /acco…
ddrayko Jun 22, 2026
63b4c02
Translate remaining French text to English in account linking notice
ddrayko Jun 22, 2026
9929878
Add Pterodactyl API key form to /account/edit page
ddrayko Jun 22, 2026
bd485f1
Match API key input style with other forms on /account/edit
ddrayko Jun 22, 2026
2ed7f89
Fix html() falsy-0 bug causing resource bars to show full and labels …
ddrayko Jun 22, 2026
c4dd152
Replace resource bar SVGs with clearer RAM chip and CPU processor icons
ddrayko Jun 22, 2026
b96fc06
Remove Resources column from servers table
ddrayko Jun 22, 2026
16b5348
Change Configure API Key link from account/links to account/edit
ddrayko Jun 22, 2026
c5f642f
Remove max-width constraint on Lifetime card to match Server Info width
ddrayko Jun 22, 2026
988490c
Remove resource bars from Recent Servers cards on overview
ddrayko Jun 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ PTERO_API_KEY=change_me
# Encryption key for sensitive data — Generate with: openssl rand -hex 32
ENCRYPTION_KEY=change_me_to_a_random_hex_string

# Cloudflare Turnstile
TURNSTILE_SECRET=change_me
# Cap CAPTCHA (self-hosted alternative to Turnstile)
CAP_ENDPOINT=https://cap.zero-host.org/f6c8171b08/
CAP_SECRET=change_me

# Session & Cookie
COOKIE_SECRET=change_me_to_a_random_string
Expand Down
35 changes: 35 additions & 0 deletions config/cap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const CAP_SECRET = process.env.CAP_SECRET;
const CAP_ENDPOINT = process.env.CAP_ENDPOINT;

if (!CAP_SECRET) {
console.error('Missing CAP_SECRET environment variable');
}

if (!CAP_ENDPOINT) {
console.error('Missing CAP_ENDPOINT environment variable');
}

async function fetchWithTimeout(url, options = {}, timeout = 10000) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeout);
try {
return await fetch(url, { ...options, signal: controller.signal });
} finally {
clearTimeout(timer);
}
}

export async function verifyCap(token) {
if (!token) return false;
try {
const res = await fetchWithTimeout(`${CAP_ENDPOINT}siteverify`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ secret: CAP_SECRET, response: token }),
});
const data = await res.json();
return data.success === true;
} catch {
return false;
}
}
14 changes: 13 additions & 1 deletion config/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const tables = {
{ name: 'first_name', def: 'VARCHAR(255)' },
{ name: 'last_name', def: 'VARCHAR(255)' },
{ name: 'password_set', def: 'TINYINT(1) NOT NULL DEFAULT 0' },
{ name: 'ptero_client_api_key', def: 'VARCHAR(255) DEFAULT NULL' },
{ name: 'created_at', def: 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP' },
],
},
Expand All @@ -33,6 +34,16 @@ const tables = {
{ name: 'created_at', def: 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP' },
],
},
activity_log: {
columns: [
{ name: 'id', def: 'INT AUTO_INCREMENT PRIMARY KEY' },
{ name: 'user_id', def: 'INT NOT NULL' },
{ name: 'action', def: 'VARCHAR(50) NOT NULL' },
{ name: 'details', def: 'VARCHAR(255) DEFAULT \'\'' },
{ name: 'server_id', def: 'INT DEFAULT NULL' },
{ name: 'created_at', def: 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP' },
],
},

};

Expand All @@ -51,7 +62,8 @@ const constraints = [
{ table: 'user_ips', sql: 'ALTER TABLE user_ips ADD INDEX idx_ip (ip_address)', name: 'idx_ip' },
{ table: 'user_ips', sql: 'ALTER TABLE user_ips ADD INDEX idx_user (user_id)', name: 'idx_user' },
{ table: 'user_ips', sql: 'ALTER TABLE user_ips ADD CONSTRAINT fk_user_ips_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE', name: 'fk_user_ips_user' },

{ table: 'activity_log', sql: 'ALTER TABLE activity_log ADD INDEX idx_activity_user (user_id)', name: 'idx_activity_user' },
{ table: 'activity_log', sql: 'ALTER TABLE activity_log ADD INDEX idx_activity_created (created_at)', name: 'idx_activity_created' },
];

export async function migrate() {
Expand Down
30 changes: 0 additions & 30 deletions config/turnstile.js

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zerohost-dashboard",
"version": "1.0.0",
"version": "0.9.7",
"private": true,
"type": "module",
"scripts": {
Expand Down
Loading