Fix Photography deploy metadata and SQLite migration
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 33s
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 33s
This commit is contained in:
@@ -7,6 +7,57 @@ const db = new sqlite3.Database(dbPath);
|
||||
|
||||
console.log('Using database at', dbPath);
|
||||
|
||||
function bootstrapInitialAdmin() {
|
||||
const username = process.env.INITIAL_ADMIN_USERNAME;
|
||||
const password = process.env.INITIAL_ADMIN_PASSWORD;
|
||||
const passwordHash = process.env.INITIAL_ADMIN_PASSWORD_HASH || (password ? bcrypt.hashSync(password, 10) : null);
|
||||
|
||||
if (!username && !passwordHash) {
|
||||
return;
|
||||
}
|
||||
if (!username || !passwordHash) {
|
||||
console.warn('Set INITIAL_ADMIN_USERNAME together with INITIAL_ADMIN_PASSWORD_HASH to bootstrap an admin.');
|
||||
return;
|
||||
}
|
||||
|
||||
db.get('SELECT id FROM users WHERE username = ?', [username], (err, row) => {
|
||||
if (err || row) return;
|
||||
|
||||
db.run(
|
||||
'INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)',
|
||||
[username, passwordHash, 'admin'],
|
||||
(insertErr) => {
|
||||
if (insertErr) {
|
||||
console.error('Failed to create initial admin:', insertErr.message);
|
||||
return;
|
||||
}
|
||||
console.log(`Initial admin created: ${username}`);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
db.get('SELECT id, role FROM users WHERE username = ?', [username], (err, row) => {
|
||||
if (err || !row || row.role === 'admin') return;
|
||||
|
||||
db.run('UPDATE users SET role = ? WHERE id = ?', ['admin', row.id], (updateErr) => {
|
||||
if (updateErr) {
|
||||
console.error('Failed to promote initial admin:', updateErr.message);
|
||||
return;
|
||||
}
|
||||
console.log(`Initial admin promoted: ${username}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runMigrations(migrations, index = 0) {
|
||||
if (index >= migrations.length) {
|
||||
bootstrapInitialAdmin();
|
||||
return;
|
||||
}
|
||||
|
||||
migrations[index](() => runMigrations(migrations, index + 1));
|
||||
}
|
||||
|
||||
db.serialize(() => {
|
||||
// Users: mit created_at fuer Client-Ablauf (30 Tage)
|
||||
db.run(`CREATE TABLE IF NOT EXISTS users (
|
||||
@@ -17,17 +68,53 @@ db.serialize(() => {
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
|
||||
// Migration: Spalten hinzufuegen falls Tabelle schon existiert (alte DB ohne role/created_at)
|
||||
db.run(`ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'client'`, (err) => {
|
||||
// Ignoriere Fehler wenn Spalte schon existiert
|
||||
if (!err) {
|
||||
// Alte Admins (die einzigen User vor dem Update) als admin markieren
|
||||
db.run(`UPDATE users SET role = 'admin' WHERE id = 1`);
|
||||
console.log('Migration: role-Spalte hinzugefuegt, User ID 1 als admin gesetzt');
|
||||
// Migration: Spalten hinzufuegen falls Tabelle schon existiert (alte DB ohne role/created_at).
|
||||
// SQLite erlaubt CURRENT_TIMESTAMP nicht als DEFAULT bei ALTER TABLE, deshalb wird created_at
|
||||
// ohne Default angelegt und danach fuer bestehende Nutzer befuellt.
|
||||
db.all(`PRAGMA table_info(users)`, (err, columns) => {
|
||||
if (err) {
|
||||
console.error('User-Migration fehlgeschlagen:', err.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
db.run(`ALTER TABLE users ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP`, (err) => {
|
||||
// Ignoriere Fehler wenn Spalte schon existiert
|
||||
|
||||
const columnNames = new Set(columns.map((column) => column.name));
|
||||
|
||||
const migrations = [];
|
||||
|
||||
if (!columnNames.has('role')) {
|
||||
migrations.push((done) => db.run(`ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'client'`, (alterErr) => {
|
||||
if (alterErr) {
|
||||
console.error('Migration role fehlgeschlagen:', alterErr.message);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Alte Admins (die einzigen User vor dem Update) als admin markieren.
|
||||
db.run(`UPDATE users SET role = 'admin' WHERE id = 1`, () => {
|
||||
console.log('Migration: role-Spalte hinzugefuegt, User ID 1 als admin gesetzt');
|
||||
done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if (!columnNames.has('created_at')) {
|
||||
migrations.push((done) => db.run(`ALTER TABLE users ADD COLUMN created_at DATETIME`, (alterErr) => {
|
||||
if (alterErr) {
|
||||
console.error('Migration created_at fehlgeschlagen:', alterErr.message);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
db.run(`UPDATE users SET created_at = datetime('now') WHERE created_at IS NULL`, () => {
|
||||
console.log('Migration: created_at-Spalte hinzugefuegt');
|
||||
done();
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
migrations.push((done) => db.run(`UPDATE users SET created_at = datetime('now') WHERE created_at IS NULL`, done));
|
||||
}
|
||||
|
||||
runMigrations(migrations);
|
||||
});
|
||||
|
||||
// Ordner-Zuweisung (neu)
|
||||
@@ -46,45 +133,6 @@ db.serialize(() => {
|
||||
UNIQUE(user_id, image_name)
|
||||
)`);
|
||||
|
||||
// Initialen Admin nur mit expliziten Credentials aus der Umgebung anlegen.
|
||||
db.serialize(() => {
|
||||
const username = process.env.INITIAL_ADMIN_USERNAME;
|
||||
const password = process.env.INITIAL_ADMIN_PASSWORD;
|
||||
const passwordHash = process.env.INITIAL_ADMIN_PASSWORD_HASH || (password ? bcrypt.hashSync(password, 10) : null);
|
||||
if (!username || !passwordHash) {
|
||||
console.warn('Set INITIAL_ADMIN_USERNAME with INITIAL_ADMIN_PASSWORD or INITIAL_ADMIN_PASSWORD_HASH to bootstrap an admin.');
|
||||
return;
|
||||
}
|
||||
|
||||
db.get('SELECT id FROM users WHERE username = ?', [username], (err, row) => {
|
||||
if (err || row) return;
|
||||
|
||||
db.run(
|
||||
'INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)',
|
||||
[username, passwordHash, 'admin'],
|
||||
(insertErr) => {
|
||||
if (insertErr) {
|
||||
console.error('Failed to create initial admin:', insertErr.message);
|
||||
return;
|
||||
}
|
||||
console.log(`Initial admin created: ${username}`);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
db.get('SELECT id, role FROM users WHERE username = ?', [username], (err, row) => {
|
||||
if (err || !row || row.role === 'admin') return;
|
||||
|
||||
db.run('UPDATE users SET role = ? WHERE id = ?', ['admin', row.id], (updateErr) => {
|
||||
if (updateErr) {
|
||||
console.error('Failed to promote initial admin:', updateErr.message);
|
||||
return;
|
||||
}
|
||||
console.log(`Initial admin promoted: ${username}`);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = db;
|
||||
|
||||
Reference in New Issue
Block a user