@yousolution/node-red-contrib-you-sap-service-layer 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +6 -0
- package/.vscode/launch.json +23 -23
- package/CHANGELOG.md +57 -49
- package/README.md +126 -126
- package/docker-compose.yml +14 -14
- package/examples/example.json +625 -625
- package/nodes/SQLQuery.html +179 -179
- package/nodes/SQLQuery.js +46 -46
- package/nodes/authenticateSap.html +146 -146
- package/nodes/authenticateSap.js +129 -129
- package/nodes/closeSap.html +128 -97
- package/nodes/closeSap.js +36 -36
- package/nodes/createSQLQuery.html +165 -165
- package/nodes/createSQLQuery.js +70 -70
- package/nodes/createSap.html +391 -391
- package/nodes/createSap.js +40 -40
- package/nodes/crossJoinSap.html +394 -394
- package/nodes/crossJoinSap.js +37 -37
- package/nodes/deleteSap.html +406 -407
- package/nodes/deleteSap.js +35 -35
- package/nodes/getSap.html +427 -445
- package/nodes/getSap.js +34 -34
- package/nodes/listSap.html +402 -402
- package/nodes/listSap.js +37 -37
- package/nodes/manageErrors.js +38 -38
- package/nodes/manipulateEntitySap.html +176 -176
- package/nodes/manipulateEntitySap.js +46 -46
- package/nodes/nextLink.html +100 -100
- package/nodes/nextLink.js +18 -18
- package/nodes/patchSap.html +424 -434
- package/nodes/patchSap.js +40 -40
- package/nodes/serviceSap.html +206 -206
- package/nodes/serviceSap.js +39 -44
- package/nodes/support.js +363 -363
- package/package.json +65 -65
- package/resources/entities.json +59 -59
- package/resources/services.json +343 -343
- package/test/authenticateSap.spec.js +307 -307
- package/test/closeSap.spec.js +156 -156
- package/test/createSQLQuery.spec.js +174 -174
- package/test/createSap.spec.js +183 -183
- package/test/crossJoinSap.spec.js +156 -156
- package/test/deleteSap.spec.js +156 -156
- package/test/getSap.spec.js +156 -156
- package/test/listSap.spec.js +156 -156
- package/test/manipulateEntitySap.spec.js +191 -191
- package/test/patchSap.spec.js +184 -184
- package/test/serviceSap.spec.js +170 -170
- package/test/support.spec.js +1419 -1419
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
<script type="text/javascript">
|
|
2
|
-
RED.nodes.registerType('authenticateSap',{
|
|
3
|
-
category: 'Sap',
|
|
4
|
-
color: '#FFC300',
|
|
5
|
-
defaults: {
|
|
6
|
-
name: {value: ''},
|
|
7
|
-
host: {value: ''},
|
|
8
|
-
port: {value: ''},
|
|
9
|
-
version: {value: ''}
|
|
10
|
-
},
|
|
11
|
-
credentials: {
|
|
12
|
-
company: {type: "string"},
|
|
13
|
-
companyType: {type: 'string'},
|
|
14
|
-
user: {type:"string"},
|
|
15
|
-
userType: {type: 'string'},
|
|
16
|
-
password: {type:"password"}
|
|
17
|
-
},
|
|
18
|
-
inputs:1,
|
|
19
|
-
outputs:1,
|
|
20
|
-
icon: 'font-awesome/fa-lock',
|
|
21
|
-
label: function() {
|
|
22
|
-
return this.name||"Sap authenticate";
|
|
23
|
-
},
|
|
24
|
-
oneditprepare: function() {
|
|
25
|
-
$("#node-input-company").typedInput({
|
|
26
|
-
default:"msg",
|
|
27
|
-
types:["msg", "str"],
|
|
28
|
-
typeField: "#node-input-companyType"
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
$("#node-input-user").typedInput({
|
|
32
|
-
default:"msg",
|
|
33
|
-
types:["msg", "str"],
|
|
34
|
-
typeField: "#node-input-userType"
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<script type="text/html" data-template-name="authenticateSap">
|
|
41
|
-
<div class="form-row">
|
|
42
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
43
|
-
<input type="text" id="node-input-name" placeholder="Name">
|
|
44
|
-
</div>
|
|
45
|
-
|
|
46
|
-
<div class="form-row">
|
|
47
|
-
<label for="node-input-host"><i class="fa fa-cogs"></i> Host</label>
|
|
48
|
-
<input type="text" id="node-input-host" placeholder="Host">
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<div class="form-row">
|
|
52
|
-
<label for="node-input-port"><i class="fa fa-cogs"></i> Port</label>
|
|
53
|
-
<input type="text" id="node-input-port" placeholder="Port">
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<div class="form-row">
|
|
57
|
-
<label for="node-input-version"><i class="fa fa-cogs"></i> Version</label>
|
|
58
|
-
<select name="node-input-version" id="node-input-version">
|
|
59
|
-
<option value="v1">v1</option>
|
|
60
|
-
<option value="v2">v2</option>
|
|
61
|
-
</select>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<div class="form-row">
|
|
65
|
-
<label for="node-input-company"><i class="fa fa-tag"></i> Company</label>
|
|
66
|
-
<input type="text" id="node-input-company" placeholder="company">
|
|
67
|
-
<input type="hidden" id="node-input-companyType">
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<div class="form-row">
|
|
71
|
-
<label for="node-input-user"><i class="fa fa-tag"></i> User</label>
|
|
72
|
-
<input type="text" id="node-input-user" placeholder="user">
|
|
73
|
-
<input type="hidden" id="node-input-userType">
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
<div class="form-row">
|
|
77
|
-
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
|
|
78
|
-
<input type="password" id="node-input-password" placeholder="password">
|
|
79
|
-
</div>
|
|
80
|
-
</script>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<!-- Documentation -->
|
|
84
|
-
<script type="text/html" data-help-name="authenticateSap">
|
|
85
|
-
<p>Authenticate action</p>
|
|
86
|
-
|
|
87
|
-
<h3>Inputs</h3>
|
|
88
|
-
<dl class="message-properties">
|
|
89
|
-
<dt>Name
|
|
90
|
-
<span class="property-type">string</span>
|
|
91
|
-
</dt>
|
|
92
|
-
<dd> the node's name </dd>
|
|
93
|
-
<dt>Host
|
|
94
|
-
<span class="property-type">string</span>
|
|
95
|
-
</dt>
|
|
96
|
-
<dd> Service layer's hostname </dd>
|
|
97
|
-
<dt>Port
|
|
98
|
-
<span class="property-type">number</span>
|
|
99
|
-
</dt>
|
|
100
|
-
<dd> Service layer's port </dd>
|
|
101
|
-
<dt>Version
|
|
102
|
-
<span class="property-type">[v1,v2]</span>
|
|
103
|
-
</dt>
|
|
104
|
-
<dd> Service layer's version </dd>
|
|
105
|
-
<dt>Company
|
|
106
|
-
<span class="property-type">string</span>
|
|
107
|
-
</dt>
|
|
108
|
-
<dd> Company's name to connect </dd>
|
|
109
|
-
<dt>User
|
|
110
|
-
<span class="property-type">string</span>
|
|
111
|
-
</dt>
|
|
112
|
-
<dd>Username to connect to the company's database </dd>
|
|
113
|
-
<dt>Password
|
|
114
|
-
<span class="property-type">string</span>
|
|
115
|
-
</dt>
|
|
116
|
-
<dd>Password to connect to the company's database </dd>
|
|
117
|
-
|
|
118
|
-
</dl>
|
|
119
|
-
|
|
120
|
-
<h3>Outputs</h3>
|
|
121
|
-
<ol class="node-ports">
|
|
122
|
-
<li>Standard output
|
|
123
|
-
<dl class="message-properties">
|
|
124
|
-
<dt>payload <span class="property-type">string</span></dt>
|
|
125
|
-
<dd>the standard output of the command.</dd>
|
|
126
|
-
</dl>
|
|
127
|
-
</li>
|
|
128
|
-
</ol>
|
|
129
|
-
|
|
130
|
-
<h3>Details</h3>
|
|
131
|
-
<p>this node is used to authenticate to the service layer.
|
|
132
|
-
See the examples to understand how to use it.
|
|
133
|
-
</p>
|
|
134
|
-
<!-- <p><code>msg.payload</code> is used as the payload of the published message.
|
|
135
|
-
If it contains an Object it will be converted to a JSON string before being sent.
|
|
136
|
-
If it contains a binary Buffer the message will be published as-is.</p>
|
|
137
|
-
<p>The topic used can be configured in the node or, if left blank, can be set
|
|
138
|
-
by <code>msg.topic</code>.</p>
|
|
139
|
-
<p>Likewise the QoS and retain values can be configured in the node or, if left
|
|
140
|
-
blank, set by <code>msg.qos</code> and <code>msg.retain</code> respectively.</p> -->
|
|
141
|
-
|
|
142
|
-
<h3>References</h3>
|
|
143
|
-
<ul>
|
|
144
|
-
<li><a href="https://sap-samples.github.io/smb-summit-hackathon/b1sl.html" target="_black">Service layer API docs</a> - for more details </li>
|
|
145
|
-
<li><a href="https://github.com/yousolution-cloud/node-red-contrib-you-sap-service-layer">@yousolution-cloud/node-red-contrib-you-sap-service-layer</a> - the nodes github repository</li>
|
|
146
|
-
</ul>
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('authenticateSap',{
|
|
3
|
+
category: 'Sap',
|
|
4
|
+
color: '#FFC300',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: {value: ''},
|
|
7
|
+
host: {value: ''},
|
|
8
|
+
port: {value: ''},
|
|
9
|
+
version: {value: ''}
|
|
10
|
+
},
|
|
11
|
+
credentials: {
|
|
12
|
+
company: {type: "string"},
|
|
13
|
+
companyType: {type: 'string'},
|
|
14
|
+
user: {type:"string"},
|
|
15
|
+
userType: {type: 'string'},
|
|
16
|
+
password: {type:"password"}
|
|
17
|
+
},
|
|
18
|
+
inputs:1,
|
|
19
|
+
outputs:1,
|
|
20
|
+
icon: 'font-awesome/fa-lock',
|
|
21
|
+
label: function() {
|
|
22
|
+
return this.name||"Sap authenticate";
|
|
23
|
+
},
|
|
24
|
+
oneditprepare: function() {
|
|
25
|
+
$("#node-input-company").typedInput({
|
|
26
|
+
default:"msg",
|
|
27
|
+
types:["msg", "str"],
|
|
28
|
+
typeField: "#node-input-companyType"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
$("#node-input-user").typedInput({
|
|
32
|
+
default:"msg",
|
|
33
|
+
types:["msg", "str"],
|
|
34
|
+
typeField: "#node-input-userType"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<script type="text/html" data-template-name="authenticateSap">
|
|
41
|
+
<div class="form-row">
|
|
42
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
43
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="form-row">
|
|
47
|
+
<label for="node-input-host"><i class="fa fa-cogs"></i> Host</label>
|
|
48
|
+
<input type="text" id="node-input-host" placeholder="Host">
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div class="form-row">
|
|
52
|
+
<label for="node-input-port"><i class="fa fa-cogs"></i> Port</label>
|
|
53
|
+
<input type="text" id="node-input-port" placeholder="Port">
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="form-row">
|
|
57
|
+
<label for="node-input-version"><i class="fa fa-cogs"></i> Version</label>
|
|
58
|
+
<select name="node-input-version" id="node-input-version">
|
|
59
|
+
<option value="v1">v1</option>
|
|
60
|
+
<option value="v2">v2</option>
|
|
61
|
+
</select>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div class="form-row">
|
|
65
|
+
<label for="node-input-company"><i class="fa fa-tag"></i> Company</label>
|
|
66
|
+
<input type="text" id="node-input-company" placeholder="company">
|
|
67
|
+
<input type="hidden" id="node-input-companyType">
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="form-row">
|
|
71
|
+
<label for="node-input-user"><i class="fa fa-tag"></i> User</label>
|
|
72
|
+
<input type="text" id="node-input-user" placeholder="user">
|
|
73
|
+
<input type="hidden" id="node-input-userType">
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="form-row">
|
|
77
|
+
<label for="node-input-password"><i class="fa fa-lock"></i> Password</label>
|
|
78
|
+
<input type="password" id="node-input-password" placeholder="password">
|
|
79
|
+
</div>
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
<!-- Documentation -->
|
|
84
|
+
<script type="text/html" data-help-name="authenticateSap">
|
|
85
|
+
<p>Authenticate action</p>
|
|
86
|
+
|
|
87
|
+
<h3>Inputs</h3>
|
|
88
|
+
<dl class="message-properties">
|
|
89
|
+
<dt>Name
|
|
90
|
+
<span class="property-type">string</span>
|
|
91
|
+
</dt>
|
|
92
|
+
<dd> the node's name </dd>
|
|
93
|
+
<dt>Host
|
|
94
|
+
<span class="property-type">string</span>
|
|
95
|
+
</dt>
|
|
96
|
+
<dd> Service layer's hostname </dd>
|
|
97
|
+
<dt>Port
|
|
98
|
+
<span class="property-type">number</span>
|
|
99
|
+
</dt>
|
|
100
|
+
<dd> Service layer's port </dd>
|
|
101
|
+
<dt>Version
|
|
102
|
+
<span class="property-type">[v1,v2]</span>
|
|
103
|
+
</dt>
|
|
104
|
+
<dd> Service layer's version </dd>
|
|
105
|
+
<dt>Company
|
|
106
|
+
<span class="property-type">string</span>
|
|
107
|
+
</dt>
|
|
108
|
+
<dd> Company's name to connect </dd>
|
|
109
|
+
<dt>User
|
|
110
|
+
<span class="property-type">string</span>
|
|
111
|
+
</dt>
|
|
112
|
+
<dd>Username to connect to the company's database </dd>
|
|
113
|
+
<dt>Password
|
|
114
|
+
<span class="property-type">string</span>
|
|
115
|
+
</dt>
|
|
116
|
+
<dd>Password to connect to the company's database </dd>
|
|
117
|
+
|
|
118
|
+
</dl>
|
|
119
|
+
|
|
120
|
+
<h3>Outputs</h3>
|
|
121
|
+
<ol class="node-ports">
|
|
122
|
+
<li>Standard output
|
|
123
|
+
<dl class="message-properties">
|
|
124
|
+
<dt>payload <span class="property-type">string</span></dt>
|
|
125
|
+
<dd>the standard output of the command.</dd>
|
|
126
|
+
</dl>
|
|
127
|
+
</li>
|
|
128
|
+
</ol>
|
|
129
|
+
|
|
130
|
+
<h3>Details</h3>
|
|
131
|
+
<p>this node is used to authenticate to the service layer.
|
|
132
|
+
See the examples to understand how to use it.
|
|
133
|
+
</p>
|
|
134
|
+
<!-- <p><code>msg.payload</code> is used as the payload of the published message.
|
|
135
|
+
If it contains an Object it will be converted to a JSON string before being sent.
|
|
136
|
+
If it contains a binary Buffer the message will be published as-is.</p>
|
|
137
|
+
<p>The topic used can be configured in the node or, if left blank, can be set
|
|
138
|
+
by <code>msg.topic</code>.</p>
|
|
139
|
+
<p>Likewise the QoS and retain values can be configured in the node or, if left
|
|
140
|
+
blank, set by <code>msg.qos</code> and <code>msg.retain</code> respectively.</p> -->
|
|
141
|
+
|
|
142
|
+
<h3>References</h3>
|
|
143
|
+
<ul>
|
|
144
|
+
<li><a href="https://sap-samples.github.io/smb-summit-hackathon/b1sl.html" target="_black">Service layer API docs</a> - for more details </li>
|
|
145
|
+
<li><a href="https://github.com/yousolution-cloud/node-red-contrib-you-sap-service-layer">@yousolution-cloud/node-red-contrib-you-sap-service-layer</a> - the nodes github repository</li>
|
|
146
|
+
</ul>
|
|
147
147
|
</script>
|
package/nodes/authenticateSap.js
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
2
|
-
const Support = require('./support');
|
|
3
|
-
|
|
4
|
-
module.exports = function (RED) {
|
|
5
|
-
function AuthenticateSapNode(config) {
|
|
6
|
-
RED.nodes.createNode(this, config);
|
|
7
|
-
const node = this;
|
|
8
|
-
|
|
9
|
-
// reset status
|
|
10
|
-
node.status({});
|
|
11
|
-
|
|
12
|
-
const globalContext = node.context().global;
|
|
13
|
-
|
|
14
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}`, {
|
|
15
|
-
host: config.host,
|
|
16
|
-
port: config.port,
|
|
17
|
-
version: config.version,
|
|
18
|
-
credentials: {
|
|
19
|
-
CompanyDB: node.credentials.company,
|
|
20
|
-
UserName: node.credentials.user,
|
|
21
|
-
Password: node.credentials.password,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
if (!node.credentials.user || !node.credentials.company) {
|
|
26
|
-
node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials' });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
node.on('input', async (msg, send, done) => {
|
|
30
|
-
|
|
31
|
-
if(!node.credentials.password && !msg.password){
|
|
32
|
-
node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials Password Code' });
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if(msg.password){
|
|
36
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.Password`, msg.password);
|
|
37
|
-
//node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials Password Code' });
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// If Company setted from msg
|
|
41
|
-
if (node.credentials.companyType == 'msg') {
|
|
42
|
-
const company = msg[node.credentials.company];
|
|
43
|
-
let currentCompany = globalContext.get(`_YOU_SapServiceLayer_${node.id}.credentials.CompanyDB`);
|
|
44
|
-
|
|
45
|
-
if(company !== currentCompany) {
|
|
46
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, null);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.CompanyDB`, company);
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// If User setted from msg
|
|
54
|
-
if (node.credentials.userType == 'msg') {
|
|
55
|
-
const user = msg[node.credentials.user];
|
|
56
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.UserName`, user);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// reset status
|
|
60
|
-
node.status({});
|
|
61
|
-
|
|
62
|
-
if (!node.credentials.user || !node.credentials.company) {
|
|
63
|
-
node.status({ fill: 'red', shape: 'dot', text: 'Missing credentials' });
|
|
64
|
-
done(new Error('Missing credentials'));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let currentDate = new Date();
|
|
69
|
-
const headers = globalContext.get(`_YOU_SapServiceLayer_${node.id}.headers`);
|
|
70
|
-
const exipiredTime = globalContext.get(`_YOU_SapServiceLayer_${node.id}.exp`);
|
|
71
|
-
let validToken = true;
|
|
72
|
-
|
|
73
|
-
msg._YOU_SapServiceLayer = {
|
|
74
|
-
idAuth: node.id,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
if(headers && exipiredTime) {
|
|
78
|
-
let providedDate = new Date(exipiredTime);
|
|
79
|
-
let timeDifference = currentDate - providedDate;
|
|
80
|
-
let minutesDifference = timeDifference / (1000 * 60);
|
|
81
|
-
validToken = minutesDifference > 25 ? false : true;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (!headers || !validToken) {
|
|
86
|
-
try {
|
|
87
|
-
const result = await Support.login(node, node.id);
|
|
88
|
-
if(result.data.hasOwnProperty("error")) {
|
|
89
|
-
node.error( result.data.error , msg);
|
|
90
|
-
node.status({ fill: 'red', shape: 'dot', text: 'disconnected' });
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, result.headers['set-cookie']);
|
|
94
|
-
globalContext.set(`_YOU_SapServiceLayer_${node.id}.exp`, currentDate.toISOString());
|
|
95
|
-
node.send(msg);
|
|
96
|
-
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
|
|
97
|
-
}
|
|
98
|
-
// globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, result.headers['set-cookie']);
|
|
99
|
-
// globalContext.set(`_YOU_SapServiceLayer_${node.id}.exp`, currentDate.toISOString());
|
|
100
|
-
} catch (error) {
|
|
101
|
-
msg.payload = error;
|
|
102
|
-
if (error.response && error.response.data) {
|
|
103
|
-
msg.statusCode = error.response.status;
|
|
104
|
-
msg.payload = error.response.data;
|
|
105
|
-
}
|
|
106
|
-
node.error( error , msg);
|
|
107
|
-
//node.send(msg);
|
|
108
|
-
node.status({ fill: 'red', shape: 'dot', text: 'disconnected' });
|
|
109
|
-
done(error);
|
|
110
|
-
//return;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
node.send(msg);
|
|
115
|
-
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
RED.nodes.registerType('authenticateSap', AuthenticateSapNode, {
|
|
121
|
-
credentials: {
|
|
122
|
-
company: { type: 'text' },
|
|
123
|
-
companyType: { type: 'text' },
|
|
124
|
-
user: { type: 'text' },
|
|
125
|
-
userType: { type: 'text' },
|
|
126
|
-
password: { type: 'password' },
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
};
|
|
1
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
2
|
+
const Support = require('./support');
|
|
3
|
+
|
|
4
|
+
module.exports = function (RED) {
|
|
5
|
+
function AuthenticateSapNode(config) {
|
|
6
|
+
RED.nodes.createNode(this, config);
|
|
7
|
+
const node = this;
|
|
8
|
+
|
|
9
|
+
// reset status
|
|
10
|
+
node.status({});
|
|
11
|
+
|
|
12
|
+
const globalContext = node.context().global;
|
|
13
|
+
|
|
14
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}`, {
|
|
15
|
+
host: config.host,
|
|
16
|
+
port: config.port,
|
|
17
|
+
version: config.version,
|
|
18
|
+
credentials: {
|
|
19
|
+
CompanyDB: node.credentials.company,
|
|
20
|
+
UserName: node.credentials.user,
|
|
21
|
+
Password: node.credentials.password,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (!node.credentials.user || !node.credentials.company) {
|
|
26
|
+
node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials' });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
node.on('input', async (msg, send, done) => {
|
|
30
|
+
|
|
31
|
+
if(!node.credentials.password && !msg.password){
|
|
32
|
+
node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials Password Code' });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if(msg.password){
|
|
36
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.Password`, msg.password);
|
|
37
|
+
//node.status({ fill: 'gray', shape: 'ring', text: 'Missing credentials Password Code' });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// If Company setted from msg
|
|
41
|
+
if (node.credentials.companyType == 'msg') {
|
|
42
|
+
const company = msg[node.credentials.company];
|
|
43
|
+
let currentCompany = globalContext.get(`_YOU_SapServiceLayer_${node.id}.credentials.CompanyDB`);
|
|
44
|
+
|
|
45
|
+
if(company !== currentCompany) {
|
|
46
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, null);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.CompanyDB`, company);
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// If User setted from msg
|
|
54
|
+
if (node.credentials.userType == 'msg') {
|
|
55
|
+
const user = msg[node.credentials.user];
|
|
56
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.credentials.UserName`, user);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// reset status
|
|
60
|
+
node.status({});
|
|
61
|
+
|
|
62
|
+
if (!node.credentials.user || !node.credentials.company) {
|
|
63
|
+
node.status({ fill: 'red', shape: 'dot', text: 'Missing credentials' });
|
|
64
|
+
done(new Error('Missing credentials'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let currentDate = new Date();
|
|
69
|
+
const headers = globalContext.get(`_YOU_SapServiceLayer_${node.id}.headers`);
|
|
70
|
+
const exipiredTime = globalContext.get(`_YOU_SapServiceLayer_${node.id}.exp`);
|
|
71
|
+
let validToken = true;
|
|
72
|
+
|
|
73
|
+
msg._YOU_SapServiceLayer = {
|
|
74
|
+
idAuth: node.id,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
if(headers && exipiredTime) {
|
|
78
|
+
let providedDate = new Date(exipiredTime);
|
|
79
|
+
let timeDifference = currentDate - providedDate;
|
|
80
|
+
let minutesDifference = timeDifference / (1000 * 60);
|
|
81
|
+
validToken = minutesDifference > 25 ? false : true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if (!headers || !validToken) {
|
|
86
|
+
try {
|
|
87
|
+
const result = await Support.login(node, node.id);
|
|
88
|
+
if(result.data.hasOwnProperty("error")) {
|
|
89
|
+
node.error( result.data.error , msg);
|
|
90
|
+
node.status({ fill: 'red', shape: 'dot', text: 'disconnected' });
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, result.headers['set-cookie']);
|
|
94
|
+
globalContext.set(`_YOU_SapServiceLayer_${node.id}.exp`, currentDate.toISOString());
|
|
95
|
+
node.send(msg);
|
|
96
|
+
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
|
|
97
|
+
}
|
|
98
|
+
// globalContext.set(`_YOU_SapServiceLayer_${node.id}.headers`, result.headers['set-cookie']);
|
|
99
|
+
// globalContext.set(`_YOU_SapServiceLayer_${node.id}.exp`, currentDate.toISOString());
|
|
100
|
+
} catch (error) {
|
|
101
|
+
msg.payload = error;
|
|
102
|
+
if (error.response && error.response.data) {
|
|
103
|
+
msg.statusCode = error.response.status;
|
|
104
|
+
msg.payload = error.response.data;
|
|
105
|
+
}
|
|
106
|
+
node.error( error , msg);
|
|
107
|
+
//node.send(msg);
|
|
108
|
+
node.status({ fill: 'red', shape: 'dot', text: 'disconnected' });
|
|
109
|
+
done(error);
|
|
110
|
+
//return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
node.send(msg);
|
|
115
|
+
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
RED.nodes.registerType('authenticateSap', AuthenticateSapNode, {
|
|
121
|
+
credentials: {
|
|
122
|
+
company: { type: 'text' },
|
|
123
|
+
companyType: { type: 'text' },
|
|
124
|
+
user: { type: 'text' },
|
|
125
|
+
userType: { type: 'text' },
|
|
126
|
+
password: { type: 'password' },
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
};
|