@nsshunt/stsdevtools 1.0.66 → 1.0.68

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.
@@ -1,18 +1,7 @@
1
1
  (function(global, factory) {
2
2
  typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("vitest"), require("chalk"), require("tough-cookie"), require("node:crypto"), require("axios"), require("testcontainers"), require("@nsshunt/stsconfig"), require("@nsshunt/stsutils"), require("node:http"), require("node:https")) : typeof define === "function" && define.amd ? define(["exports", "vitest", "chalk", "tough-cookie", "node:crypto", "axios", "testcontainers", "@nsshunt/stsconfig", "@nsshunt/stsutils", "node:http", "node:https"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["@nsshunt/stsdevtools"] = {}, global.vitest, global.chalk, global["tough-cookie"], global["node:crypto"], global.axios, global.testcontainers, global.stsconfig, global.stsutils, global["node:http"], global["node:https"]));
3
- })(this, function(exports2, vitest, chalk, tough, crypto, axios, testcontainers, stsconfig, stsutils, http, https) {
4
- "use strict";var __defProp = Object.defineProperty;
5
- var __typeError = (msg) => {
6
- throw TypeError(msg);
7
- };
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
11
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
12
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
13
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
14
-
15
- var _regexURLSafeStringComponent, _regexSTSBase64, _regexJWT, _network, _databaseContainer, _stsAuthContainer, _stsRest01Container, _ioRedisContainer, _stsFhirContainer, _ioRedisMessageProcessorUrl, _authEndpoint, _authPort, _authHost, _rest01Host, _rest01Port, _rest01Endpoint, _fhirHost, _fhirPort, _fhirEndpoint;
3
+ })(this, (function(exports2, vitest, chalk, tough, crypto, axios, testcontainers, stsconfig, stsutils, http, https) {
4
+ "use strict";
16
5
  function _interopNamespaceDefault(e) {
17
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
18
7
  if (e) {
@@ -31,344 +20,325 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
31
20
  }
32
21
  const tough__namespace = /* @__PURE__ */ _interopNamespaceDefault(tough);
33
22
  class TestHelper {
23
+ //#regexBase64URL = /^[A-Za-z0-9_-]+$/ // Base64URL - https://base64.guru/standards/base64url
24
+ #regexURLSafeStringComponent = /[-a-zA-Z0-9@:%._+~#=]{1,256}/;
25
+ // URL safe string component
26
+ //#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
27
+ #regexSTSBase64 = /SES_(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/;
28
+ // Base64
29
+ #regexJWT = /[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/;
30
+ // JWT (Base64URL.Base64URL.Base64URL)
31
+ #network;
32
+ #databaseContainer;
33
+ #stsAuthContainer;
34
+ #stsRest01Container;
35
+ #ioRedisContainer;
36
+ #stsFhirContainer;
37
+ #ioRedisMessageProcessorUrl = "";
38
+ #authEndpoint = "";
39
+ #authPort = "";
40
+ #authHost = "";
41
+ #rest01Host = "";
42
+ #rest01Port = "";
43
+ #rest01Endpoint = "";
44
+ #fhirHost = "";
45
+ #fhirPort = "";
46
+ #fhirEndpoint = "";
34
47
  constructor() {
35
- //#regexBase64URL = /^[A-Za-z0-9_-]+$/ // Base64URL - https://base64.guru/standards/base64url
36
- __privateAdd(this, _regexURLSafeStringComponent, /[-a-zA-Z0-9@:%._+~#=]{1,256}/);
37
- // URL safe string component
38
- //#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
39
- __privateAdd(this, _regexSTSBase64, /SES_(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/);
40
- // Base64
41
- __privateAdd(this, _regexJWT, /[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/);
42
- // JWT (Base64URL.Base64URL.Base64URL)
43
- __privateAdd(this, _network);
44
- __privateAdd(this, _databaseContainer);
45
- __privateAdd(this, _stsAuthContainer);
46
- __privateAdd(this, _stsRest01Container);
47
- __privateAdd(this, _ioRedisContainer);
48
- __privateAdd(this, _stsFhirContainer);
49
- __privateAdd(this, _ioRedisMessageProcessorUrl, "");
50
- __privateAdd(this, _authEndpoint, "");
51
- __privateAdd(this, _authPort, "");
52
- __privateAdd(this, _authHost, "");
53
- __privateAdd(this, _rest01Host, "");
54
- __privateAdd(this, _rest01Port, "");
55
- __privateAdd(this, _rest01Endpoint, "");
56
- __privateAdd(this, _fhirHost, "");
57
- __privateAdd(this, _fhirPort, "");
58
- __privateAdd(this, _fhirEndpoint, "");
59
- __publicField(this, "StartNetwork", async () => {
60
- __privateSet(this, _network, await new testcontainers.Network().start());
61
- });
62
- __publicField(this, "StopNetwork", async () => {
63
- await __privateGet(this, _network).stop();
64
- });
65
- __publicField(this, "CreateRandomString", () => {
66
- const charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.";
67
- let random = "";
68
- const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));
69
- randomValues.forEach((v) => random += charset[v % charset.length]);
70
- return random;
71
- });
72
- __publicField(this, "Login", async (username, password) => {
73
- const client_id = process.env.CLIENT_ID;
74
- const nonce = crypto.randomBytes(43).toString("base64");
75
- const response_type = "code";
76
- const redirect_uri = process.env.REDIRECT_URI;
77
- const response_mode = "query";
78
- const scope = process.env.SCOPE;
79
- const state = crypto.randomBytes(43).toString("base64");
80
- const code_verifier = this.CreateRandomString();
81
- const code_challenge = crypto.createHash("sha256").update(code_verifier).digest("base64");
82
- const code_challenge_method = "S256";
83
- const authoriseOptions = {
84
- email: username,
85
- password,
86
- client_id,
87
- nonce,
88
- response_type,
89
- redirect_uri,
90
- response_mode,
91
- scope,
92
- state,
93
- code_challenge,
94
- code_challenge_method
95
- };
96
- const url = `${__privateGet(this, _authEndpoint)}${stsconfig.goptions.asapiroot}/login`;
97
- console.log(`Login ---------------------------------------------------------------------------`);
98
- console.log(`url: [${url}]`);
99
- console.log(`authoriseOptions: [${JSON.stringify(authoriseOptions)}]`);
100
- const agentManager = new stsutils.AgentManager({
101
- httpAgentFactory(options) {
102
- return new http.Agent(options);
103
- },
104
- httpsAgentFactory(options) {
105
- return new https.Agent(options);
106
- }
107
- });
108
- const retVal = await axios(new stsutils.STSAxiosConfig(url, "post").withDefaultHeaders().withData(authoriseOptions).withAgentManager(agentManager).config);
109
- return retVal;
110
- });
111
- /*
112
- GetAuthServerAPITokenFromServer = async (): Promise<string> => {
113
- return await this.#authUtilsNode.GetAPITokenFromAuthServer(STSClientID.STSTestingService,
114
- "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
115
- goptions.asapiidentifier, this.#authEndpoint)
116
- }
117
- */
118
- __publicField(this, "StartDatabase", async () => {
119
- __privateSet(this, _databaseContainer, await new testcontainers.GenericContainer("postgres").withExposedPorts(5432).withEnvironment({
120
- POSTGRES_PASSWORD: "postgres"
121
- //UV_THREADPOOL_SIZE: "64"
122
- }).withNetwork(__privateGet(this, _network)).withNetworkAliases("database").start());
123
- const httpPort = __privateGet(this, _databaseContainer).getMappedPort(5432);
124
- const host = __privateGet(this, _databaseContainer).getHost();
125
- const networkIpAddress = __privateGet(this, _databaseContainer).getIpAddress(__privateGet(this, _network).getName());
126
- process.env.DB_HOST = `${host}:${httpPort}`;
127
- stsconfig.$ResetOptions();
128
- this.LogDebugMessage(chalk.green(`httpPort: [${httpPort}]`));
129
- this.LogDebugMessage(chalk.green(`host: [${host}]`));
130
- this.LogDebugMessage(chalk.green(`networkIpAddress: [${networkIpAddress}]`));
131
- this.LogDebugMessage(chalk.green(`connectionString: [${stsconfig.goptions.connectionString}]`));
132
- this.LogDebugMessage(chalk.green(`defaultDatabaseConnectionString: [${stsconfig.goptions.defaultDatabaseConnectionString}]`));
133
- });
134
- __publicField(this, "StopDatabase", async () => {
135
- if (__privateGet(this, _databaseContainer)) {
136
- await __privateGet(this, _databaseContainer).stop();
137
- this.LogDebugMessage(chalk.yellow(`Used the following parameters for the database during testing:`));
138
- this.LogDebugMessage(chalk.yellow(`connectionString: [${stsconfig.goptions.connectionString}]`));
139
- this.LogDebugMessage(chalk.yellow(`defaultDatabaseConnectionString: [${stsconfig.goptions.defaultDatabaseConnectionString}]`));
140
- }
141
- });
142
- // Note: .withCopyFilesToContainer and .withCopyContentToContainer have a defect in that Jest will not close. A file handle/stream is left open
143
- // within the underlying code.
144
- __publicField(this, "InitializeDatabase", async () => {
145
- const stsAuthContainerInit = await new testcontainers.GenericContainer("serza/stsauth:latest").withEnvironment({
146
- DB_USER: "postgres",
147
- DB_PASSWORD: "postgres",
148
- DB_HOST: "database:5432",
149
- // "192.168.14.101",
150
- POOL_SIZE: "50",
151
- MAX_CPU: "2",
152
- DEBUG: "proc*",
153
- HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
154
- HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
155
- AS_ENDPOINT: "https://stscore.stsmda.org"
156
- }).withCommand(["node", "dist/app", "create"]).withNetwork(__privateGet(this, _network)).withNetworkAliases("stsauthrunnerinit").withWaitStrategy(testcontainers.Wait.forLogMessage(`User registered: {"status":200,"detail":{"id":"USR_STSGlobalAdminUser@stsmda.com","name":"STSGlobalAdminUser@stsmda.com","email":"STSGlobalAdminUser@stsmda.com","roles":[]}}`)).start();
157
- await stsutils.Sleep(500);
158
- await stsAuthContainerInit.stop();
159
- });
160
- __publicField(this, "StartRedis", async () => {
161
- __privateSet(this, _ioRedisContainer, await new testcontainers.GenericContainer("redis/redis-stack-server").withEnvironment({
162
- REDIS_ARGS: '--save "" --appendonly no'
163
- }).withExposedPorts(6379).withNetwork(__privateGet(this, _network)).withNetworkAliases("redisstackserver").start());
164
- __privateSet(this, _ioRedisMessageProcessorUrl, `redis://${__privateGet(this, _ioRedisContainer).getHost()}:${__privateGet(this, _ioRedisContainer).getMappedPort(6379)}`);
165
- await stsutils.Sleep(2e3);
166
- this.LogDebugMessage(chalk.green(`redis/redis-stack-server Started. Server Details: ioRedisMessageProcessorUrl: [${__privateGet(this, _ioRedisMessageProcessorUrl)}]`));
167
- });
168
- __publicField(this, "StopRedis", async () => {
169
- await __privateGet(this, _ioRedisContainer).stop();
170
- await stsutils.Sleep(200);
171
- });
172
- __publicField(this, "StartAuthService", async () => {
173
- __privateSet(this, _stsAuthContainer, await new testcontainers.GenericContainer("serza/stsauth:latest").withExposedPorts(3002).withEnvironment({
174
- DB_USER: "postgres",
175
- DB_PASSWORD: "postgres",
176
- DB_HOST: "database:5432",
177
- POOL_SIZE: "50",
178
- MAX_CPU: "2",
179
- DEBUG: "proc*",
180
- HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
181
- HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
182
- AS_ENDPOINT: "https://stscore.stsmda.org",
183
- IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379"
184
- }).withNetwork(__privateGet(this, _network)).withNetworkAliases("stsauthrunner").withWaitStrategy(testcontainers.Wait.forHttp("/stsauth/v1.0/latency", 3002).usingTls().allowInsecure()).start());
185
- const httpAuthPort = __privateGet(this, _stsAuthContainer).getMappedPort(3002);
186
- await stsutils.Sleep(200);
187
- __privateSet(this, _authHost, "https://localhost");
188
- __privateSet(this, _authPort, httpAuthPort);
189
- __privateSet(this, _authEndpoint, `${__privateGet(this, _authHost)}:${__privateGet(this, _authPort)}`);
190
- this.LogDebugMessage(chalk.green(`STSAuth Started. Server Details: Host: [${__privateGet(this, _authHost)}], Port: [${__privateGet(this, _authPort)}]`));
191
- });
192
- __publicField(this, "StartFhirService", async () => {
193
- __privateSet(this, _stsFhirContainer, await new testcontainers.GenericContainer("serza/stsfhir:latest").withExposedPorts(3005).withEnvironment({
194
- DB_USER: "postgres",
195
- DB_PASSWORD: "postgres",
196
- DB_HOST: "database:5432",
197
- POOL_SIZE: "50",
198
- MAX_CPU: "2",
199
- DEBUG: "proc*",
200
- HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
201
- HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
202
- AS_ENDPOINT: "https://stsauthrunner",
203
- AS_HOST_PORT: "3002",
204
- AS_PORT: "3002",
205
- IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379",
206
- SOCKET_IO_REDIS_ADAPTOR_URL: "redis://redisstackserver:6379",
207
- STSFHIR_PORT: "3005",
208
- STSFHIR_HOST_PORT: "3005",
209
- STSFHIR_ENDPOINT: "https://stsfhirserver",
210
- // "https://stscore.stsmda.org",
211
- UV_THREADPOOL_SIZE: "64",
212
- FORCE_COLOR: "3"
213
- //node dist/app usedb postgresResources
214
- }).withNetwork(__privateGet(this, _network)).withNetworkAliases("stsfhirserver").start());
215
- __privateGet(this, _stsFhirContainer).logs().then((stream) => {
216
- stream.on("data", (line) => process.stdout.write(line.toString())).on("err", (line) => process.stderr.write(line.toString())).on("end", () => console.log("Stream ended."));
217
- });
218
- const httpFhirPort = __privateGet(this, _stsFhirContainer).getMappedPort(3005);
219
- await stsutils.Sleep(200);
220
- __privateSet(this, _fhirHost, "https://localhost");
221
- __privateSet(this, _fhirPort, httpFhirPort);
222
- __privateSet(this, _fhirEndpoint, `${__privateGet(this, _fhirHost)}:${__privateGet(this, _fhirPort)}`);
223
- this.LogDebugMessage(chalk.green(`STSFhir Started. Server Details: Host: [${__privateGet(this, _fhirHost)}], Port: [${__privateGet(this, _fhirPort)}]`));
224
- });
225
- __publicField(this, "StopAuthService", async () => {
226
- if (__privateGet(this, _stsAuthContainer)) {
227
- await __privateGet(this, _stsAuthContainer).stop();
228
- await stsutils.Sleep(200);
229
- }
230
- });
231
- __publicField(this, "StopRest01Service", async () => {
232
- if (__privateGet(this, _stsRest01Container)) {
233
- await __privateGet(this, _stsRest01Container).stop();
234
- await stsutils.Sleep(200);
235
- }
236
- });
237
- __publicField(this, "StopFhirService", async () => {
238
- if (__privateGet(this, _stsFhirContainer)) {
239
- await __privateGet(this, _stsFhirContainer).stop();
240
- await stsutils.Sleep(200);
241
- }
242
- });
243
- __publicField(this, "TestLoginAndVerify", async () => {
244
- vitest.expect.assertions(4);
245
- console.log(`TestLoginAndVerify:1`);
246
- const retVal = await this.Login("user01@stsmda.com.au", "user01password");
247
- vitest.expect(retVal.status).toEqual(200);
248
- console.log(`TestLoginAndVerify:2`);
249
- this.LogDebugMessage(chalk.red(`${JSON.stringify(retVal.data)}`));
250
- this.LogDebugMessage(chalk.magenta(`${JSON.stringify(retVal.headers)}`));
251
- this.LogDebugMessage(chalk.yellow(`${JSON.stringify(retVal.headers["set-cookie"])}`));
252
- const cookies = retVal.headers["set-cookie"];
253
- this.LogDebugMessage(chalk.yellow(`${cookies[0]}`));
254
- this.LogDebugMessage(chalk.green(`${JSON.stringify(tough__namespace.Cookie.parse(cookies[0]))}`));
255
- console.log(`TestLoginAndVerify:3`);
256
- const cookie = tough__namespace.Cookie.parse(cookies[0]);
257
- console.log(`TestLoginAndVerify:4`);
258
- const desiredCookieResultAxios = {
259
- key: "consent_cookie",
260
- value: vitest.expect.stringMatching(__privateGet(this, _regexURLSafeStringComponent)),
261
- path: "/",
262
- secure: true,
263
- httpOnly: true,
264
- sameSite: "strict"
265
- };
266
- const cookieResult = JSON.parse(JSON.stringify(cookie));
267
- vitest.expect(cookieResult).toMatchObject(desiredCookieResultAxios);
268
- console.log(`TestLoginAndVerify:5`);
269
- const cookieExpireDate = new Date(cookie.expires);
270
- vitest.expect(cookieExpireDate.getTime()).toBeGreaterThan((/* @__PURE__ */ new Date()).getTime());
271
- const consentRequired = process.env.CONSENT_REQUIRED.split(" ").sort();
272
- retVal.data.detail.consentRequired = retVal.data.detail.consentRequired.sort();
273
- console.log(`TestLoginAndVerify:6`);
274
- const desiredResult = {
275
- sessionId: vitest.expect.stringMatching(__privateGet(this, _regexSTSBase64)),
276
- id_token: vitest.expect.stringMatching(__privateGet(this, _regexJWT)),
277
- consentRequired
278
- };
279
- console.log(`TestLoginAndVerify:7`);
280
- vitest.expect(retVal.data.detail).toMatchObject(desiredResult);
281
- console.log(`TestLoginAndVerify:9`);
282
- });
283
- __publicField(this, "StartRest01Service", async () => {
284
- __privateSet(this, _stsRest01Container, await new testcontainers.GenericContainer("serza/stsrest01:latest").withExposedPorts(3003).withEnvironment({
285
- DB_USER: "postgres",
286
- DB_PASSWORD: "postgres",
287
- DB_HOST: "database:5432",
288
- POOL_SIZE: "50",
289
- MAX_CPU: "2",
290
- DEBUG: "proc*",
291
- HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
292
- HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
293
- //AS_ENDPOINT: "https://stscore.stsmda.org",
294
- AS_ENDPOINT: "https://stsauthrunner",
295
- // this.authHost,
296
- //AS_ENDPOINT: 'https://localhost', // this.authHost,
297
- AS_HOST_PORT: "3002",
298
- AS_PORT: "3002",
299
- IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379"
300
- //AS_HOST_PORT: this.authPort,
301
- //AS_PORT: this.authPort,
302
- //REST01_PORT: '3003',
303
- //REST01_HOST_PORT: '3003',
304
- //REST01_ENDPOINT: 'https://localhost' // 'https://stscore.stsmda.org'
305
- }).withNetwork(__privateGet(this, _network)).withNetworkAliases("rest01").withWaitStrategy(testcontainers.Wait.forHttp("/stsrest01/v1/latency", 3003).usingTls().allowInsecure()).start());
306
- const httpRest01Port = __privateGet(this, _stsRest01Container).getMappedPort(3003);
307
- await stsutils.Sleep(200);
308
- __privateSet(this, _rest01Host, "https://localhost");
309
- __privateSet(this, _rest01Port, httpRest01Port);
310
- __privateSet(this, _rest01Endpoint, `${__privateGet(this, _rest01Host)}:${__privateGet(this, _rest01Port)}`);
311
- this.LogDebugMessage(chalk.green(`STSRest01 Started. Server Details: Host: [${this.rest01Host}], Port: [${this.rest01Port}]`));
312
- });
313
- __privateSet(this, _authEndpoint, "https://localhost:3002");
48
+ this.#authEndpoint = "https://localhost:3002";
314
49
  }
315
50
  LogDebugMessage(message) {
316
51
  stsutils.defaultLogger.debug(message);
317
52
  }
53
+ StartNetwork = async () => {
54
+ this.#network = await new testcontainers.Network().start();
55
+ };
56
+ StopNetwork = async () => {
57
+ await this.#network.stop();
58
+ };
318
59
  get network() {
319
- return __privateGet(this, _network);
60
+ return this.#network;
320
61
  }
321
62
  get authPort() {
322
- return __privateGet(this, _authPort);
63
+ return this.#authPort;
323
64
  }
324
65
  get authHost() {
325
- return __privateGet(this, _authHost);
66
+ return this.#authHost;
326
67
  }
327
68
  get authEndpoint() {
328
- return __privateGet(this, _authEndpoint);
69
+ return this.#authEndpoint;
329
70
  }
330
71
  get rest01Port() {
331
- return __privateGet(this, _rest01Port);
72
+ return this.#rest01Port;
332
73
  }
333
74
  get rest01Host() {
334
- return __privateGet(this, _rest01Host);
75
+ return this.#rest01Host;
335
76
  }
336
77
  get rest01Endpoint() {
337
- return __privateGet(this, _rest01Endpoint);
78
+ return this.#rest01Endpoint;
338
79
  }
339
80
  get fhirPort() {
340
- return __privateGet(this, _fhirPort);
81
+ return this.#fhirPort;
341
82
  }
342
83
  get fhirHost() {
343
- return __privateGet(this, _fhirHost);
84
+ return this.#fhirHost;
344
85
  }
345
86
  get fhirEndpoint() {
346
- return __privateGet(this, _fhirEndpoint);
87
+ return this.#fhirEndpoint;
347
88
  }
348
89
  get ioRedisMessageProcessorUrl() {
349
- return __privateGet(this, _ioRedisMessageProcessorUrl);
90
+ return this.#ioRedisMessageProcessorUrl;
91
+ }
92
+ CreateRandomString = () => {
93
+ const charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.";
94
+ let random = "";
95
+ const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));
96
+ randomValues.forEach((v) => random += charset[v % charset.length]);
97
+ return random;
98
+ };
99
+ Login = async (username, password) => {
100
+ const client_id = process.env.CLIENT_ID;
101
+ const nonce = crypto.randomBytes(43).toString("base64");
102
+ const response_type = "code";
103
+ const redirect_uri = process.env.REDIRECT_URI;
104
+ const response_mode = "query";
105
+ const scope = process.env.SCOPE;
106
+ const state = crypto.randomBytes(43).toString("base64");
107
+ const code_verifier = this.CreateRandomString();
108
+ const code_challenge = crypto.createHash("sha256").update(code_verifier).digest("base64");
109
+ const code_challenge_method = "S256";
110
+ const authoriseOptions = {
111
+ email: username,
112
+ password,
113
+ client_id,
114
+ nonce,
115
+ response_type,
116
+ redirect_uri,
117
+ response_mode,
118
+ scope,
119
+ state,
120
+ code_challenge,
121
+ code_challenge_method
122
+ };
123
+ const url = `${this.#authEndpoint}${stsconfig.goptions.asapiroot}/login`;
124
+ console.log(`Login ---------------------------------------------------------------------------`);
125
+ console.log(`url: [${url}]`);
126
+ console.log(`authoriseOptions: [${JSON.stringify(authoriseOptions)}]`);
127
+ const agentManager = new stsutils.AgentManager({
128
+ httpAgentFactory(options) {
129
+ return new http.Agent(options);
130
+ },
131
+ httpsAgentFactory(options) {
132
+ return new https.Agent(options);
133
+ }
134
+ });
135
+ const retVal = await axios(new stsutils.STSAxiosConfig(url, "post").withDefaultHeaders().withData(authoriseOptions).withAgentManager(agentManager).config);
136
+ return retVal;
137
+ };
138
+ /*
139
+ GetAuthServerAPITokenFromServer = async (): Promise<string> => {
140
+ return await this.#authUtilsNode.GetAPITokenFromAuthServer(STSClientID.STSTestingService,
141
+ "eN9u0mHZLGWZrdnE1zit2vL6xwUFW466sTZcbkXDml5KWxlvKaZ1uiOZmA==",
142
+ goptions.asapiidentifier, this.#authEndpoint)
350
143
  }
144
+ */
145
+ StartDatabase = async () => {
146
+ this.#databaseContainer = await new testcontainers.GenericContainer("postgres").withExposedPorts(5432).withEnvironment({
147
+ POSTGRES_PASSWORD: "postgres"
148
+ //UV_THREADPOOL_SIZE: "64"
149
+ }).withNetwork(this.#network).withNetworkAliases("database").start();
150
+ const httpPort = this.#databaseContainer.getMappedPort(5432);
151
+ const host = this.#databaseContainer.getHost();
152
+ const networkIpAddress = this.#databaseContainer.getIpAddress(this.#network.getName());
153
+ process.env.DB_HOST = `${host}:${httpPort}`;
154
+ stsconfig.$ResetOptions();
155
+ this.LogDebugMessage(chalk.green(`httpPort: [${httpPort}]`));
156
+ this.LogDebugMessage(chalk.green(`host: [${host}]`));
157
+ this.LogDebugMessage(chalk.green(`networkIpAddress: [${networkIpAddress}]`));
158
+ this.LogDebugMessage(chalk.green(`connectionString: [${stsconfig.goptions.connectionString}]`));
159
+ this.LogDebugMessage(chalk.green(`defaultDatabaseConnectionString: [${stsconfig.goptions.defaultDatabaseConnectionString}]`));
160
+ };
161
+ StopDatabase = async () => {
162
+ if (this.#databaseContainer) {
163
+ await this.#databaseContainer.stop();
164
+ this.LogDebugMessage(chalk.yellow(`Used the following parameters for the database during testing:`));
165
+ this.LogDebugMessage(chalk.yellow(`connectionString: [${stsconfig.goptions.connectionString}]`));
166
+ this.LogDebugMessage(chalk.yellow(`defaultDatabaseConnectionString: [${stsconfig.goptions.defaultDatabaseConnectionString}]`));
167
+ }
168
+ };
169
+ // Note: .withCopyFilesToContainer and .withCopyContentToContainer have a defect in that Jest will not close. A file handle/stream is left open
170
+ // within the underlying code.
171
+ InitializeDatabase = async () => {
172
+ const stsAuthContainerInit = await new testcontainers.GenericContainer("serza/stsauth:latest").withEnvironment({
173
+ DB_USER: "postgres",
174
+ DB_PASSWORD: "postgres",
175
+ DB_HOST: "database:5432",
176
+ // "192.168.14.101",
177
+ POOL_SIZE: "50",
178
+ MAX_CPU: "2",
179
+ DEBUG: "proc*",
180
+ HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
181
+ HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
182
+ AS_ENDPOINT: "https://stscore.stsmda.org"
183
+ }).withCommand(["node", "dist/app", "create"]).withNetwork(this.#network).withNetworkAliases("stsauthrunnerinit").withWaitStrategy(testcontainers.Wait.forLogMessage(`User registered: {"status":200,"detail":{"id":"USR_STSGlobalAdminUser@stsmda.com","name":"STSGlobalAdminUser@stsmda.com","email":"STSGlobalAdminUser@stsmda.com","roles":[]}}`)).start();
184
+ await stsutils.Sleep(500);
185
+ await stsAuthContainerInit.stop();
186
+ };
187
+ StartRedis = async () => {
188
+ this.#ioRedisContainer = await new testcontainers.GenericContainer("redis/redis-stack-server").withEnvironment({
189
+ REDIS_ARGS: '--save "" --appendonly no'
190
+ }).withExposedPorts(6379).withNetwork(this.#network).withNetworkAliases("redisstackserver").start();
191
+ this.#ioRedisMessageProcessorUrl = `redis://${this.#ioRedisContainer.getHost()}:${this.#ioRedisContainer.getMappedPort(6379)}`;
192
+ await stsutils.Sleep(2e3);
193
+ this.LogDebugMessage(chalk.green(`redis/redis-stack-server Started. Server Details: ioRedisMessageProcessorUrl: [${this.#ioRedisMessageProcessorUrl}]`));
194
+ };
195
+ StopRedis = async () => {
196
+ await this.#ioRedisContainer.stop();
197
+ await stsutils.Sleep(200);
198
+ };
199
+ StartAuthService = async () => {
200
+ this.#stsAuthContainer = await new testcontainers.GenericContainer("serza/stsauth:latest").withExposedPorts(3002).withEnvironment({
201
+ DB_USER: "postgres",
202
+ DB_PASSWORD: "postgres",
203
+ DB_HOST: "database:5432",
204
+ POOL_SIZE: "50",
205
+ MAX_CPU: "2",
206
+ DEBUG: "proc*",
207
+ HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
208
+ HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
209
+ AS_ENDPOINT: "https://stscore.stsmda.org",
210
+ IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379"
211
+ }).withNetwork(this.#network).withNetworkAliases("stsauthrunner").withWaitStrategy(testcontainers.Wait.forHttp("/stsauth/v1.0/latency", 3002).usingTls().allowInsecure()).start();
212
+ const httpAuthPort = this.#stsAuthContainer.getMappedPort(3002);
213
+ await stsutils.Sleep(200);
214
+ this.#authHost = "https://localhost";
215
+ this.#authPort = httpAuthPort;
216
+ this.#authEndpoint = `${this.#authHost}:${this.#authPort}`;
217
+ this.LogDebugMessage(chalk.green(`STSAuth Started. Server Details: Host: [${this.#authHost}], Port: [${this.#authPort}]`));
218
+ };
219
+ StartFhirService = async () => {
220
+ this.#stsFhirContainer = await new testcontainers.GenericContainer("serza/stsfhir:latest").withExposedPorts(3005).withEnvironment({
221
+ DB_USER: "postgres",
222
+ DB_PASSWORD: "postgres",
223
+ DB_HOST: "database:5432",
224
+ POOL_SIZE: "50",
225
+ MAX_CPU: "2",
226
+ DEBUG: "proc*",
227
+ HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
228
+ HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
229
+ AS_ENDPOINT: "https://stsauthrunner",
230
+ AS_HOST_PORT: "3002",
231
+ AS_PORT: "3002",
232
+ IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379",
233
+ SOCKET_IO_REDIS_ADAPTOR_URL: "redis://redisstackserver:6379",
234
+ STSFHIR_PORT: "3005",
235
+ STSFHIR_HOST_PORT: "3005",
236
+ STSFHIR_ENDPOINT: "https://stsfhirserver",
237
+ // "https://stscore.stsmda.org",
238
+ UV_THREADPOOL_SIZE: "64",
239
+ FORCE_COLOR: "3"
240
+ //node dist/app usedb postgresResources
241
+ }).withNetwork(this.#network).withNetworkAliases("stsfhirserver").start();
242
+ this.#stsFhirContainer.logs().then((stream) => {
243
+ stream.on("data", (line) => process.stdout.write(line.toString())).on("err", (line) => process.stderr.write(line.toString())).on("end", () => console.log("Stream ended."));
244
+ });
245
+ const httpFhirPort = this.#stsFhirContainer.getMappedPort(3005);
246
+ await stsutils.Sleep(200);
247
+ this.#fhirHost = "https://localhost";
248
+ this.#fhirPort = httpFhirPort;
249
+ this.#fhirEndpoint = `${this.#fhirHost}:${this.#fhirPort}`;
250
+ this.LogDebugMessage(chalk.green(`STSFhir Started. Server Details: Host: [${this.#fhirHost}], Port: [${this.#fhirPort}]`));
251
+ };
252
+ StopAuthService = async () => {
253
+ if (this.#stsAuthContainer) {
254
+ await this.#stsAuthContainer.stop();
255
+ await stsutils.Sleep(200);
256
+ }
257
+ };
258
+ StopRest01Service = async () => {
259
+ if (this.#stsRest01Container) {
260
+ await this.#stsRest01Container.stop();
261
+ await stsutils.Sleep(200);
262
+ }
263
+ };
264
+ StopFhirService = async () => {
265
+ if (this.#stsFhirContainer) {
266
+ await this.#stsFhirContainer.stop();
267
+ await stsutils.Sleep(200);
268
+ }
269
+ };
270
+ TestLoginAndVerify = async () => {
271
+ vitest.expect.assertions(4);
272
+ console.log(`TestLoginAndVerify:1`);
273
+ const retVal = await this.Login("user01@stsmda.com.au", "user01password");
274
+ vitest.expect(retVal.status).toEqual(200);
275
+ console.log(`TestLoginAndVerify:2`);
276
+ this.LogDebugMessage(chalk.red(`${JSON.stringify(retVal.data)}`));
277
+ this.LogDebugMessage(chalk.magenta(`${JSON.stringify(retVal.headers)}`));
278
+ this.LogDebugMessage(chalk.yellow(`${JSON.stringify(retVal.headers["set-cookie"])}`));
279
+ const cookies = retVal.headers["set-cookie"];
280
+ this.LogDebugMessage(chalk.yellow(`${cookies[0]}`));
281
+ this.LogDebugMessage(chalk.green(`${JSON.stringify(tough__namespace.Cookie.parse(cookies[0]))}`));
282
+ console.log(`TestLoginAndVerify:3`);
283
+ const cookie = tough__namespace.Cookie.parse(cookies[0]);
284
+ console.log(`TestLoginAndVerify:4`);
285
+ const desiredCookieResultAxios = {
286
+ key: "consent_cookie",
287
+ value: vitest.expect.stringMatching(this.#regexURLSafeStringComponent),
288
+ path: "/",
289
+ secure: true,
290
+ httpOnly: true,
291
+ sameSite: "strict"
292
+ };
293
+ const cookieResult = JSON.parse(JSON.stringify(cookie));
294
+ vitest.expect(cookieResult).toMatchObject(desiredCookieResultAxios);
295
+ console.log(`TestLoginAndVerify:5`);
296
+ const cookieExpireDate = new Date(cookie.expires);
297
+ vitest.expect(cookieExpireDate.getTime()).toBeGreaterThan((/* @__PURE__ */ new Date()).getTime());
298
+ const consentRequired = process.env.CONSENT_REQUIRED.split(" ").sort();
299
+ retVal.data.detail.consentRequired = retVal.data.detail.consentRequired.sort();
300
+ console.log(`TestLoginAndVerify:6`);
301
+ const desiredResult = {
302
+ sessionId: vitest.expect.stringMatching(this.#regexSTSBase64),
303
+ id_token: vitest.expect.stringMatching(this.#regexJWT),
304
+ consentRequired
305
+ };
306
+ console.log(`TestLoginAndVerify:7`);
307
+ vitest.expect(retVal.data.detail).toMatchObject(desiredResult);
308
+ console.log(`TestLoginAndVerify:9`);
309
+ };
310
+ StartRest01Service = async () => {
311
+ this.#stsRest01Container = await new testcontainers.GenericContainer("serza/stsrest01:latest").withExposedPorts(3003).withEnvironment({
312
+ DB_USER: "postgres",
313
+ DB_PASSWORD: "postgres",
314
+ DB_HOST: "database:5432",
315
+ POOL_SIZE: "50",
316
+ MAX_CPU: "2",
317
+ DEBUG: "proc*",
318
+ HTTPS_SERVER_KEY_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.key",
319
+ HTTPS_SERVER_CERT_PATH: "/var/lib/sts/stsglobalresources/keys-tmp/server.cert",
320
+ //AS_ENDPOINT: "https://stscore.stsmda.org",
321
+ AS_ENDPOINT: "https://stsauthrunner",
322
+ // this.authHost,
323
+ //AS_ENDPOINT: 'https://localhost', // this.authHost,
324
+ AS_HOST_PORT: "3002",
325
+ AS_PORT: "3002",
326
+ IM_REDIS_MESSAGE_PROCESSOR_URL: "redis://redisstackserver:6379"
327
+ //AS_HOST_PORT: this.authPort,
328
+ //AS_PORT: this.authPort,
329
+ //REST01_PORT: '3003',
330
+ //REST01_HOST_PORT: '3003',
331
+ //REST01_ENDPOINT: 'https://localhost' // 'https://stscore.stsmda.org'
332
+ }).withNetwork(this.#network).withNetworkAliases("rest01").withWaitStrategy(testcontainers.Wait.forHttp("/stsrest01/v1/latency", 3003).usingTls().allowInsecure()).start();
333
+ const httpRest01Port = this.#stsRest01Container.getMappedPort(3003);
334
+ await stsutils.Sleep(200);
335
+ this.#rest01Host = "https://localhost";
336
+ this.#rest01Port = httpRest01Port;
337
+ this.#rest01Endpoint = `${this.#rest01Host}:${this.#rest01Port}`;
338
+ this.LogDebugMessage(chalk.green(`STSRest01 Started. Server Details: Host: [${this.rest01Host}], Port: [${this.rest01Port}]`));
339
+ };
351
340
  }
352
- _regexURLSafeStringComponent = new WeakMap();
353
- _regexSTSBase64 = new WeakMap();
354
- _regexJWT = new WeakMap();
355
- _network = new WeakMap();
356
- _databaseContainer = new WeakMap();
357
- _stsAuthContainer = new WeakMap();
358
- _stsRest01Container = new WeakMap();
359
- _ioRedisContainer = new WeakMap();
360
- _stsFhirContainer = new WeakMap();
361
- _ioRedisMessageProcessorUrl = new WeakMap();
362
- _authEndpoint = new WeakMap();
363
- _authPort = new WeakMap();
364
- _authHost = new WeakMap();
365
- _rest01Host = new WeakMap();
366
- _rest01Port = new WeakMap();
367
- _rest01Endpoint = new WeakMap();
368
- _fhirHost = new WeakMap();
369
- _fhirPort = new WeakMap();
370
- _fhirEndpoint = new WeakMap();
371
341
  exports2.TestHelper = TestHelper;
372
342
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
373
- });
343
+ }));
374
344
  //# sourceMappingURL=stsdevtools.umd.js.map