Skip to content

Commit

Permalink
Two outputs (#3)
Browse files Browse the repository at this point in the history
* Two outputs
To merge https://github.com/ttrushin/node-red-contrib-basicauth/ which is abandoned
ttrushin/node-red-contrib-basicauth#1

* Update node-red-contrib-mock-cli

* Add msg.username

* Add error messages

* Update documentation

* Fix realm

* Readme outputs
  • Loading branch information
Alkarex authored Oct 13, 2023
1 parent 8ff84fd commit 42018e1
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 25 deletions.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ curl 'https://test:[email protected]/basic-auth-demo'

There are three types of configuration:

1. *Simple*: each node has it’s own credentials. (one credential)
1. *Simple*: each node has its own credentials. (one credential)
2. *Multiple credentials*: credentials shared with multiple nodes. (multiple credentials)
3. *File with multiple credentials*: the user credentials are stored in a file. (multiple credentials)

Expand Down Expand Up @@ -57,6 +57,35 @@ user1:test
user2:$2y$10$5TSZDldoJ7MxDZdtK/SG2O3cwORqLDhHabYlKX9OsM.W/Z/oLwKW6
```

## Outputs

The first node output is used when the authentication succeeded, and it contains the username:

```json
"msg": {
"realm": "node-red",
"username": "alice",
"req": "...",
"res": "...",
"...": "..."
}
```

The second node output is used when the authentication failed, and it contains error information:

```json
"msg": {
"realm": "node-red",
"username": "",
"authError": "Unknown user 'test'",
"req": "...",
"res": "...",
"...": "..."
}
```

Both outputs contain the `req` object, which can be inspected for detailed information about HTTP request headers, IP address, URL, etc.

## Hints

Here are examples to create hashed passwords:
Expand Down
32 changes: 26 additions & 6 deletions examples/flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
"z": "d9a661f4.ef966",
"name": "",
"file": "",
"cred": "",
"multiple": "",
"realm": "node-red",
"username": "test",
"password": "$2y$10$5TSZDldoJ7MxDZdtK/SG2O3cwORqLDhHabYlKX9OsM.W/Z/oLwKW6",
"x": 1040,
"x": 1030,
"y": 100,
"wires": [
[
"6ef8ccf5965075f1"
],
[
"a230b772edd4ea9c"
]
]
},
Expand All @@ -26,7 +29,7 @@
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 810,
"x": 790,
"y": 100,
"wires": [
[
Expand All @@ -42,7 +45,7 @@
"statusCode": "",
"headers": {},
"x": 1370,
"y": 100,
"y": 80,
"wires": []
},
{
Expand All @@ -56,12 +59,29 @@
"syntax": "plain",
"template": "<p>\nHello world!\n</p>\n",
"output": "str",
"x": 1220,
"y": 100,
"x": 1240,
"y": 80,
"wires": [
[
"57b04097f0b0647d"
]
]
},
{
"id": "a230b772edd4ea9c",
"type": "debug",
"z": "d9a661f4.ef966",
"name": "Log error",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1240,
"y": 120,
"wires": []
}
]
Binary file modified images/flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions nodes/http-auth.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RED.nodes.registerType('http-basic-auth', {
category: 'function',
inputs: 1,
outputs: 1,
outputs: 2,
defaults: {
name: { value: '' },
file: { value: '', type: 'http-basic-auth-file', required: false },
Expand Down Expand Up @@ -77,7 +77,7 @@
<h2>Config</h2>
<p>There are three types of configuration:</p>
<ol>
<li><i>Simple</i>: each node has it’s own credentials. (one credential)</li>
<li><i>Simple</i>: each node has its own credentials. (one credential)</li>
<li><i>Multiple credentials</i>: credentials shared with multiple nodes. (multiple credentials)</li>
<li><i>File with multiple credentials</i>: the user credentials are stored in a file. (multiple credentials)</li>
</ol>
Expand Down
33 changes: 27 additions & 6 deletions nodes/http-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,36 @@ function basicAuth(authStr, node, msg) {
const values = Buffer.from(authStr, 'base64').toString().split(':');
const username = values[0];
const password = values[1];

if (username == '' || username == '') {
msg.authError = 'Invalid format for credentials!';
unAuth(node, msg);
return;
}

const user = node.httpauthconf.getUser(username);

if (user !== null && passwordCompare(password, user.password)) {
node.send(msg);
} else {
if (user === null) {
msg.authError = `Unknown user '${username}'!`;
unAuth(node, msg);
return;
}

if (!passwordCompare(password, user.password)) {
msg.authError = `Invalid credentials for user '${username}'!`;
unAuth(node, msg);
return;
}

msg.username = user.username;
node.send([msg, null]);
}

function unAuth(node, msg, stale) {
function unAuth(node, msg) {
const res = msg.res._res || msg.res; // Resolves deprecates warning messages.
res.set('WWW-Authenticate', 'Basic realm="' + node.httpauthconf.realm + '"');
res.type('text/plain');
res.status(401).send('401 Unauthorized');
res.sendStatus(401);
node.send([null, msg]);
}

module.exports = function (RED) {
Expand Down Expand Up @@ -76,17 +92,22 @@ module.exports = function (RED) {
this.httpauthconf = {};
this.httpauthconf.src = src;
this.httpauthconf.getUser = getUser;
this.httpauthconf.realm = config.realm;

const node = this;

this.on('input', function (msg) {
msg.realm = node.httpauthconf.realm;
msg.username = '';

const header = msg.req.get('Authorization');
const authType = header ? header.match(/^\w+\b/)[0] : null;

if (header && authType === 'Basic') {
const authStr = header.substring(authType.length).trim();
basicAuth(authStr, node, msg);
} else {
msg.authError = 'Missing Basic Auth headers!';
unAuth(node, msg);
}
});
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
"eslint-config-standard": "^17.1.0",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-n": "^16.1.0",
"eslint-plugin-n": "^16.2.0",
"eslint-plugin-promise": "^6.1.1",
"node-red-contrib-mock-cli": "^1.4.0"
"node-red-contrib-mock-cli": "^1.4.1"
},
"scripts": {
"start": "node ./index.js",
Expand Down

0 comments on commit 42018e1

Please sign in to comment.