@nsshunt/stsdatamanagement 1.10.0 → 1.10.1
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/.github/dependabot.yml +1 -8
- package/blcauth.js +98 -0
- package/databaseutils.js +101 -41
- package/package.json +6 -6
package/.github/dependabot.yml
CHANGED
|
@@ -10,11 +10,4 @@ updates:
|
|
|
10
10
|
- package-ecosystem: "npm" # See documentation for possible values
|
|
11
11
|
directory: "/" # Location of package manifests
|
|
12
12
|
schedule:
|
|
13
|
-
interval: "
|
|
14
|
-
|
|
15
|
-
- package-ecosystem: "github-actions"
|
|
16
|
-
# Workflow files stored in the
|
|
17
|
-
# default location of `.github/workflows`
|
|
18
|
-
directory: "/"
|
|
19
|
-
schedule:
|
|
20
|
-
interval: "weekly"
|
|
13
|
+
interval: "monthly"
|
package/blcauth.js
CHANGED
|
@@ -6,6 +6,8 @@ class BLCAuth
|
|
|
6
6
|
static SYSTEM_USER_ID = "STS_SYSTEM";
|
|
7
7
|
static USER_ID_PREFIX = "USR_";
|
|
8
8
|
static ROLE_ID_PREFIX = "ROLE_";
|
|
9
|
+
static APPLICATION_ID_PREFIX = "APP_";
|
|
10
|
+
static API_ID_PREFIX = "API_";
|
|
9
11
|
|
|
10
12
|
#accessLayer = null;
|
|
11
13
|
|
|
@@ -119,6 +121,102 @@ class BLCAuth
|
|
|
119
121
|
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
120
122
|
}
|
|
121
123
|
}
|
|
124
|
+
|
|
125
|
+
async AddApplication(application)
|
|
126
|
+
{
|
|
127
|
+
try
|
|
128
|
+
{
|
|
129
|
+
const { clientId } = application;
|
|
130
|
+
let applicationId = BLCAuth.APPLICATION_ID_PREFIX + clientId;
|
|
131
|
+
let existingApplication = await this.#accessLayer.getLatestResource(applicationId);
|
|
132
|
+
if (existingApplication.status === 200) {
|
|
133
|
+
return { status: status.conflict, error: 'Application already exists.', detail: { message: `Application already exists: [${applicationId}]` }};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let payload =
|
|
137
|
+
{
|
|
138
|
+
applicationId: applicationId,
|
|
139
|
+
...application
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, applicationId, payload);
|
|
143
|
+
|
|
144
|
+
// Client Secret is not returned. Seperate function used to display this field.
|
|
145
|
+
delete payload.clientSecret;
|
|
146
|
+
|
|
147
|
+
return { status: status.success, detail: payload };
|
|
148
|
+
} catch (error)
|
|
149
|
+
{
|
|
150
|
+
console.error(error);
|
|
151
|
+
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async AddAPI(api)
|
|
156
|
+
{
|
|
157
|
+
try
|
|
158
|
+
{
|
|
159
|
+
const { APIId, M2MApplications, permissions } = api;
|
|
160
|
+
let APIidentifier = BLCAuth.API_ID_PREFIX + APIId;
|
|
161
|
+
let existingAPI = await this.#accessLayer.getLatestResource(APIidentifier);
|
|
162
|
+
if (existingAPI.status === 200) {
|
|
163
|
+
return { status: status.conflict, error: 'API already exists.', detail: { message: `API already exists: [${APIidentifier}]` }};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Validate M2MApplications
|
|
167
|
+
for (let i=0; i < M2MApplications.length; i++) {
|
|
168
|
+
const m2mapplication = M2MApplications[i];
|
|
169
|
+
let appid = BLCAuth.APPLICATION_ID_PREFIX + m2mapplication.clientId;
|
|
170
|
+
let retVal = await this.#accessLayer.getLatestResource(appid);
|
|
171
|
+
if (retVal.status !== 200) {
|
|
172
|
+
return { status: status.notfound , error: 'Cannot find client application.', detail: { message: `Cannot find client application: [${appid}].` }};
|
|
173
|
+
}
|
|
174
|
+
let applicationResource = JSON.parse(retVal.detail.resdesc);
|
|
175
|
+
if (applicationResource.clientName.localeCompare(m2mapplication.clientName) !== 0) {
|
|
176
|
+
return { status: status.error, error: 'clientName mismatch.', detail: { message: `clientName mismatch: Value: [${m2mapplication.clientName}], Expecting: [${applicationResource.clientName}]` }};
|
|
177
|
+
}
|
|
178
|
+
for (let j=0; j < m2mapplication.permissions.length; j++) {
|
|
179
|
+
const permission = m2mapplication.permissions[j];
|
|
180
|
+
if (!permissions.includes(permission)) {
|
|
181
|
+
return { status: status.error, error: 'M2M permission not found within API available permission list.', detail: { message: `M2M permission not found within API available permission list: [${permission}]` }};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Client Secret is not returned. Seperate function used to display this field.
|
|
187
|
+
let payload =
|
|
188
|
+
{
|
|
189
|
+
APIidentifier: APIidentifier,
|
|
190
|
+
...api
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
await this.#accessLayer.saveResource(BLCAuth.SYSTEM_USER_ID, APIidentifier, payload);
|
|
194
|
+
|
|
195
|
+
return { status: status.success, detail: payload };
|
|
196
|
+
} catch (error)
|
|
197
|
+
{
|
|
198
|
+
console.error(error);
|
|
199
|
+
throw new Error({ status: status.error, error: 'Operation was not successful', detail: error });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async GetApplication(clientId) {
|
|
204
|
+
let clientIdentifier = BLCAuth.APPLICATION_ID_PREFIX + clientId;
|
|
205
|
+
let application = await this.#accessLayer.getLatestResource(clientIdentifier);
|
|
206
|
+
if (application.status !== 200) {
|
|
207
|
+
return { status: status.notfound, error: 'Application not found.', detail: { message: `Application not found: [${clientId}]` }};
|
|
208
|
+
}
|
|
209
|
+
return application;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async GetAPI(APIId) {
|
|
213
|
+
let APIidentifier = BLCAuth.API_ID_PREFIX + APIId;
|
|
214
|
+
let api = await this.#accessLayer.getLatestResource(APIidentifier);
|
|
215
|
+
if (api.status !== 200) {
|
|
216
|
+
return { status: status.notfound, error: 'API not found.', detail: { message: `API not found: [${APIId}]` }};
|
|
217
|
+
}
|
|
218
|
+
return api;
|
|
219
|
+
}
|
|
122
220
|
}
|
|
123
221
|
|
|
124
222
|
module.exports = { BLCAuth };
|
package/databaseutils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const prompts = require('prompts');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
require('colors');
|
|
4
|
+
let crypto = require('crypto');
|
|
4
5
|
|
|
5
6
|
const goptions = require('@nsshunt/stsconfig').$options;
|
|
6
7
|
|
|
@@ -22,22 +23,93 @@ class DatabaseUtils
|
|
|
22
23
|
this.#accessLayer = accessLayer;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
#_RegisterRolesAndPermissions = async(blcauth) => {
|
|
27
|
+
this.#debug(`Registering Roles and Role Permissions.`.yellow);
|
|
28
|
+
console.log(`Registering Roles and Role Permissions.`.yellow);
|
|
29
|
+
const rolePermissionFile = goptions.databasescriptfolder + '/role-permission.json'
|
|
30
|
+
const rawdata = fs.readFileSync(rolePermissionFile);
|
|
31
|
+
let rolePermissions = JSON.parse(rawdata);
|
|
32
|
+
for (const [, rolePermission] of Object.entries(rolePermissions)) {
|
|
33
|
+
let retVal = await blcauth.AddRolePermissions(rolePermission);
|
|
34
|
+
if (retVal.status !== 200) {
|
|
35
|
+
console.log(`Role Permission registered: ${JSON.stringify(retVal)}`.red);
|
|
36
|
+
return false;
|
|
37
|
+
} else {
|
|
38
|
+
console.log(`Role Permission registered: ${JSON.stringify(retVal)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#_RegisterUsersAndRoles = async(blcauth) => {
|
|
45
|
+
this.#debug(`Registering Users and Roles.`.yellow);
|
|
46
|
+
console.log(`Registering Users and Roles.`.yellow);
|
|
47
|
+
const roleFile = goptions.databasescriptfolder + '/user-role.json'
|
|
48
|
+
let rawdata = fs.readFileSync(roleFile);
|
|
49
|
+
let userroles = JSON.parse(rawdata);
|
|
50
|
+
for (const [, user] of Object.entries(userroles)) {
|
|
51
|
+
let retVal = await blcauth.AddUser(user);
|
|
52
|
+
if (retVal.status !== 200) {
|
|
53
|
+
console.log(`Role registered: ${JSON.stringify(retVal)}`.red);
|
|
54
|
+
return false;
|
|
55
|
+
} else {
|
|
56
|
+
console.log(`Role registered: ${JSON.stringify(retVal)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#_RegisterApplications = async(blcauth) => {
|
|
63
|
+
this.#debug(`Registering Applications.`.yellow);
|
|
64
|
+
console.log(`Registering Applications.`.yellow);
|
|
65
|
+
const roleFile = goptions.databasescriptfolder + '/applications.json'
|
|
66
|
+
let rawdata = fs.readFileSync(roleFile);
|
|
67
|
+
let applications = JSON.parse(rawdata);
|
|
68
|
+
for (const [, application] of Object.entries(applications)) {
|
|
69
|
+
application.clientSecret = crypto.randomBytes(32).toString('base64');
|
|
70
|
+
let retVal = await blcauth.AddApplication(application);
|
|
71
|
+
if (retVal.status !== 200) {
|
|
72
|
+
console.log(`Application registered: ${JSON.stringify(retVal)}`.red);
|
|
73
|
+
return false;
|
|
74
|
+
} else {
|
|
75
|
+
console.log(`Application registered: ${JSON.stringify(retVal)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#_RegisterAPIs = async(blcauth) => {
|
|
82
|
+
this.#debug(`Registering APIs.`.yellow);
|
|
83
|
+
console.log(`Registering APIs.`.yellow);
|
|
84
|
+
const roleFile = goptions.databasescriptfolder + '/apis.json'
|
|
85
|
+
let rawdata = fs.readFileSync(roleFile);
|
|
86
|
+
let apis = JSON.parse(rawdata);
|
|
87
|
+
for (const [, api] of Object.entries(apis)) {
|
|
88
|
+
let retVal = await blcauth.AddAPI(api);
|
|
89
|
+
if (retVal.status !== 200) {
|
|
90
|
+
console.log(`API registered: ${JSON.stringify(retVal)}`.red);
|
|
91
|
+
return false;
|
|
92
|
+
} else {
|
|
93
|
+
console.log(`API registered: ${JSON.stringify(retVal)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
25
99
|
// options ::= { start: <int>, entries: <int>, minextradata: <int>, maxextradata: <int>,
|
|
26
100
|
// user: { name: <string>, password: <string>, email: <string> } }
|
|
27
|
-
|
|
101
|
+
createfreshdatabase = async (options) =>
|
|
28
102
|
{
|
|
29
|
-
let ns = `proc:${process.pid}:DatabaseUtils`; // namespace for debug
|
|
30
|
-
let debug = require('debug')(ns);
|
|
31
103
|
let fname = 'createfreshdatabase';
|
|
32
104
|
const { start, entries, minextradata, maxextradata } = options;
|
|
33
105
|
let builddbscript = goptions.databasescriptfolder + '/builddb.sql'
|
|
34
|
-
debug(`Database Build Script: [${builddbscript}]`.yellow);
|
|
106
|
+
this.#debug(`Database Build Script: [${builddbscript}]`.yellow);
|
|
35
107
|
|
|
36
108
|
try
|
|
37
109
|
{
|
|
38
110
|
try
|
|
39
111
|
{
|
|
40
|
-
debug(`Dropping database.`.yellow);
|
|
112
|
+
this.#debug(`Dropping database.`.yellow);
|
|
41
113
|
await PGUtils.dropdatabase();
|
|
42
114
|
} catch (error)
|
|
43
115
|
{
|
|
@@ -46,66 +118,54 @@ class DatabaseUtils
|
|
|
46
118
|
}
|
|
47
119
|
|
|
48
120
|
// Create a new empty database
|
|
49
|
-
debug(`Creating new empty database.`.yellow);
|
|
121
|
+
this.#debug(`Creating new empty database.`.yellow);
|
|
50
122
|
await PGUtils.createdatabase();
|
|
51
123
|
|
|
52
124
|
let localAccesslayer = new PGAccessLayer(new PGPoolManager());
|
|
53
125
|
|
|
54
126
|
// Build the database assets (tables, functions, etc.)
|
|
55
|
-
debug(`Building database assets (tables, functions, etc.).`.yellow);
|
|
127
|
+
this.#debug(`Building database assets (tables, functions, etc.).`.yellow);
|
|
56
128
|
await localAccesslayer.executedbscript(builddbscript);
|
|
57
129
|
|
|
58
130
|
if (typeof entries !== 'undefined') {
|
|
59
131
|
// Add new faker entries
|
|
60
|
-
debug(`Adding test data.`.yellow);
|
|
132
|
+
this.#debug(`Adding test data.`.yellow);
|
|
61
133
|
let dg = new DataGenerator(localAccesslayer);
|
|
62
134
|
await dg.RunAddFakerBulkInsert(start, entries, minextradata, maxextradata);
|
|
63
135
|
}
|
|
64
136
|
|
|
65
137
|
const blcauth = new BLCAuth(localAccesslayer);
|
|
138
|
+
let status = true;
|
|
66
139
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const userFile = goptions.databasescriptfolder + '/users.json'
|
|
71
|
-
let rawdata = fs.readFileSync(userFile);
|
|
72
|
-
let users = JSON.parse(rawdata);
|
|
73
|
-
for (const [, user] of Object.entries(users)) {
|
|
74
|
-
let retVal = await blcauth.registeruser(user);
|
|
75
|
-
console.log(`User registered: ${JSON.stringify(retVal)}`);
|
|
140
|
+
status = await this.#_RegisterUsersAndRoles(blcauth);
|
|
141
|
+
if (status) {
|
|
142
|
+
status = await this.#_RegisterRolesAndPermissions(blcauth);
|
|
76
143
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
debug(`Registering Users and Roles.`.yellow);
|
|
80
|
-
console.log(`Registering Users and Roles.`.yellow);
|
|
81
|
-
const roleFile = goptions.databasescriptfolder + '/user-role.json'
|
|
82
|
-
let rawdata = fs.readFileSync(roleFile);
|
|
83
|
-
let userroles = JSON.parse(rawdata);
|
|
84
|
-
for (const [, user] of Object.entries(userroles)) {
|
|
85
|
-
let retVal = await blcauth.AddUser(user);
|
|
86
|
-
console.log(`Role registered: ${JSON.stringify(retVal)}`);
|
|
144
|
+
if (status) {
|
|
145
|
+
status = await this.#_RegisterApplications(blcauth);
|
|
87
146
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.log(`Registering Roles and Role Permissions.`.yellow);
|
|
91
|
-
const rolePermissionFile = goptions.databasescriptfolder + '/role-permission.json'
|
|
92
|
-
rawdata = fs.readFileSync(rolePermissionFile);
|
|
93
|
-
let rolePermissions = JSON.parse(rawdata);
|
|
94
|
-
for (const [, rolePermission] of Object.entries(rolePermissions)) {
|
|
95
|
-
let retVal = await blcauth.AddRolePermissions(rolePermission);
|
|
96
|
-
console.log(`Role Permission registered: ${JSON.stringify(retVal)}`);
|
|
147
|
+
if (status) {
|
|
148
|
+
status = await this.#_RegisterAPIs(blcauth);
|
|
97
149
|
}
|
|
98
150
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
151
|
+
if (status) {
|
|
152
|
+
let retVal = await blcauth.GetUserPermissions('STSREST01ServiceUser@stsmda.com');
|
|
153
|
+
console.log(`User Permissions: ${JSON.stringify(retVal)}`);
|
|
154
|
+
}
|
|
102
155
|
|
|
103
156
|
localAccesslayer.enddatabase();
|
|
104
|
-
|
|
157
|
+
|
|
158
|
+
if (status) {
|
|
159
|
+
this.#debug(`Database successfully initiailized.`.green);
|
|
160
|
+
console.log(`Database successfully initiailized.`.green);
|
|
161
|
+
} else {
|
|
162
|
+
this.#debug(`Database did not initiailize correctly.`.red);
|
|
163
|
+
console.log(`Database did not initiailize correctly.`.red);
|
|
164
|
+
}
|
|
105
165
|
} catch (error)
|
|
106
166
|
{
|
|
107
167
|
console.error(`[${fname}]: Could not create fresh database: ${error}`);
|
|
108
|
-
debug(`[${fname}]: Could not create fresh database: ${error}`);
|
|
168
|
+
this.#debug(`[${fname}]: Could not create fresh database: ${error}`);
|
|
109
169
|
}
|
|
110
170
|
};
|
|
111
171
|
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nsshunt/stsdatamanagement",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "STS Data Management Modules, Utilities and Services",
|
|
5
5
|
"main": "dbaccess.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@nsshunt/stsconfig": "^1.
|
|
7
|
+
"@nsshunt/stsconfig": "^1.17.1",
|
|
8
8
|
"@nsshunt/stsinstrumentation": "^6.4.2",
|
|
9
|
-
"@nsshunt/stsutils": "^1.7.
|
|
9
|
+
"@nsshunt/stsutils": "^1.7.5",
|
|
10
10
|
"axios": "^0.26.0",
|
|
11
11
|
"bcryptjs": "^2.4.3",
|
|
12
12
|
"cli-progress": "^3.10.0",
|
|
13
13
|
"colors": "^1.4.0",
|
|
14
|
-
"debug": "^4.3.
|
|
14
|
+
"debug": "^4.3.4",
|
|
15
15
|
"ioredis": "^4.28.5",
|
|
16
16
|
"pg": "^8.7.3",
|
|
17
17
|
"pg-copy-streams": "^6.0.2",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"parser": "@babel/eslint-parser"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@babel/core": "^7.17.
|
|
30
|
+
"@babel/core": "^7.17.8",
|
|
31
31
|
"@babel/eslint-parser": "^7.17.0",
|
|
32
32
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
33
33
|
"@babel/plugin-proposal-private-methods": "^7.16.11",
|
|
34
|
-
"eslint": "^8.
|
|
34
|
+
"eslint": "^8.11.0",
|
|
35
35
|
"jest": "^27.5.1"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|