Initial I Want to Heal app
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { isIP } from 'node:net'
|
||||
import { DatabaseSync } from 'node:sqlite'
|
||||
|
||||
const [command, rawIp, rawLimit, ...noteParts] = process.argv.slice(2)
|
||||
const database = new DatabaseSync('data/game.db')
|
||||
|
||||
function normalizeIp(value) {
|
||||
const address = String(value ?? '').trim()
|
||||
if (address.startsWith('::ffff:') && isIP(address.slice(7)) === 4) {
|
||||
return address.slice(7)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
function requireIp(value) {
|
||||
const address = normalizeIp(value)
|
||||
if (!isIP(address)) {
|
||||
throw new Error('Provide a valid IPv4 or IPv6 address.')
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
try {
|
||||
if (command === 'set') {
|
||||
const ip = requireIp(rawIp)
|
||||
const maxAccounts = Number(rawLimit)
|
||||
if (!Number.isInteger(maxAccounts) || maxAccounts < 2 || maxAccounts > 100) {
|
||||
throw new Error('The allowed account count must be an integer from 2 to 100.')
|
||||
}
|
||||
const note = noteParts.join(' ').slice(0, 200)
|
||||
database.prepare(`
|
||||
INSERT INTO account_ip_allowances
|
||||
(ip_address, max_accounts, note, updated_at)
|
||||
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT(ip_address) DO UPDATE SET
|
||||
max_accounts = excluded.max_accounts,
|
||||
note = excluded.note,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
`).run(ip, maxAccounts, note)
|
||||
console.log(`${ip} may create up to ${maxAccounts} accounts${note ? ` (${note})` : ''}.`)
|
||||
} else if (command === 'remove') {
|
||||
const ip = requireIp(rawIp)
|
||||
const result = database.prepare(`
|
||||
DELETE FROM account_ip_allowances WHERE ip_address = ?
|
||||
`).run(ip)
|
||||
console.log(
|
||||
result.changes
|
||||
? `${ip} returned to the default one-account limit.`
|
||||
: `${ip} had no custom allowance.`,
|
||||
)
|
||||
} else if (command === 'list') {
|
||||
const rows = database.prepare(`
|
||||
SELECT
|
||||
account_ip_allowances.ip_address AS ip,
|
||||
account_ip_allowances.max_accounts AS maxAccounts,
|
||||
account_ip_allowances.note,
|
||||
account_ip_allowances.updated_at AS updatedAt,
|
||||
COUNT(accounts.id) AS existingAccounts
|
||||
FROM account_ip_allowances
|
||||
LEFT JOIN accounts
|
||||
ON accounts.created_ip = account_ip_allowances.ip_address
|
||||
GROUP BY account_ip_allowances.ip_address
|
||||
ORDER BY account_ip_allowances.updated_at DESC
|
||||
`).all()
|
||||
console.table(rows)
|
||||
} else {
|
||||
console.log('Usage:')
|
||||
console.log(' npm run accounts:ip -- set <ip> <max-accounts> [note]')
|
||||
console.log(' npm run accounts:ip -- remove <ip>')
|
||||
console.log(' npm run accounts:ip -- list')
|
||||
process.exitCode = command ? 1 : 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error instanceof Error ? error.message : error)
|
||||
process.exitCode = 1
|
||||
} finally {
|
||||
database.close()
|
||||
}
|
||||
Reference in New Issue
Block a user