Skip to content

Commit

Permalink
Add bcrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
Alkarex committed Oct 10, 2023
1 parent 4954fba commit bca0177
Show file tree
Hide file tree
Showing 9 changed files with 510 additions and 56 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
This Node-RED module performs [HTTP Basic authentication](https://developer.mozilla.org/docs/Web/HTTP/Authentication).
It is to be used in conjunction with an [HTTP Input node](https://cookbook.nodered.org/http/create-an-http-endpoint).

Supports [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) to store passwords
(such as in the [Apache password format](https://httpd.apache.org/docs/current/misc/password_encryptions.html)).

![flow.png](images/flow.png)

## Config
Expand All @@ -19,19 +22,18 @@ There are three type of configuration:

With all three config types you must specify the following:

- *Realm*: what realm will be used with this node
- *Hashed*: are the passwords in the *Password* field or in the credentials file hashed.
- *Realm*: what authorization realm will be used with this node.

With *Simple* and *Shared* config types you must specify the following:

- *Username*: the username
- *Password*: the password.
If you entered a hashed password you must check the *Hashed* checkbox.
- *Password*: the password may be in plain-text or hashed (only bcrypt is supported).

With *File* config type you must specify the following:

- File: location of the file containing the credentials relative to the presently working directory.
If the password are hashed you must check the Hashed checkbox.
The format for each line is `user:realm:password`.
The passwords may be in plain-text or hashed (only bcrypt is supported).

### File Configuration

Expand Down
5 changes: 0 additions & 5 deletions nodes/http-auth-cred.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
realm: { value: '', required: true },
username: { value: '', required: true },
password: { value: '', required: true },
hashed: { value: false, required: true },
},
label: function () {
return this.name.trim() || this.realm.trim() + ':' + this.username.trim() + ':*****';
Expand All @@ -32,8 +31,4 @@
<label for="node-config-input-password"><i class="fa fa-key"></i> Password</label>
<input type="text" id="node-config-input-password" />
</div>
<div class="form-row">
<label for="node-config-input-hashed"><i class="fa fa-asterisk"></i> Hashed credentials</label>
<input type="checkbox" id="node-config-input-hashed" />
</div>
</script>
1 change: 0 additions & 1 deletion nodes/http-auth-cred.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module.exports = function (RED) {
this.realm = config.realm;
this.username = config.username;
this.password = config.password;
this.hashed = config.hashed;
}

RED.nodes.registerType('node-red-http-basic-auth-cred', HttpAuthCredNode);
Expand Down
5 changes: 0 additions & 5 deletions nodes/http-auth-file.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
name: { value: '' },
realm: { value: '', required: true },
filePath: { value: '', required: true },
hashed: { value: false, required: true },
},
label: function () {
return this.name.trim() || this.realm.trim() + ':' + this.filePath.trim();
Expand All @@ -27,8 +26,4 @@
<label for="node-config-input-filePath"><i class="fa fa-file"></i> File</label>
<input type="text" id="node-config-input-filePath" />
</div>
<div class="form-row">
<label for="node-config-input-hashed"><i class="fa fa-asterisk"></i> Hashed credentials</label>
<input type="checkbox" id="node-config-input-hashed" />
</div>
</script>
7 changes: 2 additions & 5 deletions nodes/http-auth-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module.exports = function (RED) {
const realm = config.realm.trim();
const realmL = realm.toLowerCase();
const filePath = config.filePath.trim();
const hashed = config.hashed;
const users = {};

const stats = fs.statSync(filePath);
Expand All @@ -25,12 +24,11 @@ module.exports = function (RED) {
const _realmL = _realm.toLowerCase();
const _password = values[2];

if (_realmL == realmL) {
if (_realmL === realmL) {
users[_usernameL] = {
realm: _realm,
username: _username,
password: _password,
hashed,
};
}
}
Expand All @@ -40,12 +38,11 @@ module.exports = function (RED) {
this.getUser = function (_realm, _username) {
const _realmL = _realm.trim().toLowerCase();
const _usernameL = _username.trim().toLowerCase();
if (_realmL == realmL && users[_usernameL]) {
if (_realmL === realmL && users[_usernameL]) {
return {
realm: users[_usernameL].realm,
username: users[_usernameL].username,
password: users[_usernameL].password,
hashed: users[_usernameL].hashed,
};
}
return null;
Expand Down
14 changes: 4 additions & 10 deletions nodes/http-auth.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
realm: { value: '' },
username: { value: '' },
password: { value: '' },
hashed: { value: false },
},
color: '#E7E7AE',
icon: 'white-globe.png',
Expand Down Expand Up @@ -41,10 +40,6 @@
<label for="node-input-password"><i class="fa fa-key"></i> Password</label>
<input type="text" id="node-input-password" />
</div>
<div class="form-row">
<label for="node-input-hashed"><i class="fa fa-asterisk"></i> Hashed credentials</label>
<input type="checkbox" id="node-input-hashed" />
</div>
</fieldset>

<fieldset>
Expand Down Expand Up @@ -89,24 +84,23 @@ <h2>Config</h2>

<p>With all three config types you must specify the following:</p>
<ul>
<li><i>Realm</i>: what realm will be used with this node</li>
<li><i>Hashed</i>: are the passwords in the Password field or in the credentials file hashed.</li>
<li><i>Realm</i>: what authorization realm will be used with this node</li>
</ul>

<p>With <i>Simple</i> and <i>Shared</i> config types you must specify the following:</p>
<ul>
<li><i>Username</i>: the username</li>
<li>
<i>Password</i>: the password.<br />
If you entered a hashed password you must check the Hashed checkbox.
<i>Password</i>: the password may be in plain-text or hashed (only bcrypt is supported).
</li>
</ul>

<p>With <i>File</i> config type you must specify the following:</p>
<ul>
<li>
<i>File</i>: location of the file containing the credentials relative to the presently working directory.<br />
If the password are hashed you must check the Hashed checkbox.
The format for each line is <code>user:realm:password</code>.<br />
The passwords may be in plain-text or hashed (only bcrypt is supported).
</li>
</ul>

Expand Down
16 changes: 11 additions & 5 deletions nodes/http-auth.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
let bcrypt;
try {
// Faster native library, if available
bcrypt = require('bcrypt');
} catch (e) {
// Pure JavaScript fallback
bcrypt = require('bcryptjs');
}

function basicAuth(authStr, node, msg) {
const values = Buffer.from(authStr, 'base64').toString().split(':');
const username = values[0];
const password = values[1];
const user = node.httpauthconf.getUser(node.httpauthconf.realm, username);

if (user && password == user.password) {
if (user !== null && (password === user.password || bcrypt.compareSync(password, user.password))) {
node.send(msg);
} else {
unAuth(node, msg);
Expand All @@ -30,14 +39,12 @@ module.exports = function (RED) {
let username = config.username.trim();
let usernameL = username.toLowerCase();
let password = config.password;
let hashed = config.hashed;
let getUser = function (_realm, _username) {
if (_realm.trim().toLowerCase() == realmL && _username.trim().toLowerCase() == usernameL) {
if (_realm.trim().toLowerCase() === realmL && _username.trim().toLowerCase() === usernameL) {
return {
realm,
username,
password,
hashed,
};
}
return null;
Expand All @@ -51,7 +58,6 @@ module.exports = function (RED) {
username = cred.username.trim();
usernameL = username.toLowerCase();
password = cred.password;
hashed = cred.hashed;
}

const file = RED.nodes.getNode(config.file);
Expand Down
Loading

0 comments on commit bca0177

Please sign in to comment.