From 9210ffb2e3e926478139e06f8632c01b0df7caf7 Mon Sep 17 00:00:00 2001 From: "Ayobami O. Idowu" Date: Fri, 20 Oct 2023 08:18:27 -0700 Subject: [PATCH] update: update branch with upstream master branch (#1097) * fix: FORMS-891 vuetify traditional chinese support (#1072) Co-authored-by: Walter Moar * fix: filter out draft submissions on the submission page search * fix: remove boolean check for filterformSubmissionStatusCode props * fix: urgent timeout increase to fix outage (#1084) * Fix/urgent timeout increase (#1085) * fix: urgent timeout increase to fix outage * fix: database view performance (#1091) * fix: simplification of user form access view (#1087) * fix: database view performance (#1090) * fix: simplification of user form access view * fix: remove the sorting in user_form_access_vw --------- Co-authored-by: Walter Moar * fix: FORMS-893 semver vuln and endpoint bug (#1094) * FORMS-881 - Not allow to save drafts if form validation fails (#1048) * fix: not allow to save drafts if form validation fails * fix: make validation run on render for drafts. remove disable save draft button on validation fails * update: add countdown timer to token expiration warning dialog - add a countdown timer to the token expiration warning dialog - wrote unit tests for the frontend changes - added multi lang to the new components created * feat: FORMS-882 add submissionId to exports Co-authored-by: Walter Moar * fix: FORMS-899 revert timeout and simplify views (#1093) * fix: FORMS-899 remove sorting in views * fix: FORMS-899 revert frontend timeout change --------- Co-authored-by: Walter Moar --------- Co-authored-by: bcgov-citz-ccft <114184659+bcgov-citz-ccft@users.noreply.github.com> Co-authored-by: Walter Moar Co-authored-by: bcvesalink <127142437+bcvesalink@users.noreply.github.com> --- .../base/BaseInternationalization.vue | 2 +- .../src/components/designer/FormViewer.vue | 4 + .../trans/vuetify/locale/README.md | 2 + ...0231017192656_037-user-form-permissions.js | 176 ++++++++++++++++++ .../20231019153505_038-view-simplification.js | 157 ++++++++++++++++ app/src/forms/form/exportService.js | 2 +- app/src/forms/form/service.js | 14 +- .../unit/forms/form/exportService.spec.js | 14 +- app/tests/unit/forms/form/service.spec.js | 14 +- tests/load/load-test/index.js | 5 +- tests/load/load-test/package-lock.json | 122 +++++++++--- tests/load/load-test/package.json | 2 +- 12 files changed, 461 insertions(+), 53 deletions(-) create mode 100644 app/frontend/src/internationalization/trans/vuetify/locale/README.md create mode 100644 app/src/db/migrations/20231017192656_037-user-form-permissions.js create mode 100644 app/src/db/migrations/20231019153505_038-view-simplification.js diff --git a/app/frontend/src/components/base/BaseInternationalization.vue b/app/frontend/src/components/base/BaseInternationalization.vue index 85a42dee2..2833058db 100644 --- a/app/frontend/src/components/base/BaseInternationalization.vue +++ b/app/frontend/src/components/base/BaseInternationalization.vue @@ -74,7 +74,7 @@ export default { this.$vuetify.lang.current = lang.keyword == 'zh' ? 'zhHans' - : lang.keyword == 'zh-TW' + : lang.keyword == 'zhTW' ? 'zhHant' : lang.keyword; this.setMultiLanguage(lang.keyword); diff --git a/app/frontend/src/components/designer/FormViewer.vue b/app/frontend/src/components/designer/FormViewer.vue index 8dd1a4baa..e104c2648 100644 --- a/app/frontend/src/components/designer/FormViewer.vue +++ b/app/frontend/src/components/designer/FormViewer.vue @@ -542,6 +542,10 @@ export default { this.block = e; }, formChange(e) { + // if draft check validation on render + if (this.submissionRecord.draft) { + this.$refs.chefForm.formio.checkValidity(null, true, null, false); + } if (e.changed != undefined && !e.changed.flags.fromSubmission) { this.formDataEntered = true; } diff --git a/app/frontend/src/internationalization/trans/vuetify/locale/README.md b/app/frontend/src/internationalization/trans/vuetify/locale/README.md new file mode 100644 index 000000000..047600a8f --- /dev/null +++ b/app/frontend/src/internationalization/trans/vuetify/locale/README.md @@ -0,0 +1,2 @@ +This directory contains the translation files for languages that are supported +by CHEFS, but not supported by Vuetify. diff --git a/app/src/db/migrations/20231017192656_037-user-form-permissions.js b/app/src/db/migrations/20231017192656_037-user-form-permissions.js new file mode 100644 index 000000000..9d25619b1 --- /dev/null +++ b/app/src/db/migrations/20231017192656_037-user-form-permissions.js @@ -0,0 +1,176 @@ +// Having performance problems and these views seem to be a cause of it. +// 1. Remove the join of "role" in user_form_permissions_vw. +// 2. Remove the join of "role" in user_form_roles_vw. +// 3. Simplify the EXISTS SELECT in user_form_permissions_vw. +// 4. Simplify the EXISTS SELECT in user_form_roles_vw. +// 5. Remove the sorting in the user_form_access_vw. + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function (knex) { + return Promise.resolve() + .then(() => knex.schema.dropViewIfExists('user_form_access_vw')) + .then(() => knex.schema.dropViewIfExists('user_form_permissions_vw')) + .then(() => knex.schema.dropViewIfExists('user_form_roles_vw')) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw + AS SELECT fru."userId", + fru."formId", + array_agg(DISTINCT fru.role) AS roles + FROM form_role_user fru + GROUP BY fru."userId", fru."formId" + UNION + SELECT u2.id AS "userId", + f2.id AS "formId", + '{}'::character varying[] AS roles + FROM form_vw f2, + "user" u2 + WHERE NOT EXISTS ( + SELECT 1 FROM form_role_user fru2 + WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`) + ) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_permissions_vw + AS SELECT fru."userId", + fru."formId", + array_agg(DISTINCT p.code) AS permissions + FROM form_role_user fru + JOIN role_permission rp ON fru.role::text = rp.role::text + JOIN permission p ON rp.permission::text = p.code::text + GROUP BY fru."userId", fru."formId" + UNION + SELECT u2.id AS "userId", + f2.id AS "formId", + '{submission_create,form_read}'::character varying[] AS permissions + FROM form_vw f2, + "user" u2 + WHERE NOT EXISTS ( + SELECT 1 FROM form_role_user fru2 + WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id);`) + ) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw + AS SELECT r."userId", + u."idpUserId", + u.username, + u."fullName", + u."firstName", + u."lastName", + u.email, + r."formId", + f.name AS "formName", + f.labels, + u."idpCode" AS "user_idpCode", + f."identityProviders", + f."identityProviders" AS form_login_required, + f.idps, + f.active, + f."formVersionId", + f.version, + r.roles, + p.permissions, + f.published, + f."versionUpdatedAt", + f.description AS "formDescription" + FROM "user" u + JOIN user_form_roles_vw r ON u.id = r."userId" + JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId" + JOIN form_vw f ON f.id = p."formId";`) + ); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = function (knex) { + return Promise.resolve() + .then(() => knex.schema.dropViewIfExists('user_form_access_vw')) + .then(() => knex.schema.dropViewIfExists('user_form_permissions_vw')) + .then(() => knex.schema.dropViewIfExists('user_form_roles_vw')) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_roles_vw + AS SELECT fru."userId", + fru."formId", + array_agg(DISTINCT r.code) AS roles + FROM form_role_user fru + JOIN role r ON fru.role::text = r.code::text + GROUP BY fru."userId", fru."formId" + UNION + SELECT u2.id AS "userId", + f2.id AS "formId", + '{}'::character varying[] AS roles + FROM form_vw f2, + "user" u2 + WHERE NOT (EXISTS ( SELECT fru2.id, + fru2.role, + fru2."formId", + fru2."userId", + fru2."createdBy", + fru2."createdAt", + fru2."updatedBy", + fru2."updatedAt" + FROM form_role_user fru2 + WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`) + ) + .then(() => + knex.schema.raw(` + CREATE OR REPLACE VIEW public.user_form_permissions_vw + AS SELECT fru."userId", + fru."formId", + array_agg(DISTINCT p.code) AS permissions + FROM form_role_user fru + JOIN role r ON fru.role::text = r.code::text + JOIN role_permission rp ON r.code::text = rp.role::text + JOIN permission p ON rp.permission::text = p.code::text + GROUP BY fru."userId", fru."formId" + UNION + SELECT u2.id AS "userId", + f2.id AS "formId", + '{submission_create,form_read}'::character varying[] AS permissions + FROM form_vw f2, + "user" u2 + WHERE NOT (EXISTS ( SELECT fru2.id, + fru2.role, + fru2."formId", + fru2."userId", + fru2."createdBy", + fru2."createdAt", + fru2."updatedBy", + fru2."updatedAt" + FROM form_role_user fru2 + WHERE fru2."formId" = f2.id AND fru2."userId" = u2.id));`) + ) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.user_form_access_vw + AS SELECT r."userId", + u."idpUserId", + u.username, + u."fullName", + u."firstName", + u."lastName", + u.email, + r."formId", + f.name AS "formName", + f.labels, + u."idpCode" AS "user_idpCode", + f."identityProviders", + f."identityProviders" AS form_login_required, + f.idps, + f.active, + f."formVersionId", + f.version, + r.roles, + p.permissions, + f.published, + f."versionUpdatedAt", + f.description AS "formDescription" + FROM "user" u + JOIN user_form_roles_vw r ON u.id = r."userId" + JOIN user_form_permissions_vw p ON r."userId" = p."userId" AND r."formId" = p."formId" + JOIN form_vw f ON f.id = p."formId" + ORDER BY (lower(u."lastName"::text)), (lower(u."firstName"::text)), (lower(f.name::text));`) + ); +}; diff --git a/app/src/db/migrations/20231019153505_038-view-simplification.js b/app/src/db/migrations/20231019153505_038-view-simplification.js new file mode 100644 index 000000000..1e8d17968 --- /dev/null +++ b/app/src/db/migrations/20231019153505_038-view-simplification.js @@ -0,0 +1,157 @@ +// Having performance problems and these views seem to be a cause of it. +// 1. Remove the sorting in the public_form_access_vw. +// 2. Remove the sorting in the form_vw. + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function (knex) { + return Promise.resolve() + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.public_form_access_vw + AS SELECT NULL::text AS "userId", + NULL::text AS "idpUserId", + 'public'::text AS username, + 'public'::text AS "fullName", + NULL::text AS "firstName", + NULL::text AS "lastName", + NULL::text AS email, + f.id AS "formId", + f.name AS "formName", + f.labels, + f."identityProviders", + f.idps, + f.active, + f."formVersionId", + f.version, + '{}'::character varying[] AS roles, + '{submission_create,form_read}'::character varying[] AS permissions + FROM form_vw f + WHERE 'public'::text = ANY (f.idps::text[])`) + ) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.form_vw + AS SELECT DISTINCT ON ((lower(f.name::text)), fv.version, f.id) f.id, + f.name, + f.active, + f.description, + f.labels, + f."createdAt", + f."createdBy", + f."updatedAt", + f."updatedBy", + fv.id AS "formVersionId", + fv.version, + CASE + WHEN count(fip.code) = 0 THEN '{}'::character varying[] + ELSE array_agg(DISTINCT fip.code) + END AS "identityProviders", + CASE + WHEN count(ip.idp) = 0 THEN '{}'::character varying[] + ELSE array_agg(DISTINCT ip.idp) + END AS idps, + fv.published, + fv."updatedAt" AS "versionUpdatedAt", + f."allowSubmitterToUploadFile" + FROM form f + LEFT JOIN LATERAL ( SELECT v.id, + v."formId", + v.version, + v.schema, + v."createdBy", + v."createdAt", + v."updatedBy", + v."updatedAt", + v.published + FROM form_version v + WHERE v."formId" = f.id + ORDER BY ( + CASE + WHEN v.published THEN 1 + ELSE 0 + END) DESC, v.version DESC + LIMIT 1) fv ON true + LEFT JOIN form_identity_provider fip ON f.id = fip."formId" + LEFT JOIN identity_provider ip ON fip.code::text = ip.code::text + GROUP BY f.id, f.name, f.active, f.description, f.labels, f."createdAt", f."createdBy", f."updatedAt", f."updatedBy", fv.id, fv.version, fv.published, fv."updatedAt"`) + ); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = function (knex) { + return Promise.resolve() + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.form_vw + AS SELECT DISTINCT ON ((lower(f.name::text)), fv.version, f.id) f.id, + f.name, + f.active, + f.description, + f.labels, + f."createdAt", + f."createdBy", + f."updatedAt", + f."updatedBy", + fv.id AS "formVersionId", + fv.version, + CASE + WHEN count(fip.code) = 0 THEN '{}'::character varying[] + ELSE array_agg(DISTINCT fip.code) + END AS "identityProviders", + CASE + WHEN count(ip.idp) = 0 THEN '{}'::character varying[] + ELSE array_agg(DISTINCT ip.idp) + END AS idps, + fv.published, + fv."updatedAt" AS "versionUpdatedAt", + f."allowSubmitterToUploadFile" + FROM form f + LEFT JOIN LATERAL ( SELECT v.id, + v."formId", + v.version, + v.schema, + v."createdBy", + v."createdAt", + v."updatedBy", + v."updatedAt", + v.published + FROM form_version v + WHERE v."formId" = f.id + ORDER BY ( + CASE + WHEN v.published THEN 1 + ELSE 0 + END) DESC, v.version DESC + LIMIT 1) fv ON true + LEFT JOIN form_identity_provider fip ON f.id = fip."formId" + LEFT JOIN identity_provider ip ON fip.code::text = ip.code::text + GROUP BY f.id, f.name, f.active, f.description, f.labels, f."createdAt", f."createdBy", f."updatedAt", f."updatedBy", fv.id, fv.version, fv.published, fv."updatedAt" + ORDER BY (lower(f.name::text)), fv.version DESC, f.id;`) + ) + .then(() => + knex.schema.raw(`CREATE OR REPLACE VIEW public.public_form_access_vw + AS SELECT NULL::text AS "userId", + NULL::text AS "idpUserId", + 'public'::text AS username, + 'public'::text AS "fullName", + NULL::text AS "firstName", + NULL::text AS "lastName", + NULL::text AS email, + f.id AS "formId", + f.name AS "formName", + f.labels, + f."identityProviders", + f.idps, + f.active, + f."formVersionId", + f.version, + '{}'::character varying[] AS roles, + '{submission_create,form_read}'::character varying[] AS permissions + FROM form_vw f + WHERE 'public'::text = ANY (f.idps::text[]) + ORDER BY (lower(f.name::text));`) + ); +}; diff --git a/app/src/forms/form/exportService.js b/app/src/forms/form/exportService.js index a551ba8c2..849c572d0 100644 --- a/app/src/forms/form/exportService.js +++ b/app/src/forms/form/exportService.js @@ -200,7 +200,7 @@ const service = { _submissionsColumns: (form, params) => { // Custom columns not defined - return default column selection behavior - let columns = ['confirmationId', 'formName', 'version', 'createdAt', 'fullName', 'username', 'email']; + let columns = ['submissionId', 'confirmationId', 'formName', 'version', 'createdAt', 'fullName', 'username', 'email']; // if form has 'status updates' enabled in the form settings include these in export if (form.enableStatusUpdates) { columns = columns.concat(['status', 'assignee', 'assigneeEmail']); diff --git a/app/src/forms/form/service.js b/app/src/forms/form/service.js index 8fcc69e2b..b8a96390a 100644 --- a/app/src/forms/form/service.js +++ b/app/src/forms/form/service.js @@ -249,6 +249,7 @@ const service = { .modify('filterCreatedBy', params.createdBy) .modify('filterFormVersionId', params.formVersionId) .modify('filterVersion', params.version) + .modify('filterformSubmissionStatusCode', params.filterformSubmissionStatusCode) .modify('orderDefault', params.sortBy && params.page ? true : false, params); if (params.createdAt && Array.isArray(params.createdAt) && params.createdAt.length == 2) { query.modify('filterCreatedAt', params.createdAt[0], params.createdAt[1]); @@ -283,20 +284,12 @@ const service = { ); } if (params.paginationEnabled) { - return await service.processPaginationData( - query, - parseInt(params.page), - parseInt(params.itemsPerPage), - params.filterformSubmissionStatusCode, - params.totalSubmissions, - params.search, - params.searchEnabled - ); + return await service.processPaginationData(query, parseInt(params.page), parseInt(params.itemsPerPage), params.totalSubmissions, params.search, params.searchEnabled); } return query; }, - async processPaginationData(query, page, itemsPerPage, filterformSubmissionStatusCode, totalSubmissions, search, searchEnabled) { + async processPaginationData(query, page, itemsPerPage, totalSubmissions, search, searchEnabled) { let isSearchAble = typeUtils.isBoolean(searchEnabled) ? searchEnabled : searchEnabled !== undefined ? JSON.parse(searchEnabled) : false; if (isSearchAble) { let submissionsData = await query; @@ -338,7 +331,6 @@ const service = { result.results = searchedData.slice(start, end); return result; } else { - await query.modify('filterformSubmissionStatusCode', filterformSubmissionStatusCode); if (itemsPerPage && parseInt(itemsPerPage) === -1) { return await query.page(parseInt(page), parseInt(totalSubmissions || 0)); } else if (itemsPerPage && parseInt(page) >= 0) { diff --git a/app/tests/unit/forms/form/exportService.spec.js b/app/tests/unit/forms/form/exportService.spec.js index 3e63ddc6a..9baccec10 100644 --- a/app/tests/unit/forms/form/exportService.spec.js +++ b/app/tests/unit/forms/form/exportService.spec.js @@ -459,7 +459,7 @@ describe('_submissionsColumns', () => { enableCopyExistingSubmission: false, }; - it('should return right number of columns, when no prefered columns passed as params.', async () => { + it('should return right columns, when no prefered columns passed as params.', async () => { const params = { type: 'submissions', format: 'json', @@ -469,7 +469,8 @@ describe('_submissionsColumns', () => { }; const submissions = exportService._submissionsColumns(form, params); - expect(submissions.length).toEqual(8); + expect(submissions.length).toEqual(9); + expect(submissions).toEqual(expect.arrayContaining(['submissionId', 'confirmationId', 'formName', 'version', 'createdAt', 'fullName', 'username', 'email', 'submission'])); }); it('should return right number of columns, when 1 prefered column (deleted) passed as params.', async () => { @@ -483,7 +484,7 @@ describe('_submissionsColumns', () => { }; const submissions = exportService._submissionsColumns(form, params); - expect(submissions.length).toEqual(9); + expect(submissions.length).toEqual(10); }); it('should return right number of columns, when 1 prefered column (draft) passed as params.', async () => { @@ -497,7 +498,7 @@ describe('_submissionsColumns', () => { }; const submissions = exportService._submissionsColumns(form, params); - expect(submissions.length).toEqual(9); + expect(submissions.length).toEqual(10); }); it('should return right number of columns, when 2 prefered column (draft & deleted) passed as params.', async () => { @@ -511,7 +512,8 @@ describe('_submissionsColumns', () => { }; const submissions = exportService._submissionsColumns(form, params); - expect(submissions.length).toEqual(10); + + expect(submissions.length).toEqual(11); }); it('should return right number of columns, when a garbage or NON-allowed column (testCol1 & testCol2) passed as params.', async () => { @@ -525,7 +527,7 @@ describe('_submissionsColumns', () => { }; const submissions = exportService._submissionsColumns(form, params); - expect(submissions.length).toEqual(8); + expect(submissions.length).toEqual(9); }); }); diff --git a/app/tests/unit/forms/form/service.spec.js b/app/tests/unit/forms/form/service.spec.js index 17fc0cf98..d7eee486d 100644 --- a/app/tests/unit/forms/form/service.spec.js +++ b/app/tests/unit/forms/form/service.spec.js @@ -417,7 +417,7 @@ describe('processPaginationData', () => { modify: () => jest.fn().mockReturnThis(), }; }); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 10, false, 0, null, false); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 10, 0, null, false); expect(result.results).toHaveLength(10); expect(result.total).toEqual(SubmissionData.length); }); @@ -432,7 +432,7 @@ describe('processPaginationData', () => { modify: () => jest.fn().mockReturnThis(), }; }); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, false, 0, null, false); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, 0, null, false); expect(result.results).toHaveLength(5); expect(result.total).toEqual(SubmissionData.length); }); @@ -447,29 +447,29 @@ describe('processPaginationData', () => { modify: () => jest.fn().mockReturnThis(), }; }); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 1, 5, false, 0, null, false); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 1, 5, 0, null, false); expect(result.results).toHaveLength(5); expect(result.total).toEqual(SubmissionData.length); }); it('search submission data with pagination base on datetime', async () => { MockModel.query.mockImplementation((data) => data); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, false, 0, '2023-08-19T19:11', true); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, 0, '2023-08-19T19:11', true); expect(result.results).toHaveLength(3); expect(result.total).toEqual(3); }); it('search submission data with pagination base on any value (first page)', async () => { MockModel.query.mockImplementation((data) => data); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, false, 0, 'a', true); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 5, 0, 'a', true); expect(result.results).toHaveLength(5); }); it('search submission data with pagination base on any value (second page)', async () => { MockModel.query.mockImplementation((data) => data); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 1, 5, false, 0, 'a', true); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 1, 5, 0, 'a', true); expect(result.results).toHaveLength(5); }); it('search submission data with pagination base on any value (test for case)', async () => { MockModel.query.mockImplementation((data) => data); - let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 10, false, 0, 'A', true); + let result = await service.processPaginationData(MockModel.query(SubmissionData), 0, 10, 0, 'A', true); expect(result.results).toHaveLength(10); }); }); diff --git a/tests/load/load-test/index.js b/tests/load/load-test/index.js index f83e8b6e1..30434a403 100644 --- a/tests/load/load-test/index.js +++ b/tests/load/load-test/index.js @@ -73,7 +73,9 @@ const getToken = async () => { return new Promise((resolve, reject) => { const start = performance.now(); - const endpoint = `${auth.host}/realms/${auth.realm}/protocol/openid-connect/token`; + const endpoint = config.get('auth.host').startsWith('https://') + ? `${auth.host}/auth/realms/${auth.realm}/protocol/openid-connect/token` + : `${auth.host}/realms/${auth.realm}/protocol/openid-connect/token`; const postData = `grant_type=password&client_id=${auth.clientId}&username=${auth.username}&password=${auth.password}`; const options = { @@ -142,6 +144,7 @@ const createForm = async (token, schema) => { }, }; + log.debug(`${apiPath()}/forms`); const req = http.request(`${apiPath()}/forms`, options, (res) => { let data = ''; diff --git a/tests/load/load-test/package-lock.json b/tests/load/load-test/package-lock.json index 0c5cb72b4..a824911be 100644 --- a/tests/load/load-test/package-lock.json +++ b/tests/load/load-test/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "bytes": "^3.1.2", "config": "^3.3.9", - "jsonwebtoken": "^9.0.0", + "jsonwebtoken": "^9.0.2", "npmlog": "^7.0.1" } }, @@ -226,14 +226,20 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "engines": { "node": ">=12", @@ -259,10 +265,40 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -336,9 +372,9 @@ ] }, "node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -537,14 +573,20 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "requires": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" } }, "jwa": { @@ -566,10 +608,40 @@ "safe-buffer": "^5.0.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "lru-cache": { "version": "6.0.0", @@ -617,9 +689,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } diff --git a/tests/load/load-test/package.json b/tests/load/load-test/package.json index 1a2c5abfa..6de9c87a9 100644 --- a/tests/load/load-test/package.json +++ b/tests/load/load-test/package.json @@ -14,7 +14,7 @@ "dependencies": { "bytes": "^3.1.2", "config": "^3.3.9", - "jsonwebtoken": "^9.0.0", + "jsonwebtoken": "^9.0.2", "npmlog": "^7.0.1" } }