@nsshunt/stsappframework 2.19.173 → 2.19.174
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/workflows/npm-publish.yml +2 -2
- package/dist/authutilsnode.js +152 -178
- package/dist/authutilsnode.js.map +1 -1
- package/dist/masterprocessbase.js +454 -484
- package/dist/masterprocessbase.js.map +1 -1
- package/dist/processbase.js +161 -180
- package/dist/processbase.js.map +1 -1
- package/dist/server.js +3 -16
- package/dist/server.js.map +1 -1
- package/dist/singleprocessbase.js +216 -240
- package/dist/singleprocessbase.js.map +1 -1
- package/dist/socketioHelper.js +132 -145
- package/dist/socketioHelper.js.map +1 -1
- package/dist/stscontrollerbase.js +3 -16
- package/dist/stscontrollerbase.js.map +1 -1
- package/dist/stslatencycontroller.js +9 -20
- package/dist/stslatencycontroller.js.map +1 -1
- package/dist/stsrouterbase.js +6 -19
- package/dist/stsrouterbase.js.map +1 -1
- package/dist/testHelpers.js +238 -262
- package/dist/testHelpers.js.map +1 -1
- package/dist/workerprocessbase.js +297 -321
- package/dist/workerprocessbase.js.map +1 -1
- package/dist/workerprocessbase.test.js +2 -11
- package/dist/workerprocessbase.test.js.map +1 -1
- package/package.json +8 -7
- package/tsconfig.json +28 -9
package/dist/testHelpers.js
CHANGED
|
@@ -22,30 +22,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
35
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
36
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
37
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
38
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
39
|
-
};
|
|
40
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
41
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
42
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
43
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
44
|
-
};
|
|
45
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
27
|
};
|
|
48
|
-
var _TestHelper_regexURLSafeStringComponent, _TestHelper_regexSTSBase64, _TestHelper_regexJWT, _TestHelper_authUtilsNode, _TestHelper_databaseContainer, _TestHelper_stsAuthContainer, _TestHelper_network, _TestHelper_authEndpoint, _TestHelper_authPort, _TestHelper_authHost, _TestHelper_httpsAgent, _TestHelper_GetHttpsAgent;
|
|
49
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
29
|
exports.TestHelper = void 0;
|
|
51
30
|
const debug_1 = __importDefault(require("debug"));
|
|
@@ -61,259 +40,256 @@ let goptions = (0, stsconfig_1.$Options)();
|
|
|
61
40
|
const stsutils_1 = require("@nsshunt/stsutils");
|
|
62
41
|
const authutilsnode_1 = require("./authutilsnode");
|
|
63
42
|
class TestHelper {
|
|
43
|
+
//#regexBase64URL = /^[A-Za-z0-9_-]+$/ // Base64URL - https://base64.guru/standards/base64url
|
|
44
|
+
#regexURLSafeStringComponent = /[-a-zA-Z0-9@:%._+~#=]{1,256}/; // URL safe string component
|
|
45
|
+
//#regexBase64 = /(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/ // Base64 - https://stackoverflow.com/questions/475074/regex-to-parse-or-validate-base64-data
|
|
46
|
+
#regexSTSBase64 = /SES_(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/; // Base64
|
|
47
|
+
#regexJWT = /[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/; // JWT (Base64URL.Base64URL.Base64URL)
|
|
48
|
+
#authUtilsNode = new authutilsnode_1.AuthUtilsNode();
|
|
49
|
+
#databaseContainer;
|
|
50
|
+
#stsAuthContainer;
|
|
51
|
+
#network;
|
|
52
|
+
#authEndpoint = '';
|
|
53
|
+
#authPort = '';
|
|
54
|
+
#authHost = '';
|
|
55
|
+
#httpsAgent = null;
|
|
64
56
|
constructor() {
|
|
65
|
-
|
|
66
|
-
_TestHelper_regexURLSafeStringComponent.set(this, /[-a-zA-Z0-9@:%._+~#=]{1,256}/
|
|
67
|
-
//#regexBase64 = /(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/ // Base64 - https://stackoverflow.com/questions/475074/regex-to-parse-or-validate-base64-data
|
|
68
|
-
); // URL safe string component
|
|
69
|
-
//#regexBase64 = /(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/ // Base64 - https://stackoverflow.com/questions/475074/regex-to-parse-or-validate-base64-data
|
|
70
|
-
_TestHelper_regexSTSBase64.set(this, /SES_(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/); // Base64
|
|
71
|
-
_TestHelper_regexJWT.set(this, /[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/); // JWT (Base64URL.Base64URL.Base64URL)
|
|
72
|
-
_TestHelper_authUtilsNode.set(this, new authutilsnode_1.AuthUtilsNode());
|
|
73
|
-
_TestHelper_databaseContainer.set(this, void 0);
|
|
74
|
-
_TestHelper_stsAuthContainer.set(this, void 0);
|
|
75
|
-
_TestHelper_network.set(this, void 0);
|
|
76
|
-
_TestHelper_authEndpoint.set(this, '');
|
|
77
|
-
_TestHelper_authPort.set(this, '');
|
|
78
|
-
_TestHelper_authHost.set(this, '');
|
|
79
|
-
_TestHelper_httpsAgent.set(this, null);
|
|
80
|
-
_TestHelper_GetHttpsAgent.set(this, () => {
|
|
81
|
-
if (__classPrivateFieldGet(this, _TestHelper_httpsAgent, "f") === null) {
|
|
82
|
-
// https://nodejs.org/api/http.html#class-httpagent
|
|
83
|
-
__classPrivateFieldSet(this, _TestHelper_httpsAgent, new https_1.default.Agent({
|
|
84
|
-
keepAlive: goptions.keepAlive,
|
|
85
|
-
maxSockets: goptions.maxSockets,
|
|
86
|
-
maxTotalSockets: goptions.maxTotalSockets,
|
|
87
|
-
maxFreeSockets: goptions.maxFreeSockets,
|
|
88
|
-
timeout: goptions.timeout,
|
|
89
|
-
rejectUnauthorized: false
|
|
90
|
-
}), "f");
|
|
91
|
-
}
|
|
92
|
-
return __classPrivateFieldGet(this, _TestHelper_httpsAgent, "f");
|
|
93
|
-
});
|
|
94
|
-
this.StartNetwork = () => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
__classPrivateFieldSet(this, _TestHelper_network, yield new testcontainers_1.Network().start(), "f");
|
|
96
|
-
});
|
|
97
|
-
this.StopNetwork = () => __awaiter(this, void 0, void 0, function* () {
|
|
98
|
-
yield __classPrivateFieldGet(this, _TestHelper_network, "f").stop();
|
|
99
|
-
});
|
|
100
|
-
this.CreateRandomString = () => {
|
|
101
|
-
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.'; // /[0-9A-Za-z\-_~.]/
|
|
102
|
-
let random = '';
|
|
103
|
-
const randomValues = Array.from(crypto_1.default.getRandomValues(new Uint8Array(43)));
|
|
104
|
-
randomValues.forEach(v => (random += charset[v % charset.length]));
|
|
105
|
-
return random;
|
|
106
|
-
};
|
|
107
|
-
this.Login = (username, password) => __awaiter(this, void 0, void 0, function* () {
|
|
108
|
-
const client_id = process.env.CLIENT_ID;
|
|
109
|
-
const nonce = crypto_1.default.randomBytes(43).toString('base64'); //CreateRandomString();
|
|
110
|
-
const response_type = 'code';
|
|
111
|
-
const redirect_uri = process.env.REDIRECT_URI;
|
|
112
|
-
const response_mode = 'query';
|
|
113
|
-
const scope = process.env.SCOPE;
|
|
114
|
-
const state = crypto_1.default.randomBytes(43).toString('base64'); // CreateRandomString();
|
|
115
|
-
const code_verifier = this.CreateRandomString();
|
|
116
|
-
const code_challenge = crypto_1.default.createHash('sha256').update(code_verifier).digest('base64');
|
|
117
|
-
const code_challenge_method = 'S256';
|
|
118
|
-
const authoriseOptions = {
|
|
119
|
-
email: username,
|
|
120
|
-
password,
|
|
121
|
-
client_id,
|
|
122
|
-
nonce,
|
|
123
|
-
response_type,
|
|
124
|
-
redirect_uri,
|
|
125
|
-
response_mode,
|
|
126
|
-
scope,
|
|
127
|
-
state,
|
|
128
|
-
code_challenge,
|
|
129
|
-
code_challenge_method
|
|
130
|
-
};
|
|
131
|
-
const url = `${__classPrivateFieldGet(this, _TestHelper_authEndpoint, "f")}${goptions.asapiroot}/login`;
|
|
132
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
133
|
-
const retVal = yield (0, axios_1.default)({
|
|
134
|
-
url,
|
|
135
|
-
method: 'post',
|
|
136
|
-
data: authoriseOptions,
|
|
137
|
-
headers: headers,
|
|
138
|
-
httpsAgent: __classPrivateFieldGet(this, _TestHelper_GetHttpsAgent, "f").call(this)
|
|
139
|
-
});
|
|
140
|
-
//const cookieString = retVal.headers['set-cookie'];
|
|
141
|
-
/*
|
|
142
|
-
const api = request(this.#endpoint);
|
|
143
|
-
const retVal: any = await (api as any)
|
|
144
|
-
.post(`${goptions.asapiroot}/login`)
|
|
145
|
-
.send(authoriseOptions)
|
|
146
|
-
//.expect('set-cookie', /consent_cookie=.*; Max-Age=86; Path=\/; Expires=.*; HttpOnly; Secure; SameSite=Strict/);
|
|
147
|
-
|
|
148
|
-
const cookieString = retVal.header['set-cookie'];
|
|
149
|
-
|
|
150
|
-
if (cookieString) {
|
|
151
|
-
retVal.cookie = new Cookie(cookieString[0]);
|
|
152
|
-
}
|
|
153
|
-
*/
|
|
154
|
-
return retVal;
|
|
155
|
-
});
|
|
156
|
-
this.GetAuthServerAPITokenFromServer = () => __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
return yield __classPrivateFieldGet(this, _TestHelper_authUtilsNode, "f").GetAPITokenFromAuthServer(authutilsnode_1.STSClientID.STSTestingService, "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==", goptions.asapiidentifier, __classPrivateFieldGet(this, _TestHelper_authEndpoint, "f"));
|
|
158
|
-
});
|
|
159
|
-
this.ValidateJWT = (token) => __awaiter(this, void 0, void 0, function* () {
|
|
160
|
-
return yield __classPrivateFieldGet(this, _TestHelper_authUtilsNode, "f").ValidateJWT(token, goptions.asapiidentifier, __classPrivateFieldGet(this, _TestHelper_authEndpoint, "f"));
|
|
161
|
-
});
|
|
162
|
-
this.StartDatabase = () => __awaiter(this, void 0, void 0, function* () {
|
|
163
|
-
__classPrivateFieldSet(this, _TestHelper_databaseContainer, yield new testcontainers_1.GenericContainer("postgres")
|
|
164
|
-
.withExposedPorts(5432)
|
|
165
|
-
.withEnvironment({
|
|
166
|
-
POSTGRES_PASSWORD: "postgres",
|
|
167
|
-
//UV_THREADPOOL_SIZE: "64"
|
|
168
|
-
})
|
|
169
|
-
.withNetwork(__classPrivateFieldGet(this, _TestHelper_network, "f"))
|
|
170
|
-
.withNetworkAliases("database")
|
|
171
|
-
.start(), "f");
|
|
172
|
-
const httpPort = __classPrivateFieldGet(this, _TestHelper_databaseContainer, "f").getMappedPort(5432);
|
|
173
|
-
const host = __classPrivateFieldGet(this, _TestHelper_databaseContainer, "f").getHost();
|
|
174
|
-
const networkIpAddress = __classPrivateFieldGet(this, _TestHelper_databaseContainer, "f").getIpAddress(__classPrivateFieldGet(this, _TestHelper_network, "f").getName());
|
|
175
|
-
process.env.DB_PORT = httpPort;
|
|
176
|
-
process.env.DB_HOST = host;
|
|
177
|
-
(0, stsconfig_1.$ResetOptions)();
|
|
178
|
-
goptions = (0, stsconfig_1.$Options)();
|
|
179
|
-
debug(`httpPort: [${httpPort}]`.green);
|
|
180
|
-
debug(`host: [${host}]`.green);
|
|
181
|
-
debug(`networkIpAddress: [${networkIpAddress}]`.green);
|
|
182
|
-
debug(`connectionString: [${goptions.connectionString}]`.green);
|
|
183
|
-
debug(`defaultDatabaseConnectionString: [${goptions.defaultDatabaseConnectionString}]`.green);
|
|
184
|
-
});
|
|
185
|
-
this.StopDatabase = () => __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
if (__classPrivateFieldGet(this, _TestHelper_databaseContainer, "f")) {
|
|
187
|
-
yield __classPrivateFieldGet(this, _TestHelper_databaseContainer, "f").stop();
|
|
188
|
-
debug(`Used the following parameters for the database during testing:`.yellow);
|
|
189
|
-
debug(`connectionString: [${goptions.connectionString}]`.yellow);
|
|
190
|
-
debug(`defaultDatabaseConnectionString: [${goptions.defaultDatabaseConnectionString}]`.yellow);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
// Note: .withCopyFilesToContainer and .withCopyContentToContainer have a defect in that Jest will not close. A file handle/stream is left open
|
|
194
|
-
// within the underlying code.
|
|
195
|
-
this.InitializeDatabase = () => __awaiter(this, void 0, void 0, function* () {
|
|
196
|
-
const stsAuthContainerInit = yield new testcontainers_1.GenericContainer("serza/stsauth:latest")
|
|
197
|
-
.withEnvironment({
|
|
198
|
-
DB_USER: "postgres",
|
|
199
|
-
DB_PASSWORD: "postgres",
|
|
200
|
-
DB_HOST: "database",
|
|
201
|
-
DB_PORT: "5432",
|
|
202
|
-
POOL_SIZE: "50",
|
|
203
|
-
MAX_CPU: "2",
|
|
204
|
-
DEBUG: "proc*",
|
|
205
|
-
HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
|
|
206
|
-
HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
|
|
207
|
-
AS_CLIENT_ID: "q6a9F0kksXDDcrsCUKRwHKDnTNh7yZfxCShAgIJqfGg=",
|
|
208
|
-
AS_CLIENT_SECRET: "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
|
|
209
|
-
AS_ENDPOINT: "https://stscore.stsmda.org"
|
|
210
|
-
})
|
|
211
|
-
.withCommand(["node", "dist/app", "create"])
|
|
212
|
-
.withNetwork(__classPrivateFieldGet(this, _TestHelper_network, "f"))
|
|
213
|
-
.withNetworkAliases("stsauthrunnerinit")
|
|
214
|
-
.withWaitStrategy(testcontainers_1.Wait.forLogMessage(`User Permissions: {"status":200,"detail":["STSREST01ReadPermission","STSREST01CreatePermission","STSREST01UpdatePermission","STSREST01DeletePermission"]}`))
|
|
215
|
-
.start();
|
|
216
|
-
yield (0, stsutils_1.Sleep)(200);
|
|
217
|
-
yield stsAuthContainerInit.stop();
|
|
218
|
-
});
|
|
219
|
-
this.StartAuthService = () => __awaiter(this, void 0, void 0, function* () {
|
|
220
|
-
__classPrivateFieldSet(this, _TestHelper_stsAuthContainer, yield new testcontainers_1.GenericContainer("serza/stsauth:latest")
|
|
221
|
-
.withExposedPorts(3002)
|
|
222
|
-
.withEnvironment({
|
|
223
|
-
DB_USER: "postgres",
|
|
224
|
-
DB_PASSWORD: "postgres",
|
|
225
|
-
DB_HOST: "database",
|
|
226
|
-
DB_PORT: "5432",
|
|
227
|
-
POOL_SIZE: "50",
|
|
228
|
-
MAX_CPU: "2",
|
|
229
|
-
DEBUG: "proc*",
|
|
230
|
-
HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
|
|
231
|
-
HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
|
|
232
|
-
AS_CLIENT_ID: "q6a9F0kksXDDcrsCUKRwHKDnTNh7yZfxCShAgIJqfGg=",
|
|
233
|
-
AS_CLIENT_SECRET: "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
|
|
234
|
-
AS_ENDPOINT: "https://stscore.stsmda.org"
|
|
235
|
-
})
|
|
236
|
-
.withNetwork(__classPrivateFieldGet(this, _TestHelper_network, "f"))
|
|
237
|
-
.withNetworkAliases("stsauthrunner")
|
|
238
|
-
.withWaitStrategy(testcontainers_1.Wait.forHttp("/stsauth/v1.0/latency", 3002).usingTls().allowInsecure())
|
|
239
|
-
.start(), "f");
|
|
240
|
-
const httpAuthPort = __classPrivateFieldGet(this, _TestHelper_stsAuthContainer, "f").getMappedPort(3002);
|
|
241
|
-
yield (0, stsutils_1.Sleep)(200);
|
|
242
|
-
debug(`-------------------------------------------------------------------------------------------`.green);
|
|
243
|
-
debug(` *** STSAuth Started ***: [${httpAuthPort}]`.green);
|
|
244
|
-
debug(`-------------------------------------------------------------------------------------------`.green);
|
|
245
|
-
__classPrivateFieldSet(this, _TestHelper_authHost, 'https://localhost', "f");
|
|
246
|
-
__classPrivateFieldSet(this, _TestHelper_authPort, httpAuthPort, "f");
|
|
247
|
-
__classPrivateFieldSet(this, _TestHelper_authEndpoint, `${__classPrivateFieldGet(this, _TestHelper_authHost, "f")}:${__classPrivateFieldGet(this, _TestHelper_authPort, "f")}`, "f");
|
|
248
|
-
});
|
|
249
|
-
this.StopAuthService = () => __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
if (__classPrivateFieldGet(this, _TestHelper_stsAuthContainer, "f")) {
|
|
251
|
-
yield __classPrivateFieldGet(this, _TestHelper_stsAuthContainer, "f").stop();
|
|
252
|
-
yield (0, stsutils_1.Sleep)(200);
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
this.TestLoginAndVerify = () => __awaiter(this, void 0, void 0, function* () {
|
|
256
|
-
expect.assertions(4);
|
|
257
|
-
const retVal = yield this.Login('user01@stsmda.com.au', 'user01password');
|
|
258
|
-
expect(retVal.status).toEqual(200);
|
|
259
|
-
debug(`${JSON.stringify(retVal.data)}`.red);
|
|
260
|
-
debug(`${JSON.stringify(retVal.headers)}`.magenta);
|
|
261
|
-
debug(`${JSON.stringify(retVal.headers['set-cookie'])}`.yellow);
|
|
262
|
-
const cookies = retVal.headers['set-cookie'];
|
|
263
|
-
debug(`${cookies[0]}`.yellow);
|
|
264
|
-
debug(`${JSON.stringify(tough.Cookie.parse(cookies[0]))}`.green);
|
|
265
|
-
const cookie = tough.Cookie.parse(cookies[0]);
|
|
266
|
-
const desiredCookieResultAxios = {
|
|
267
|
-
key: 'consent_cookie',
|
|
268
|
-
value: expect.stringMatching(__classPrivateFieldGet(this, _TestHelper_regexURLSafeStringComponent, "f")),
|
|
269
|
-
path: '/',
|
|
270
|
-
secure: true,
|
|
271
|
-
httpOnly: true,
|
|
272
|
-
sameSite: 'strict',
|
|
273
|
-
};
|
|
274
|
-
const cookieResult = JSON.parse(JSON.stringify(cookie));
|
|
275
|
-
expect(cookieResult).toMatchObject(desiredCookieResultAxios);
|
|
276
|
-
const cookieExpireDate = new Date(cookie.expires);
|
|
277
|
-
expect(cookieExpireDate).toBeAfter(new Date());
|
|
278
|
-
const desiredResult = {
|
|
279
|
-
sessionId: expect.stringMatching(__classPrivateFieldGet(this, _TestHelper_regexSTSBase64, "f")),
|
|
280
|
-
id_token: expect.stringMatching(__classPrivateFieldGet(this, _TestHelper_regexJWT, "f")),
|
|
281
|
-
consentRequired: ['res01.create', 'res01.read', 'res01.update', 'res01.delete']
|
|
282
|
-
};
|
|
283
|
-
expect(retVal.data.detail).toMatchObject(desiredResult);
|
|
284
|
-
});
|
|
285
|
-
this.TestValidateJWT = () => __awaiter(this, void 0, void 0, function* () {
|
|
286
|
-
expect.assertions(1);
|
|
287
|
-
const access_token = yield this.GetAuthServerAPITokenFromServer();
|
|
288
|
-
debug(`access_token: [${access_token}]`.green);
|
|
289
|
-
const retVal = yield this.ValidateJWT(access_token);
|
|
290
|
-
// https://jestjs.io/docs/expect#tomatchobjectobject
|
|
291
|
-
const desiredJWT = {
|
|
292
|
-
scope: 'offline_access session.read session.update',
|
|
293
|
-
iss: 'https://stsmda.com.au/stsauth/',
|
|
294
|
-
aud: 'https://stsmda.com.au/stsauthapi/v1.0/',
|
|
295
|
-
sub: 'session'
|
|
296
|
-
};
|
|
297
|
-
expect(retVal).toMatchObject(desiredJWT);
|
|
298
|
-
});
|
|
299
|
-
__classPrivateFieldSet(this, _TestHelper_authEndpoint, 'https://localhost:3002', "f"); //@@
|
|
57
|
+
this.#authEndpoint = 'https://localhost:3002'; //@@
|
|
300
58
|
}
|
|
59
|
+
#GetHttpsAgent = () => {
|
|
60
|
+
if (this.#httpsAgent === null) {
|
|
61
|
+
// https://nodejs.org/api/http.html#class-httpagent
|
|
62
|
+
this.#httpsAgent = new https_1.default.Agent({
|
|
63
|
+
keepAlive: goptions.keepAlive,
|
|
64
|
+
maxSockets: goptions.maxSockets,
|
|
65
|
+
maxTotalSockets: goptions.maxTotalSockets,
|
|
66
|
+
maxFreeSockets: goptions.maxFreeSockets,
|
|
67
|
+
timeout: goptions.timeout,
|
|
68
|
+
rejectUnauthorized: false
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return this.#httpsAgent;
|
|
72
|
+
};
|
|
73
|
+
StartNetwork = async () => {
|
|
74
|
+
this.#network = await new testcontainers_1.Network().start();
|
|
75
|
+
};
|
|
76
|
+
StopNetwork = async () => {
|
|
77
|
+
await this.#network.stop();
|
|
78
|
+
};
|
|
301
79
|
get network() {
|
|
302
|
-
return
|
|
80
|
+
return this.#network;
|
|
303
81
|
}
|
|
304
82
|
get authPort() {
|
|
305
|
-
return
|
|
83
|
+
return this.#authPort;
|
|
306
84
|
}
|
|
307
85
|
get authHost() {
|
|
308
|
-
return
|
|
86
|
+
return this.#authHost;
|
|
309
87
|
}
|
|
310
88
|
get authEndpoint() {
|
|
311
|
-
return
|
|
89
|
+
return this.#authEndpoint;
|
|
312
90
|
}
|
|
313
91
|
get getHttpsAgent() {
|
|
314
|
-
return
|
|
92
|
+
return this.#GetHttpsAgent();
|
|
315
93
|
}
|
|
94
|
+
CreateRandomString = () => {
|
|
95
|
+
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.'; // /[0-9A-Za-z\-_~.]/
|
|
96
|
+
let random = '';
|
|
97
|
+
const randomValues = Array.from(crypto_1.default.getRandomValues(new Uint8Array(43)));
|
|
98
|
+
randomValues.forEach(v => (random += charset[v % charset.length]));
|
|
99
|
+
return random;
|
|
100
|
+
};
|
|
101
|
+
Login = async (username, password) => {
|
|
102
|
+
const client_id = process.env.CLIENT_ID;
|
|
103
|
+
const nonce = crypto_1.default.randomBytes(43).toString('base64'); //CreateRandomString();
|
|
104
|
+
const response_type = 'code';
|
|
105
|
+
const redirect_uri = process.env.REDIRECT_URI;
|
|
106
|
+
const response_mode = 'query';
|
|
107
|
+
const scope = process.env.SCOPE;
|
|
108
|
+
const state = crypto_1.default.randomBytes(43).toString('base64'); // CreateRandomString();
|
|
109
|
+
const code_verifier = this.CreateRandomString();
|
|
110
|
+
const code_challenge = crypto_1.default.createHash('sha256').update(code_verifier).digest('base64');
|
|
111
|
+
const code_challenge_method = 'S256';
|
|
112
|
+
const authoriseOptions = {
|
|
113
|
+
email: username,
|
|
114
|
+
password,
|
|
115
|
+
client_id,
|
|
116
|
+
nonce,
|
|
117
|
+
response_type,
|
|
118
|
+
redirect_uri,
|
|
119
|
+
response_mode,
|
|
120
|
+
scope,
|
|
121
|
+
state,
|
|
122
|
+
code_challenge,
|
|
123
|
+
code_challenge_method
|
|
124
|
+
};
|
|
125
|
+
const url = `${this.#authEndpoint}${goptions.asapiroot}/login`;
|
|
126
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
127
|
+
const retVal = await (0, axios_1.default)({
|
|
128
|
+
url,
|
|
129
|
+
method: 'post',
|
|
130
|
+
data: authoriseOptions,
|
|
131
|
+
headers: headers,
|
|
132
|
+
httpsAgent: this.#GetHttpsAgent()
|
|
133
|
+
});
|
|
134
|
+
//const cookieString = retVal.headers['set-cookie'];
|
|
135
|
+
/*
|
|
136
|
+
const api = request(this.#endpoint);
|
|
137
|
+
const retVal: any = await (api as any)
|
|
138
|
+
.post(`${goptions.asapiroot}/login`)
|
|
139
|
+
.send(authoriseOptions)
|
|
140
|
+
//.expect('set-cookie', /consent_cookie=.*; Max-Age=86; Path=\/; Expires=.*; HttpOnly; Secure; SameSite=Strict/);
|
|
141
|
+
|
|
142
|
+
const cookieString = retVal.header['set-cookie'];
|
|
143
|
+
|
|
144
|
+
if (cookieString) {
|
|
145
|
+
retVal.cookie = new Cookie(cookieString[0]);
|
|
146
|
+
}
|
|
147
|
+
*/
|
|
148
|
+
return retVal;
|
|
149
|
+
};
|
|
150
|
+
GetAuthServerAPITokenFromServer = async () => {
|
|
151
|
+
return await this.#authUtilsNode.GetAPITokenFromAuthServer(authutilsnode_1.STSClientID.STSTestingService, "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==", goptions.asapiidentifier, this.#authEndpoint);
|
|
152
|
+
};
|
|
153
|
+
ValidateJWT = async (token) => {
|
|
154
|
+
return await this.#authUtilsNode.ValidateJWT(token, goptions.asapiidentifier, this.#authEndpoint);
|
|
155
|
+
};
|
|
156
|
+
StartDatabase = async () => {
|
|
157
|
+
this.#databaseContainer = await new testcontainers_1.GenericContainer("postgres")
|
|
158
|
+
.withExposedPorts(5432)
|
|
159
|
+
.withEnvironment({
|
|
160
|
+
POSTGRES_PASSWORD: "postgres",
|
|
161
|
+
//UV_THREADPOOL_SIZE: "64"
|
|
162
|
+
})
|
|
163
|
+
.withNetwork(this.#network)
|
|
164
|
+
.withNetworkAliases("database")
|
|
165
|
+
.start();
|
|
166
|
+
const httpPort = this.#databaseContainer.getMappedPort(5432);
|
|
167
|
+
const host = this.#databaseContainer.getHost();
|
|
168
|
+
const networkIpAddress = this.#databaseContainer.getIpAddress(this.#network.getName());
|
|
169
|
+
process.env.DB_PORT = httpPort;
|
|
170
|
+
process.env.DB_HOST = host;
|
|
171
|
+
(0, stsconfig_1.$ResetOptions)();
|
|
172
|
+
goptions = (0, stsconfig_1.$Options)();
|
|
173
|
+
debug(`httpPort: [${httpPort}]`.green);
|
|
174
|
+
debug(`host: [${host}]`.green);
|
|
175
|
+
debug(`networkIpAddress: [${networkIpAddress}]`.green);
|
|
176
|
+
debug(`connectionString: [${goptions.connectionString}]`.green);
|
|
177
|
+
debug(`defaultDatabaseConnectionString: [${goptions.defaultDatabaseConnectionString}]`.green);
|
|
178
|
+
};
|
|
179
|
+
StopDatabase = async () => {
|
|
180
|
+
if (this.#databaseContainer) {
|
|
181
|
+
await this.#databaseContainer.stop();
|
|
182
|
+
debug(`Used the following parameters for the database during testing:`.yellow);
|
|
183
|
+
debug(`connectionString: [${goptions.connectionString}]`.yellow);
|
|
184
|
+
debug(`defaultDatabaseConnectionString: [${goptions.defaultDatabaseConnectionString}]`.yellow);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
// Note: .withCopyFilesToContainer and .withCopyContentToContainer have a defect in that Jest will not close. A file handle/stream is left open
|
|
188
|
+
// within the underlying code.
|
|
189
|
+
InitializeDatabase = async () => {
|
|
190
|
+
const stsAuthContainerInit = await new testcontainers_1.GenericContainer("serza/stsauth:latest")
|
|
191
|
+
.withEnvironment({
|
|
192
|
+
DB_USER: "postgres",
|
|
193
|
+
DB_PASSWORD: "postgres",
|
|
194
|
+
DB_HOST: "database",
|
|
195
|
+
DB_PORT: "5432",
|
|
196
|
+
POOL_SIZE: "50",
|
|
197
|
+
MAX_CPU: "2",
|
|
198
|
+
DEBUG: "proc*",
|
|
199
|
+
HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
|
|
200
|
+
HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
|
|
201
|
+
AS_CLIENT_ID: "q6a9F0kksXDDcrsCUKRwHKDnTNh7yZfxCShAgIJqfGg=",
|
|
202
|
+
AS_CLIENT_SECRET: "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
|
|
203
|
+
AS_ENDPOINT: "https://stscore.stsmda.org"
|
|
204
|
+
})
|
|
205
|
+
.withCommand(["node", "dist/app", "create"])
|
|
206
|
+
.withNetwork(this.#network)
|
|
207
|
+
.withNetworkAliases("stsauthrunnerinit")
|
|
208
|
+
.withWaitStrategy(testcontainers_1.Wait.forLogMessage(`User Permissions: {"status":200,"detail":["STSREST01ReadPermission","STSREST01CreatePermission","STSREST01UpdatePermission","STSREST01DeletePermission"]}`))
|
|
209
|
+
.start();
|
|
210
|
+
await (0, stsutils_1.Sleep)(200);
|
|
211
|
+
await stsAuthContainerInit.stop();
|
|
212
|
+
};
|
|
213
|
+
StartAuthService = async () => {
|
|
214
|
+
this.#stsAuthContainer = await new testcontainers_1.GenericContainer("serza/stsauth:latest")
|
|
215
|
+
.withExposedPorts(3002)
|
|
216
|
+
.withEnvironment({
|
|
217
|
+
DB_USER: "postgres",
|
|
218
|
+
DB_PASSWORD: "postgres",
|
|
219
|
+
DB_HOST: "database",
|
|
220
|
+
DB_PORT: "5432",
|
|
221
|
+
POOL_SIZE: "50",
|
|
222
|
+
MAX_CPU: "2",
|
|
223
|
+
DEBUG: "proc*",
|
|
224
|
+
HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
|
|
225
|
+
HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
|
|
226
|
+
AS_CLIENT_ID: "q6a9F0kksXDDcrsCUKRwHKDnTNh7yZfxCShAgIJqfGg=",
|
|
227
|
+
AS_CLIENT_SECRET: "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
|
|
228
|
+
AS_ENDPOINT: "https://stscore.stsmda.org"
|
|
229
|
+
})
|
|
230
|
+
.withNetwork(this.#network)
|
|
231
|
+
.withNetworkAliases("stsauthrunner")
|
|
232
|
+
.withWaitStrategy(testcontainers_1.Wait.forHttp("/stsauth/v1.0/latency", 3002).usingTls().allowInsecure())
|
|
233
|
+
.start();
|
|
234
|
+
const httpAuthPort = this.#stsAuthContainer.getMappedPort(3002);
|
|
235
|
+
await (0, stsutils_1.Sleep)(200);
|
|
236
|
+
debug(`-------------------------------------------------------------------------------------------`.green);
|
|
237
|
+
debug(` *** STSAuth Started ***: [${httpAuthPort}]`.green);
|
|
238
|
+
debug(`-------------------------------------------------------------------------------------------`.green);
|
|
239
|
+
this.#authHost = 'https://localhost';
|
|
240
|
+
this.#authPort = httpAuthPort;
|
|
241
|
+
this.#authEndpoint = `${this.#authHost}:${this.#authPort}`;
|
|
242
|
+
};
|
|
243
|
+
StopAuthService = async () => {
|
|
244
|
+
if (this.#stsAuthContainer) {
|
|
245
|
+
await this.#stsAuthContainer.stop();
|
|
246
|
+
await (0, stsutils_1.Sleep)(200);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
TestLoginAndVerify = async () => {
|
|
250
|
+
expect.assertions(4);
|
|
251
|
+
const retVal = await this.Login('user01@stsmda.com.au', 'user01password');
|
|
252
|
+
expect(retVal.status).toEqual(200);
|
|
253
|
+
debug(`${JSON.stringify(retVal.data)}`.red);
|
|
254
|
+
debug(`${JSON.stringify(retVal.headers)}`.magenta);
|
|
255
|
+
debug(`${JSON.stringify(retVal.headers['set-cookie'])}`.yellow);
|
|
256
|
+
const cookies = retVal.headers['set-cookie'];
|
|
257
|
+
debug(`${cookies[0]}`.yellow);
|
|
258
|
+
debug(`${JSON.stringify(tough.Cookie.parse(cookies[0]))}`.green);
|
|
259
|
+
const cookie = tough.Cookie.parse(cookies[0]);
|
|
260
|
+
const desiredCookieResultAxios = {
|
|
261
|
+
key: 'consent_cookie',
|
|
262
|
+
value: expect.stringMatching(this.#regexURLSafeStringComponent),
|
|
263
|
+
path: '/',
|
|
264
|
+
secure: true,
|
|
265
|
+
httpOnly: true,
|
|
266
|
+
sameSite: 'strict',
|
|
267
|
+
};
|
|
268
|
+
const cookieResult = JSON.parse(JSON.stringify(cookie));
|
|
269
|
+
expect(cookieResult).toMatchObject(desiredCookieResultAxios);
|
|
270
|
+
const cookieExpireDate = new Date(cookie.expires);
|
|
271
|
+
expect(cookieExpireDate).toBeAfter(new Date());
|
|
272
|
+
const desiredResult = {
|
|
273
|
+
sessionId: expect.stringMatching(this.#regexSTSBase64),
|
|
274
|
+
id_token: expect.stringMatching(this.#regexJWT),
|
|
275
|
+
consentRequired: ['res01.create', 'res01.read', 'res01.update', 'res01.delete']
|
|
276
|
+
};
|
|
277
|
+
expect(retVal.data.detail).toMatchObject(desiredResult);
|
|
278
|
+
};
|
|
279
|
+
TestValidateJWT = async () => {
|
|
280
|
+
expect.assertions(1);
|
|
281
|
+
const access_token = await this.GetAuthServerAPITokenFromServer();
|
|
282
|
+
debug(`access_token: [${access_token}]`.green);
|
|
283
|
+
const retVal = await this.ValidateJWT(access_token);
|
|
284
|
+
// https://jestjs.io/docs/expect#tomatchobjectobject
|
|
285
|
+
const desiredJWT = {
|
|
286
|
+
scope: 'offline_access session.read session.update',
|
|
287
|
+
iss: 'https://stsmda.com.au/stsauth/',
|
|
288
|
+
aud: 'https://stsmda.com.au/stsauthapi/v1.0/',
|
|
289
|
+
sub: 'session'
|
|
290
|
+
};
|
|
291
|
+
expect(retVal).toMatchObject(desiredJWT);
|
|
292
|
+
};
|
|
316
293
|
}
|
|
317
294
|
exports.TestHelper = TestHelper;
|
|
318
|
-
_TestHelper_regexURLSafeStringComponent = new WeakMap(), _TestHelper_regexSTSBase64 = new WeakMap(), _TestHelper_regexJWT = new WeakMap(), _TestHelper_authUtilsNode = new WeakMap(), _TestHelper_databaseContainer = new WeakMap(), _TestHelper_stsAuthContainer = new WeakMap(), _TestHelper_network = new WeakMap(), _TestHelper_authEndpoint = new WeakMap(), _TestHelper_authPort = new WeakMap(), _TestHelper_authHost = new WeakMap(), _TestHelper_httpsAgent = new WeakMap(), _TestHelper_GetHttpsAgent = new WeakMap();
|
|
319
295
|
//# sourceMappingURL=testHelpers.js.map
|
package/dist/testHelpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testHelpers.js","sourceRoot":"","sources":["../src/testHelpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testHelpers.js","sourceRoot":"","sources":["../src/testHelpers.ts"],"names":[],"mappings":"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"}
|