release: v1.0.2
Add i18n (zh-CN/en), mobile navigation menus, stats and upload UI improvements, and Docker reset-password CLI for emergency recovery.
This commit is contained in:
1 parent
074e4502c2
commit
22cb2ca8bc
46 files changed
+3724
-587
No files matched your search
@@ -0,0 +1,56 @@
|
||||
import { mkdirSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { randomBytes, scryptSync } from 'node:crypto'
|
||||
import { DatabaseSync } from 'node:sqlite'
|
||||
|
||||
const usernameArg = process.argv[2]?.trim() || ''
|
||||
|
||||
if (process.argv.length > 3) {
|
||||
console.error('Usage: reset-password [username]')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const dataDir = process.env.DATA_DIR || join(process.cwd(), 'data')
|
||||
mkdirSync(dataDir, { recursive: true })
|
||||
const db = new DatabaseSync(join(dataDir, 'pichost.db'))
|
||||
|
||||
function fail(message) {
|
||||
console.error(`Error: ${message}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
let user
|
||||
if (usernameArg) {
|
||||
user = db.prepare(`
|
||||
SELECT id, username, role
|
||||
FROM users
|
||||
WHERE username = ?
|
||||
`).get(usernameArg)
|
||||
if (!user) fail(`user "${usernameArg}" not found`)
|
||||
} else {
|
||||
const admins = db.prepare(`
|
||||
SELECT id, username, role
|
||||
FROM users
|
||||
WHERE role = 'admin'
|
||||
ORDER BY id ASC
|
||||
`).all()
|
||||
if (!admins.length) fail('no administrator account found')
|
||||
if (admins.length > 1) {
|
||||
const names = admins.map(row => row.username).join(', ')
|
||||
fail(`multiple administrators (${names}); run: reset-password <username>`)
|
||||
}
|
||||
user = admins[0]
|
||||
}
|
||||
|
||||
const password = randomBytes(9).toString('base64url')
|
||||
const salt = randomBytes(16).toString('hex')
|
||||
const derived = scryptSync(password, salt, 64, { N: 16384, r: 8, p: 1 })
|
||||
const passwordHash = `scrypt$16384$8$1$${salt}$${derived.toString('hex')}`
|
||||
|
||||
db.prepare('UPDATE users SET password_hash = ? WHERE id = ?').run(passwordHash, user.id)
|
||||
db.prepare('DELETE FROM sessions WHERE user_id = ?').run(user.id)
|
||||
db.close()
|
||||
|
||||
console.log(`[PicHost] User "${user.username}" (${user.role}) password reset.`)
|
||||
console.log(`[PicHost] New password: ${password}`)
|
||||
console.log('[PicHost] Sign in and change it under Account.')
|
||||
Reference in new issue
Block a user