Files
munin-bitcoin/server/auth.js
T

87 lines
1.6 KiB
JavaScript

const crypto = require('crypto')
const adminPassword = process.env.MUNIN_ADMIN_PASSWORD || ''
const sessions = new Map()
const SESSION_TTL_MS = 24 * 60 * 60 * 1000
function createSession() {
const token = crypto.randomBytes(32).toString('hex')
sessions.set(token, {
expiresAt: Date.now() + SESSION_TTL_MS,
})
return token
}
function parseCookies(cookieHeader) {
const cookies = {}
for (const part of (cookieHeader || '').split(';')) {
const index = part.indexOf('=')
if (index === -1) continue
const name = part.slice(0, index).trim()
const value = part.slice(index + 1).trim()
if (name) {
cookies[name] = decodeURIComponent(value)
}
}
return cookies
}
function isValidSession(req) {
const token = parseCookies(req.headers.cookie).munin_session
if (!token) return false
const session = sessions.get(token)
if (!session) return false
if (session.expiresAt <= Date.now()) {
sessions.delete(token)
return false
}
return true
}
function passwordsEqual(a, b) {
const left = Buffer.from(a)
const right = Buffer.from(b)
if (left.length !== right.length) return false
return crypto.timingSafeEqual(left, right)
}
function checkPassword(password) {
if (!adminPassword || typeof password !== 'string') {
return false
}
return passwordsEqual(password, adminPassword)
}
function cleanupSessions() {
const now = Date.now()
for (const [token, session] of sessions) {
if (session.expiresAt <= now) {
sessions.delete(token)
}
}
}
setInterval(cleanupSessions, 60 * 60 * 1000).unref()
module.exports = {
checkPassword,
createSession,
isValidSession,
}