Compare commits
4
Commits
v0.6.2
..
ba9e00d65b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba9e00d65b | ||
|
|
aa9998cbd8 | ||
|
|
f9352617b0 | ||
|
|
17b0becc82 |
@@ -6,6 +6,34 @@ Pre-1.0 versions treat MINOR as feature releases and PATCH as bug fixes.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [0.6.6] — 2026-04-12
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **`seed.ts` skips admin on re-run** — `findUnique` + `create` meant re-running the seed after a failed install left the admin password in `.env` out of sync with the hashed password in the database. Changed to `upsert` so the seed always writes the current `.env` password, making re-runs safe.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.6.5] — 2026-04-12
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **`install.sh` regenerates secrets on re-run** — `JWT_SECRET`, `JWT_REFRESH_SECRET`, and `MARIADB_ROOT_PASS` were always generated fresh, so re-running the installer after a failed build overwrote `.env` with secrets that no longer matched the already-configured MariaDB password. The installer now reads existing values from `.env` (if present) and only generates new secrets when none exist.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.6.4] — 2026-04-12
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **`SectionCard.tsx` TypeScript build error** — `icon` prop typed as `ComponentType<{ size?: number }>` but Lucide icons declare `size?: string | number`. Widened the prop type to `size?: number | string` to match Lucide's `LucideProps`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.6.3] — 2026-04-12
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **`install.sh` aborts immediately when piped via `curl | bash`** — Interactive confirmation prompt (`read`) received EOF from the pipe and exited non-zero, causing `set -euo pipefail` to kill the script before installation began. Replaced the prompt entirely with a 5-second countdown (`sleep 5`) so the installer works correctly whether piped or run from a file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.6.2] — 2026-04-12
|
## [0.6.2] — 2026-04-12
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ interface SectionCardProps {
|
|||||||
label: string
|
label: string
|
||||||
description?: string
|
description?: string
|
||||||
to: string
|
to: string
|
||||||
icon?: ComponentType<{ size?: number; className?: string }>
|
icon?: ComponentType<{ size?: number | string; className?: string }>
|
||||||
comingSoon?: boolean
|
comingSoon?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nixpanel-server",
|
"name": "nixpanel-server",
|
||||||
"version": "0.6.2",
|
"version": "0.6.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"server",
|
"server",
|
||||||
|
|||||||
+16
-7
@@ -82,11 +82,21 @@ if [[ -z "$ADMIN_EMAIL" ]]; then
|
|||||||
ADMIN_EMAIL="admin@$(hostname -f 2>/dev/null || echo localhost)"
|
ADMIN_EMAIL="admin@$(hostname -f 2>/dev/null || echo localhost)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Redirect all interactive reads to /dev/tty so curl | bash works correctly
|
# ── Preserve secrets across re-runs ──────────────────────────────────────────
|
||||||
|
# If .env already exists, reuse the same secrets so a failed-and-retried
|
||||||
|
# install doesn't leave MariaDB with a password that doesn't match .env.
|
||||||
|
_EXISTING_ENV="${INSTALL_DIR}/server/.env"
|
||||||
|
if [[ -f "$_EXISTING_ENV" ]]; then
|
||||||
|
_read_env() { grep -m1 "^$1=" "$_EXISTING_ENV" 2>/dev/null | cut -d= -f2- | tr -d '"'; }
|
||||||
|
MARIADB_ROOT_PASS=$(_read_env MARIADB_PASSWORD)
|
||||||
|
JWT_SECRET=$(_read_env JWT_SECRET)
|
||||||
|
JWT_REFRESH_SECRET=$(_read_env JWT_REFRESH_SECRET)
|
||||||
|
fi
|
||||||
|
|
||||||
MARIADB_ROOT_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)
|
# Fill in any values that weren't in the existing .env (or first install)
|
||||||
JWT_SECRET=$(gen_secret)
|
MARIADB_ROOT_PASS=${MARIADB_ROOT_PASS:-$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 24)}
|
||||||
JWT_REFRESH_SECRET=$(gen_secret)
|
JWT_SECRET=${JWT_SECRET:-$(gen_secret)}
|
||||||
|
JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-$(gen_secret)}
|
||||||
|
|
||||||
# ── Confirm ───────────────────────────────────────────────────────────────────
|
# ── Confirm ───────────────────────────────────────────────────────────────────
|
||||||
echo -e "${BOLD}Installation summary:${RESET}"
|
echo -e "${BOLD}Installation summary:${RESET}"
|
||||||
@@ -95,9 +105,8 @@ echo " Admin username : $ADMIN_USER"
|
|||||||
echo " Admin email : $ADMIN_EMAIL"
|
echo " Admin email : $ADMIN_EMAIL"
|
||||||
echo " Admin password : $([ "$GENERATED_PASS" = "true" ] && echo "<auto-generated>" || echo "$ADMIN_PASS")"
|
echo " Admin password : $([ "$GENERATED_PASS" = "true" ] && echo "<auto-generated>" || echo "$ADMIN_PASS")"
|
||||||
echo ""
|
echo ""
|
||||||
read -r -p "Continue? [Y/n] " CONFIRM < /dev/tty || CONFIRM="Y"
|
echo " Starting in 5 seconds — press Ctrl+C to abort."
|
||||||
CONFIRM="${CONFIRM:-Y}"
|
sleep 5
|
||||||
[[ "$CONFIRM" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }
|
|
||||||
|
|
||||||
# ── Logging ───────────────────────────────────────────────────────────────────
|
# ── Logging ───────────────────────────────────────────────────────────────────
|
||||||
mkdir -p /var/log/nixpanel
|
mkdir -p /var/log/nixpanel
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ export async function buildApp() {
|
|||||||
|
|
||||||
fastify.get('/api/health', async () => ({
|
fastify.get('/api/health', async () => ({
|
||||||
status: 'ok',
|
status: 'ok',
|
||||||
version: '0.6.2',
|
version: '0.6.6',
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
+6
-11
@@ -7,19 +7,14 @@ const prisma = new PrismaClient()
|
|||||||
async function main() {
|
async function main() {
|
||||||
console.log('Seeding database...')
|
console.log('Seeding database...')
|
||||||
|
|
||||||
// Admin user
|
// Admin user — upsert so re-runs always sync the password from .env
|
||||||
const existing = await prisma.adminUser.findUnique({ where: { username: config.admin.username } })
|
|
||||||
if (!existing) {
|
|
||||||
const hash = await bcrypt.hash(config.admin.password, 12)
|
const hash = await bcrypt.hash(config.admin.password, 12)
|
||||||
await prisma.adminUser.create({
|
await prisma.adminUser.upsert({
|
||||||
data: {
|
where: { username: config.admin.username },
|
||||||
username: config.admin.username,
|
update: { passwordHash: hash, email: config.admin.email },
|
||||||
passwordHash: hash,
|
create: { username: config.admin.username, passwordHash: hash, email: config.admin.email },
|
||||||
email: config.admin.email,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
console.log(`Created admin user: ${config.admin.username}`)
|
console.log(`Admin user ready: ${config.admin.username}`)
|
||||||
}
|
|
||||||
|
|
||||||
// Default packages
|
// Default packages
|
||||||
const packages = [
|
const packages = [
|
||||||
|
|||||||
Reference in New Issue
Block a user