Spaces:
Running
Running
/** | |
* When applied, this middleware will ensure the request contains the required header for basic authentication and only | |
* allow access to the endpoint after successful authentication. | |
*/ | |
import { Buffer } from 'node:buffer'; | |
import storage from 'node-persist'; | |
import { getAllUserHandles, toKey, getPasswordHash } from '../users.js'; | |
import { getConfigValue, safeReadFileSync } from '../util.js'; | |
const PER_USER_BASIC_AUTH = getConfigValue('perUserBasicAuth', false, 'boolean'); | |
const ENABLE_ACCOUNTS = getConfigValue('enableUserAccounts', false, 'boolean'); | |
const basicAuthMiddleware = async function (request, response, callback) { | |
const unauthorizedWebpage = safeReadFileSync('./public/error/unauthorized.html') ?? ''; | |
const unauthorizedResponse = (res) => { | |
res.set('WWW-Authenticate', 'Basic realm="SillyTavern", charset="UTF-8"'); | |
return res.status(401).send(unauthorizedWebpage); | |
}; | |
const basicAuthUserName = getConfigValue('basicAuthUser.username'); | |
const basicAuthUserPassword = getConfigValue('basicAuthUser.password'); | |
const authHeader = request.headers.authorization; | |
if (!authHeader) { | |
return unauthorizedResponse(response); | |
} | |
const [scheme, credentials] = authHeader.split(' '); | |
if (scheme !== 'Basic' || !credentials) { | |
return unauthorizedResponse(response); | |
} | |
const usePerUserAuth = PER_USER_BASIC_AUTH && ENABLE_ACCOUNTS; | |
const [username, password] = Buffer.from(credentials, 'base64') | |
.toString('utf8') | |
.split(':'); | |
if (!usePerUserAuth && username === basicAuthUserName && password === basicAuthUserPassword) { | |
return callback(); | |
} else if (usePerUserAuth) { | |
const userHandles = await getAllUserHandles(); | |
for (const userHandle of userHandles) { | |
if (username === userHandle) { | |
const user = await storage.getItem(toKey(userHandle)); | |
if (user && user.enabled && (user.password && user.password === getPasswordHash(password, user.salt))) { | |
return callback(); | |
} | |
} | |
} | |
} | |
return unauthorizedResponse(response); | |
}; | |
export default basicAuthMiddleware; | |