Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node RED SDK v0.1.1 #13

Merged
merged 4 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,25 @@ This repository contains the NodeRED nodes to interact with the HCL Domino REST

## Installation

Install the palette manager or `npm` like any other [NodeRED](https://nodered.org/) node
Install the palette manager or `npm` like any other [NodeRED](https://nodered.org/) node.

```bash
npm install @hcl-software/node-red-domino
```

The installation will add one node in `network` and two related configuration nodes.
![Domino Node](img/dominonode.png). Each node gets configured with a credential and a connection configuration node. Multiple Domino can share the same Credential and Connection node.

![Domino Node](img/dominonode.png)

Each node gets configured with a credential and a connection configuration node. Multiple Domino can share the same credential and connection node.

## Usage

Each Domino Node can be configured to execute [**one OperationId**](https://opensource.hcltechsw.com/Domino-rest-api/topicguides/howkeepworks.html?h=operationid). The node translates the OperationId into the actual operation URL and checks for mandatory parameters.
Each Domino node can be configured to execute [**one operation ID**](https://opensource.hcltechsw.com/Domino-rest-api/topicguides/howkeepworks.html?h=operationid). The node translates the operation ID into the actual operation URL and checks for mandatory parameters.

### Configuration

A new Node and the related configuration nodes show regular entry fields:
A new node and the related configuration nodes show regular entry fields:

![Domino Node](img/EmptyDOminoNode.png)
![Domino Credential Node](img/EmptyCredentialsNode.png)
Expand All @@ -38,21 +41,20 @@ After saving and re-opening the dialogs query the server and populate the drop-d
![Domino Credential Node](img/FullCredentialsNode.png)
![Domino Connection Node](img/FullConnectionNode.png)

Check the node help and the official [Domino REST API Documentation](https://opensource.hcltechsw.com/Domino-rest-api/) for details, especially around [Operation IDs](https://opensource.hcltechsw.com/Domino-rest-api/references/openapidefinitions.html)
Check the node help and the official [Domino REST API Documentation](https://opensource.hcltechsw.com/Domino-rest-api/) for details, especially around [operation IDs](https://opensource.hcltechsw.com/Domino-rest-api/references/openapidefinitions.html)

### Flows

- refer to the exsample directory
- all parameters (well most of) are in the `msg.payload`
- payload can have a `params` object for parameters and a `body` object for request bodies. Both objects are optional
- You can specify a `msg.unid` to interact with one document
- responses that can have more than one result (lists, query) emit on result for each entry. This can be switched off using `single result (no splitting)`
- Refer to the example directory.
- All parameters (well most of) are in the `msg.payload`.
- Payload can have a `params` object for parameters and a `body` object for request bodies. Both objects are optional.
- You can specify a `msg.unid` to interact with one document.
- Responses that can have more than one result (lists, query) emit on result for each entry. This can be switched off using `single result (no splitting)`.

## Known limitations

- To take advantage of the selection list, you need to add the Credential and COnnection Configuration Nodes and close the DOmino Node. On Open the configuration queries teh server and offers APis, scope and OperationIds found on your selected server.
- th http response node can't send chunked responses, so in a http flow you need to select `single result (no splitting)`
- authentication using username/password olny (for now)
- To take advantage of the selection list, you need to add the credential and connection configuration nodes and close the Domino node. On open, the configuration queries the server and offers APIs, scope and operation IDs found on your selected server.
- The HTTP response node can't send chunked responses, so in a HTTP flow you need to select `single result (no splitting)`.

## Documentation

Expand All @@ -72,3 +74,11 @@ Check the node help and the official [Domino REST API Documentation](https://ope
### 0.1.0 November 2023 Release

- initial release

### 0.1.1

- Credential configuration node now has three authentication types:

- basic
- oauth
- token
120 changes: 99 additions & 21 deletions domino/domino-access.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,77 @@
RED.nodes.registerType('domino-access', {
category: 'config',
defaults: {
name: { value: '', required: true },
name: { required: true },
authtype: { value: 'basic', required: true },
baseUrl: { value: 'http://localhost:8880', required: true },
scope: { value: '$DATA', required: true },
authtype: { value: 'basic', required: true }
},
credentials: {
// basic, oauth
scope: { type: 'text' },
// basic
username: { type: 'text' },
password: { type: 'password' }
// basic
password: { type: 'password' },
// oauth
appId: { type: 'text' },
// oauth
appSecret: { type: 'password' },
// oauth
refreshToken: { type: 'password' },
// token
token: { type: 'password' },
},
label: function () {
return this.name + ': ' + this.scope;
if (this.credentials) {
return this.name + ': ' + this.credentials.scope;
}
return this.name;
},
oneditprepare: function () {
function hideAllCredentialConfig() {
$('#node-config-div-scope').hide();
$('#node-config-div-username').hide();
$('#node-config-div-password').hide();
$('#node-config-div-appId').hide();
$('#node-config-div-appSecret').hide();
$('#node-config-div-refreshToken').hide();
$('#node-config-div-token').hide();
}

// defaults
$('#node-config-input-scope').val('$DATA');
hideAllCredentialConfig();
$('#node-config-div-scope').show();
$('#node-config-div-username').show();
$('#node-config-div-password').show();

getAuthMethods()
.then((ti) => $('#node-config-input-authtype').typedInput(ti))
.catch((e) => console.error(e));
getScopes($('#node-config-input-baseUrl').val())
.then((ti) => {
ti.types[0].multiple = 'true';
$('#node-config-input-scope').typedInput(ti);
})
.catch((e) => console.error(e));
// getScopes($('#node-config-input-baseUrl').val())
// .then((ti) => {
// ti.types[0].multiple = 'true';
// $('#node-config-input-scope').typedInput(ti);
// })
// .catch((e) => console.error(e));

$('#node-config-input-authtype').on('change', function () {
hideAllCredentialConfig();

const authtype = $('#node-config-input-authtype').val();
if (authtype === 'basic') {
$('#node-config-div-scope').show();
$('#node-config-div-username').show();
$('#node-config-div-password').show();
} else if (authtype === 'oauth') {
$('#node-config-div-scope').show();
$('#node-config-div-appId').show();
$('#node-config-div-appSecret').show();
$('#node-config-div-refreshToken').show();
} else if (authtype === 'token') {
$('#node-config-div-token').show();
}
});
}
});
</script>
Expand All @@ -34,40 +83,69 @@
<label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-config-input-name" placeholder="Name" />
</div>

<div class="form-row">
<label for="node-config-input-authtype">
<i class="fa fa-user"></i> Auth type
</label>
<input type="text" id="node-config-input-authtype" />
</div>

<div class="form-row">
<label for="node-config-input-baseUrl">
<i class="fa fa-globe"></i> Base URL
</label>
<input type="url" id="node-config-input-baseUrl" />
</div>

<div class="form-row">
<div class="form-row" id="node-config-div-scope">
<label for="node-config-input-scope">
<i class="fa fa-gears"></i> Scopes
</label>
<input type="text" id="node-config-input-scope" />
</div>

<div class="form-row">
<label for="node-config-input-authtype">
<i class="fa fa-user"></i> Auth type
</label>
<input type="text" id="node-config-input-authtype" />
</div>

<div class="form-row">
<div class="form-row" id="node-config-div-username">
<label for="node-config-input-username">
<i class="fa fa-user"></i> Username
</label>
<input type="text" id="node-config-input-username" />
</div>

<div class="form-row">
<div class="form-row" id="node-config-div-password">
<label for="node-config-input-password">
<i class="fa fa-file"></i> Password
</label>
<input type="password" id="node-config-input-password" />
</div>

<div class="form-row" id="node-config-div-appId">
<label for="node-config-input-appId">
<i class="fa fa-user"></i> Application ID
</label>
<input type="text" id="node-config-input-appId" />
</div>

<div class="form-row" id="node-config-div-appSecret">
<label for="node-config-input-appSecret">
<i class="fa fa-file"></i> Application Secret
</label>
<input type="password" id="node-config-input-appSecret" />
</div>

<div class="form-row" id="node-config-div-refreshToken">
<label for="node-config-input-refreshToken">
<i class="fa fa-file"></i> Refresh Token
</label>
<input type="password" id="node-config-input-refreshToken" />
</div>

<div class="form-row" id="node-config-div-token">
<label for="node-config-input-token">
<i class="fa fa-file"></i> Token
</label>
<input type="password" id="node-config-input-token" />
</div>
</script>

<script type="text/html" data-help-name="domino-access">
Expand Down
43 changes: 33 additions & 10 deletions domino/domino-access.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,30 @@ module.exports = function (RED) {
const node = this;
node.name = config.name;
node.baseUrl = config.baseUrl;
node.scope = config.scope.replace(',', ' ');
node.scope = node.credentials.scope.replace(',', ' ');
node.authtype = config.authtype;
node.username = node.credentials.username;
node.password = node.credentials.password;
node.creds = {
baseUrl: config.baseUrl,
credentials: {
type: config.authtype,
scope: config.scope,
username: node.credentials.username,
password: node.credentials.password
}
type: node.authtype
},
};

if (config.authtype === 'basic') {
node.creds.credentials.scope = node.credentials.scope.replace(',', ' ');
node.creds.credentials.username = node.credentials.username;
node.creds.credentials.password = node.credentials.password;
} else if (config.authtype === 'oauth') {
node.creds.credentials.scope = node.credentials.scope.replace(',', ' ');
node.creds.credentials.appId = node.credentials.appId;
node.creds.credentials.appSecret = node.credentials.appSecret;
node.creds.credentials.refreshToken = node.credentials.refreshToken;
} else if (config.authtype === 'token') {
node.creds.credentials.token = node.credentials.token;
} else {
console.log(`Authentication type: ${config.authtype} is not supported`);
}

try {
node.dominoAccess = new keepAPI.DominoAccess(node.creds);
} catch (e) {
Expand All @@ -33,8 +44,20 @@ module.exports = function (RED) {

RED.nodes.registerType('domino-access', DominoAccessNode, {
credentials: {
// basic, oauth
scope: { type: 'text' },
// basic
username: { type: 'text' },
password: { type: 'password' }
}
// basic
password: { type: 'password' },
// oauth
appId: { type: 'text' },
// oauth
appSecret: { type: 'password' },
// oauth
refreshToken: { type: 'password' },
// token
token: { type: 'password' },
},
});
};
1 change: 0 additions & 1 deletion domino/domino-user-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* ========================================================================== */

const keepred = require('./keepred');
const keepAPI = require('@hcl-software/domino-rest-sdk-node');

/**
* Main NodeRED node <code>domino-user-session</code> depending on two configurstion
Expand Down
10 changes: 4 additions & 6 deletions domino/keepred.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ const getKeepScopesServer = (hostname) => {
}

console.log(`Retrieve scope List for ${hostname}`);

return fetch(hostURL.href)
.then((result) => successJsonOrError(result))
.then((json) => {
Expand Down Expand Up @@ -264,12 +263,11 @@ const runRequest = (session, operationId, scope, msg, send, singleReply) =>
/**
* Processes the data stream
*
* Here is the interesting part
* we have 4 potential scenarios:
* Here is the interesting part we have 4 potential scenarios:
* 1. JSON not chunked
* 2. JSON chunked
* 3. Binary not chunked
* 4. Binary chunked
* 4. Binary chunked
*
* @param {ReadableStream} stream
* @param {json} newMsg
Expand All @@ -286,7 +284,7 @@ const processResultStream = (stream, returnMsg, send, singleReply) => {
.pipeThrough(keepAPI.streamTransformToJson())
.pipeTo(streamToSend(returnMsg, send));
}
// Anythin else
// Anything else
return stream.pipeTo(streamToSend(returnMsg, send));
}

Expand Down Expand Up @@ -390,7 +388,7 @@ const lookupForAdminUI = (req, res) => {
};

/**
* Main function when DOmino processsing needs to happen
* Main function when Domino processsing needs to happen
*
* @param {domino-user-session} node The NodeRED Node processing incoming requests
* @param {json} msg The NodeRED incoming message
Expand Down
Binary file modified img/EmptyCredentialsNode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/FullCredentialsNode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed img/FullDominoCredentialsNode.png
Binary file not shown.
12 changes: 6 additions & 6 deletions package-lock.json

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

Loading