forked from mirrors/amnezia-wg-easy
feat: introduce PASSWORD_HASH and deprecate PASSWORD
This commit is contained in:
parent
72fbf1baf6
commit
eaa4b1ebaa
3 changed files with 42 additions and 10 deletions
|
@ -29,11 +29,14 @@ const {
|
|||
WEBUI_HOST,
|
||||
RELEASE,
|
||||
PASSWORD,
|
||||
PASSWORD_HASH,
|
||||
LANG,
|
||||
UI_TRAFFIC_STATS,
|
||||
UI_CHART_TYPE,
|
||||
} = require('../config');
|
||||
|
||||
const requiresPassword = !!PASSWORD || !!PASSWORD_HASH;
|
||||
|
||||
module.exports = class Server {
|
||||
|
||||
constructor() {
|
||||
|
@ -72,7 +75,6 @@ module.exports = class Server {
|
|||
|
||||
// Authentication
|
||||
.get('/api/session', defineEventHandler((event) => {
|
||||
const requiresPassword = !!process.env.PASSWORD;
|
||||
const authenticated = requiresPassword
|
||||
? !!(event.node.req.session && event.node.req.session.authenticated)
|
||||
: true;
|
||||
|
@ -85,19 +87,21 @@ module.exports = class Server {
|
|||
.post('/api/session', defineEventHandler(async (event) => {
|
||||
const { password } = await readBody(event);
|
||||
|
||||
if (typeof password !== 'string') {
|
||||
if (!requiresPassword) {
|
||||
// if no password is required, the API should never be called.
|
||||
// Do not automatically authenticate the user.
|
||||
throw createError({
|
||||
status: 401,
|
||||
message: 'Missing: Password',
|
||||
message: 'Invalid state',
|
||||
});
|
||||
}
|
||||
|
||||
if (password !== PASSWORD) {
|
||||
if (!isPasswordValid(password)) {
|
||||
throw createError({
|
||||
status: 401,
|
||||
message: 'Incorrect Password',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
event.node.req.session.authenticated = true;
|
||||
event.node.req.session.save();
|
||||
|
@ -110,7 +114,7 @@ module.exports = class Server {
|
|||
// WireGuard
|
||||
app.use(
|
||||
fromNodeMiddleware((req, res, next) => {
|
||||
if (!PASSWORD || !req.url.startsWith('/api/')) {
|
||||
if (!requiresPassword || !req.url.startsWith('/api/')) {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
@ -119,7 +123,7 @@ module.exports = class Server {
|
|||
}
|
||||
|
||||
if (req.url.startsWith('/api/') && req.headers['authorization']) {
|
||||
if (bcrypt.compareSync(req.headers['authorization'], bcrypt.hashSync(PASSWORD, 10))) {
|
||||
if (isPasswordValid(req.headers['authorization'])) {
|
||||
return next();
|
||||
}
|
||||
return res.status(401).json({
|
||||
|
@ -235,6 +239,32 @@ module.exports = class Server {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if `password` matches the PASSWORD_HASH.
|
||||
*
|
||||
* For backward compatibility it also allows `password` to match the clear text PASSWORD,
|
||||
* but only if no PASSWORD_HASH is provided.
|
||||
*
|
||||
* If both enviornment variables are not set, the password is always invalid.
|
||||
*
|
||||
* @param {string} password String to test
|
||||
* @returns {boolean} true if matching environment, otherwise false
|
||||
*/
|
||||
const isPasswordValid = (password) => {
|
||||
if (typeof password !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!!PASSWORD_HASH) {
|
||||
return bcrypt.compareSync(password, PASSWORD_HASH);
|
||||
}
|
||||
if (!!PASSWORD) {
|
||||
return password == PASSWORD;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Static assets
|
||||
const publicDir = '/app/www';
|
||||
app.use(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue