From 067814e2170c997900b0c18f9ae437d041f60ebb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:00:41 +0000 Subject: [PATCH 001/258] build(deps): bump @nestjs/platform-express from 10.3.8 to 10.3.9 Bumps [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) from 10.3.8 to 10.3.9. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.9/packages/platform-express) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c26d183b..ea38b27ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2446,9 +2446,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.3.8", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.8.tgz", - "integrity": "sha512-sifLoxgEJvAgbim1UuW6wyScMfkS9SVQRH+lN33N/9ZvZSjO6NSDLOe+wxqsnZkia+QrjFC0qy0ITRAsggfqbg==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.9.tgz", + "integrity": "sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", From a15ed99353527c3139f1a08f527b2231033ea26e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:11:12 +0000 Subject: [PATCH 002/258] build(deps-dev): bump prettier from 3.2.5 to 3.3.0 Bumps [prettier](https://github.com/prettier/prettier) from 3.2.5 to 3.3.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.2.5...3.3.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea38b27ca..fca8fe0bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11658,9 +11658,9 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From 8247274781707ec67d785f3cb202138e1687d749 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:21:58 +0000 Subject: [PATCH 003/258] build(deps): bump mongoose from 8.4.0 to 8.4.1 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.0 to 8.4.1. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.0...8.4.1) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fca8fe0bd..f1d8fd245 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10755,9 +10755,9 @@ } }, "node_modules/mongoose": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.0.tgz", - "integrity": "sha512-fgqRMwVEP1qgRYfh+tUe2YBBFnPO35FIg2lfFH+w9IhRGg1/ataWGIqvf/MjwM29cZ60D5vSnqtN2b8Qp0sOZA==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.1.tgz", + "integrity": "sha512-odQ2WEWGL3hb0Qex+QMN4eH6D34WdMEw7F1If2MGABApSDmG9cMmqv/G1H6WsXmuaH9mkuuadW/WbLE5+tHJwA==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From acfc19e05e93102aab0ebe920a22597c48f0499d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:32:36 +0000 Subject: [PATCH 004/258] build(deps): bump @nestjs/common from 10.3.8 to 10.3.9 Bumps [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) from 10.3.8 to 10.3.9. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.9/packages/common) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1d8fd245..5cdf71d2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2293,9 +2293,9 @@ } }, "node_modules/@nestjs/common": { - "version": "10.3.8", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.8.tgz", - "integrity": "sha512-P+vPEIvqx2e+fonsYVlFXKvoChyJ8Tq+lfpqdVFqblovHbFr3kZ/nYX0cPs+XuW6bnRT8tz0SSR9XBGU43kJhw==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.9.tgz", + "integrity": "sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.2", From 16e48ab0e6e04dd23c7d8ecf29a786bc58a61b51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:43:00 +0000 Subject: [PATCH 005/258] build(deps-dev): bump @nestjs/testing from 10.3.8 to 10.3.9 Bumps [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) from 10.3.8 to 10.3.9. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.9/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5cdf71d2f..d93b11001 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2589,9 +2589,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.3.8", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.8.tgz", - "integrity": "sha512-hpX9das2TdFTKQ4/2ojhjI6YgXtCfXRKui3A4Qaj54VVzc5+mtK502Jj18Vzji98o9MVS6skmYu+S/UvW3U6Fw==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.9.tgz", + "integrity": "sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg==", "dev": true, "dependencies": { "tslib": "2.6.2" From 8413b9a9b6ea2dd390059df857af5c01e5007119 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:53:31 +0000 Subject: [PATCH 006/258] build(deps-dev): bump @types/node from 20.12.12 to 20.14.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.12 to 20.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d93b11001..ef54fca75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3140,9 +3140,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "20.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz", + "integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==", "dependencies": { "undici-types": "~5.26.4" } From ddebcd118ebb67fca7473e271ef7bb8be9fa6c8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:03:55 +0000 Subject: [PATCH 007/258] build(deps-dev): bump @typescript-eslint/parser from 7.10.0 to 7.11.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.10.0 to 7.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.11.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef54fca75..d612c46d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3365,15 +3365,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", - "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4" }, "engines": { @@ -3392,6 +3392,105 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", From 6677b27086c1d5bee4dfc32fea5ebd9791945d73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:14:09 +0000 Subject: [PATCH 008/258] build(deps): bump swagger-ui-express from 5.0.0 to 5.0.1 Bumps [swagger-ui-express](https://github.com/scottie1984/swagger-ui-express) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/scottie1984/swagger-ui-express/releases) - [Commits](https://github.com/scottie1984/swagger-ui-express/compare/5.0.0...5.0.1) --- updated-dependencies: - dependency-name: swagger-ui-express dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d612c46d4..2ea9d452f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13250,9 +13250,9 @@ "integrity": "sha512-jQG0cRgJNMZ7aCoiFofnoojeSaa/+KgWaDlfgs8QN+BXoGMpxeMVY5OEnjq4OlNvF3yjftO8c9GRAgcHlO+u7A==" }, "node_modules/swagger-ui-express": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", - "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz", + "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==", "dependencies": { "swagger-ui-dist": ">=5.0.0" }, From af3428a0c9bb2648cc2c9b09dbfafb9c3c615daf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:24:38 +0000 Subject: [PATCH 009/258] build(deps): bump @nestjs/core from 10.3.8 to 10.3.9 Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 10.3.8 to 10.3.9. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.9/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2ea9d452f..eb60cfb4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2336,9 +2336,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.3.8", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.8.tgz", - "integrity": "sha512-AxF4tpYLDNn5Wfb3C4bNaaHJ4pREH5FJrSisR2A5zkYpQFORFs0Tc36lOFPMwBTy8Iv2wUwWLUVc5ftBnxEv4w==", + "version": "10.3.9", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.9.tgz", + "integrity": "sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", From a69a91c8b6b66bdecfe59f1325d13722786ee385 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:39:33 +0000 Subject: [PATCH 010/258] build(deps-dev): bump @typescript-eslint/parser from 7.11.0 to 7.12.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.11.0 to 7.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.12.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb60cfb4a..b33b947df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3365,15 +3365,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", - "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.12.0.tgz", + "integrity": "sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.11.0", - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/typescript-estree": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "debug": "^4.3.4" }, "engines": { @@ -3393,13 +3393,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", - "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz", + "integrity": "sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0" + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3410,9 +3410,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", - "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", + "integrity": "sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3423,13 +3423,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", - "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz", + "integrity": "sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3451,12 +3451,12 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", - "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", + "integrity": "sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/types": "7.12.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From d29fe4758d95679594344af0082bc81c4207410e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:50:02 +0000 Subject: [PATCH 011/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.10.0 to 7.12.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.12.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 161 +++++++++------------------------------------- 1 file changed, 31 insertions(+), 130 deletions(-) diff --git a/package-lock.json b/package-lock.json index b33b947df..b21deb34d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3332,16 +3332,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", - "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.12.0.tgz", + "integrity": "sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/type-utils": "7.10.0", - "@typescript-eslint/utils": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/type-utils": "7.12.0", + "@typescript-eslint/utils": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3392,7 +3392,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz", "integrity": "sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==", @@ -3409,113 +3409,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", - "integrity": "sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz", - "integrity": "sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.12.0", - "@typescript-eslint/visitor-keys": "7.12.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", - "integrity": "sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.12.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", - "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", - "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.12.0.tgz", + "integrity": "sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/typescript-estree": "7.12.0", + "@typescript-eslint/utils": "7.12.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3536,9 +3437,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", - "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", + "integrity": "sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3549,13 +3450,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", - "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz", + "integrity": "sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3601,15 +3502,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.12.0.tgz", + "integrity": "sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/typescript-estree": "7.12.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3623,12 +3524,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", - "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", + "integrity": "sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/types": "7.12.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From fd9bdcdb677a56d3b681fd1a819de534a9811660 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:00:48 +0000 Subject: [PATCH 012/258] build(deps-dev): bump prettier from 3.3.0 to 3.3.1 Bumps [prettier](https://github.com/prettier/prettier) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.0...3.3.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b21deb34d..475d331d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11658,9 +11658,9 @@ } }, "node_modules/prettier": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", - "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz", + "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From c357a435774e0592ed387f06e298e8f5c59c44b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:11:10 +0000 Subject: [PATCH 013/258] build(deps-dev): bump @types/lodash from 4.17.4 to 4.17.5 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.4 to 4.17.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 475d331d8..888a39f99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3095,9 +3095,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==", + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", "dev": true }, "node_modules/@types/luxon": { From bca6f4cb514c20521efa29f998e0b533a435f7c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:21:53 +0000 Subject: [PATCH 014/258] build(deps-dev): bump @types/node from 20.14.0 to 20.14.2 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.0 to 20.14.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 888a39f99..5c39a07c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3140,9 +3140,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz", - "integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dependencies": { "undici-types": "~5.26.4" } From ba083938ac3ce4f067c92aa10bb963be2c2a46b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:32:24 +0000 Subject: [PATCH 015/258] build(deps): bump mathjs from 12.4.2 to 13.0.0 Bumps [mathjs](https://github.com/josdejong/mathjs) from 12.4.2 to 13.0.0. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v12.4.2...v13.0.0) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5c39a07c6..a09a2e6a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "handlebars": "^4.7.7", "lodash": "^4.17.21", "luxon": "^3.2.1", - "mathjs": "^12.0.0", + "mathjs": "^13.0.0", "migrate-mongo": "^11.0.0", "mongoose": "^8.4.0", "node-fetch": "^3.3.0", @@ -882,9 +882,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -7199,9 +7199,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", - "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "engines": { "node": "*" }, @@ -9831,15 +9831,15 @@ } }, "node_modules/mathjs": { - "version": "12.4.2", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.2.tgz", - "integrity": "sha512-lW14EzwAFgbNN7AZikxplmhs7wiXDhMphBOGCA3KS6T29ECEkHJsBtbEW5cnCz7sXtl4nDyvTdR+DqVsZyiiEw==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.0.tgz", + "integrity": "sha512-Jy9/01M5lTRLxlkxnvPmvWq6EFwzq8guIspeQ9p66AY+8Pih3Jf8Us5fSZ9kC8gl7iRNHUQ+SJpitX41aa6agw==", "dependencies": { - "@babel/runtime": "^7.24.4", + "@babel/runtime": "^7.24.6", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", - "fraction.js": "4.3.4", + "fraction.js": "^4.3.7", "javascript-natural-sort": "^0.7.1", "seedrandom": "^3.0.5", "tiny-emitter": "^2.1.0", diff --git a/package.json b/package.json index 65b1ff50f..df21e0c71 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "handlebars": "^4.7.7", "lodash": "^4.17.21", "luxon": "^3.2.1", - "mathjs": "^12.0.0", + "mathjs": "^13.0.0", "migrate-mongo": "^11.0.0", "mongoose": "^8.4.0", "node-fetch": "^3.3.0", From 6787f8043f9415bcf4b36f95a946351ea3d0a668 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:16:22 +0000 Subject: [PATCH 016/258] build(deps): bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index a09a2e6a9..f2a5cb9da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4529,12 +4529,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -6929,9 +6929,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" From a49f31e2808677ddbd2285523423a647fb6b4af7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:26:56 +0000 Subject: [PATCH 017/258] build(deps): bump uuid from 9.0.1 to 10.0.0 Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.1 to 10.0.0. - [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md) - [Commits](https://github.com/uuidjs/uuid/compare/v9.0.1...v10.0.0) --- updated-dependencies: - dependency-name: uuid dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 33 +++++++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2a5cb9da..f954723e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "rimraf": "^5.0.0", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", - "uuid": "^9.0.0" + "uuid": "^10.0.0" }, "devDependencies": { "@faker-js/faker": "^8.0.1", @@ -2335,6 +2335,18 @@ "rxjs": "^7.1.0" } }, + "node_modules/@nestjs/config/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@nestjs/core": { "version": "10.3.9", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.9.tgz", @@ -11732,6 +11744,19 @@ "node": ">=14" } }, + "node_modules/preview-email/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -13918,9 +13943,9 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/package.json b/package.json index df21e0c71..30adafafa 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "rimraf": "^5.0.0", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", - "uuid": "^9.0.0" + "uuid": "^10.0.0" }, "overrides": { "pac-resolver": { From 5b76b1f109a7fdb6cffa7f98370c5c9d67c609be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:09:35 +0000 Subject: [PATCH 018/258] build(deps-dev): bump prettier from 3.3.1 to 3.3.2 Bumps [prettier](https://github.com/prettier/prettier) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.1...3.3.2) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f954723e2..772b247b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11670,9 +11670,9 @@ } }, "node_modules/prettier": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz", - "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From 1b4f6e200e2d29a94920c06f832d79a498d5ae95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:20:08 +0000 Subject: [PATCH 019/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.12.0 to 7.13.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 264 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 246 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 772b247b3..666324692 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3344,16 +3344,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.12.0.tgz", - "integrity": "sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", + "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.12.0", - "@typescript-eslint/type-utils": "7.12.0", - "@typescript-eslint/utils": "7.12.0", - "@typescript-eslint/visitor-keys": "7.12.0", + "@typescript-eslint/scope-manager": "7.13.0", + "@typescript-eslint/type-utils": "7.13.0", + "@typescript-eslint/utils": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3376,6 +3376,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", + "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", + "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", + "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.12.0.tgz", @@ -3422,13 +3469,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.12.0.tgz", - "integrity": "sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", + "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.12.0", - "@typescript-eslint/utils": "7.12.0", + "@typescript-eslint/typescript-estree": "7.13.0", + "@typescript-eslint/utils": "7.13.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3448,6 +3495,88 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", + "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", + "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", + "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", @@ -3514,15 +3643,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.12.0.tgz", - "integrity": "sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", + "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.12.0", - "@typescript-eslint/types": "7.12.0", - "@typescript-eslint/typescript-estree": "7.12.0" + "@typescript-eslint/scope-manager": "7.13.0", + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/typescript-estree": "7.13.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3535,6 +3664,105 @@ "eslint": "^8.56.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", + "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", + "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", + "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", + "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", From c7f9ea2f849d9cbd405f1cdb769bd772c2894a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:30:34 +0000 Subject: [PATCH 020/258] build(deps-dev): bump @typescript-eslint/parser from 7.12.0 to 7.13.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.12.0 to 7.13.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 256 +++------------------------------------------- 1 file changed, 14 insertions(+), 242 deletions(-) diff --git a/package-lock.json b/package-lock.json index 666324692..ddd8da63c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3376,63 +3376,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", + "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "7.13.0", "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.12.0.tgz", - "integrity": "sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.12.0", - "@typescript-eslint/types": "7.12.0", - "@typescript-eslint/typescript-estree": "7.12.0", - "@typescript-eslint/visitor-keys": "7.12.0", + "@typescript-eslint/typescript-estree": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", "debug": "^4.3.4" }, "engines": { @@ -3452,13 +3405,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz", - "integrity": "sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", + "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.12.0", - "@typescript-eslint/visitor-keys": "7.12.0" + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3495,7 +3448,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", @@ -3508,7 +3461,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", @@ -3536,88 +3489,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", - "integrity": "sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz", - "integrity": "sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.12.0", - "@typescript-eslint/visitor-keys": "7.12.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3664,65 +3535,7 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", - "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", @@ -3739,47 +3552,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", - "integrity": "sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.12.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ucast/core": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", From ef7c1fb92f285c9f499ce788526d694862ed749b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:55:00 +0000 Subject: [PATCH 021/258] build(deps): bump docker/build-push-action from 5 to 6 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-release.yaml | 2 +- .github/workflows/deploy.yml | 2 +- .github/workflows/github-tag-and-release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-release.yaml b/.github/workflows/build-release.yaml index 35865481b..8ca6af829 100644 --- a/.github/workflows/build-release.yaml +++ b/.github/workflows/build-release.yaml @@ -33,7 +33,7 @@ jobs: type=ref,event=tag - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: true diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 018ee476f..627b603d2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: tags: type=sha,format=long,prefix= # adds : tag to outputs.tags - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64/v8 diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index 8512df323..80d5fe2e2 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -69,7 +69,7 @@ jobs: type=raw,value={{date 'YYYY_MM'}},prefix=r_ - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: true From 16ee8a50f69928dad7d6456808a9a65a33f09494 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 19:45:02 +0000 Subject: [PATCH 022/258] build(deps-dev): bump ws from 7.5.9 to 7.5.10 Bumps [ws](https://github.com/websockets/ws) from 7.5.9 to 7.5.10. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.5.9...7.5.10) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ddd8da63c..aac25a593 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14542,9 +14542,9 @@ "dev": true }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" From 6284016a3d2c2106813596bc92c9424beb7f1aaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:55:49 +0000 Subject: [PATCH 023/258] build(deps): bump nodemailer from 6.9.3 to 6.9.14 Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.9.3 to 6.9.14. - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v6.9.3...v6.9.14) --- updated-dependencies: - dependency-name: nodemailer dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index aac25a593..185a1ef60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10978,9 +10978,9 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.9.13", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.13.tgz", - "integrity": "sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==", + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", + "integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==", "engines": { "node": ">=6.0.0" } From 9d69b4a6f4ee5487e53749f9f8853facc1afd78c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:54:24 +0000 Subject: [PATCH 024/258] build(deps-dev): bump @types/mocha from 10.0.6 to 10.0.7 Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.6 to 10.0.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha) --- updated-dependencies: - dependency-name: "@types/mocha" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 185a1ef60..69fed08bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3146,9 +3146,9 @@ "optional": true }, "node_modules/@types/mocha": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", "dev": true }, "node_modules/@types/node": { From 5846aaca81384872df70ddadcc5e32f118324639 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:05:01 +0000 Subject: [PATCH 025/258] build(deps-dev): bump @types/node from 20.14.2 to 20.14.8 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.2 to 20.14.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69fed08bb..bc3dfddaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3152,9 +3152,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", - "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "version": "20.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", + "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", "dependencies": { "undici-types": "~5.26.4" } From fd479daf2a21a3fd0c3eb165eb00bb11f9141fce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:15:04 +0000 Subject: [PATCH 026/258] build(deps): bump mongoose from 8.4.1 to 8.4.3 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.1 to 8.4.3. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.1...8.4.3) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bc3dfddaf..cbbb77b45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10767,9 +10767,9 @@ } }, "node_modules/mongoose": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.1.tgz", - "integrity": "sha512-odQ2WEWGL3hb0Qex+QMN4eH6D34WdMEw7F1If2MGABApSDmG9cMmqv/G1H6WsXmuaH9mkuuadW/WbLE5+tHJwA==", + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.3.tgz", + "integrity": "sha512-GxPVLD+I/dxVkgcts2r2QmJJvS62/++btVj3RFt8YnHt+DSOp1Qjj62YEvgZaElwIOTcc4KGJM95X5LlrU1qQg==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From 2a05042015479646d3bd5195fa9116e7e66ac939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:25:24 +0000 Subject: [PATCH 027/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.13.0 to 7.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 264 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 246 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index cbbb77b45..10aebecfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3344,16 +3344,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", - "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", + "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/type-utils": "7.13.0", - "@typescript-eslint/utils": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/type-utils": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3376,6 +3376,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", @@ -3422,13 +3469,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", - "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", + "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/utils": "7.13.0", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/utils": "7.13.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3448,6 +3495,88 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", @@ -3514,15 +3643,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", - "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", + "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0" + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3535,6 +3664,105 @@ "eslint": "^8.56.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", From 1c1ba2f6d2b795d77a37afae64555097130b3713 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:35:52 +0000 Subject: [PATCH 028/258] build(deps-dev): bump @typescript-eslint/parser from 7.13.0 to 7.13.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.13.0 to 7.13.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.13.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 256 +++------------------------------------------- 1 file changed, 14 insertions(+), 242 deletions(-) diff --git a/package-lock.json b/package-lock.json index 10aebecfb..d4e4cc9b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3376,63 +3376,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", + "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "7.13.1", "@typescript-eslint/types": "7.13.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", - "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.13.0", - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/typescript-estree": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", "debug": "^4.3.4" }, "engines": { @@ -3452,13 +3405,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", - "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0" + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3495,7 +3448,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", @@ -3508,7 +3461,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", @@ -3536,88 +3489,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", - "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", - "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "@typescript-eslint/visitor-keys": "7.13.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3664,65 +3535,7 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", @@ -3739,47 +3552,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", - "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ucast/core": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", From 75136b0aeb3493f9cb80743d0e83785d6fa02991 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:46:34 +0000 Subject: [PATCH 029/258] build(deps-dev): bump @types/uuid from 9.0.8 to 10.0.0 Bumps [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) from 9.0.8 to 10.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid) --- updated-dependencies: - dependency-name: "@types/uuid" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4e4cc9b2..eb3cfed35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,7 +69,7 @@ "@types/passport-jwt": "^4.0.0", "@types/passport-local": "^1.0.34", "@types/supertest": "^6.0.1", - "@types/uuid": "^9.0.0", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.3.0", "@typescript-eslint/parser": "^7.3.0", "chai": "^5.0.0", @@ -3305,9 +3305,9 @@ } }, "node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, "node_modules/@types/validator": { diff --git a/package.json b/package.json index 30adafafa..ed5b6f9fb 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@types/passport-jwt": "^4.0.0", "@types/passport-local": "^1.0.34", "@types/supertest": "^6.0.1", - "@types/uuid": "^9.0.0", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.3.0", "@typescript-eslint/parser": "^7.3.0", "chai": "^5.0.0", From 255ee9e8406e87954611a0227465c210dcd604dc Mon Sep 17 00:00:00 2001 From: Yoganandan Pandiyan <132274772+yoganandaness@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:38:57 +0200 Subject: [PATCH 030/258] fix: Added Docker support for ARM 64. (#1283) --- .github/workflows/build-release.yaml | 1 + .github/workflows/github-tag-and-release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build-release.yaml b/.github/workflows/build-release.yaml index 8ca6af829..c6e51b436 100644 --- a/.github/workflows/build-release.yaml +++ b/.github/workflows/build-release.yaml @@ -36,5 +36,6 @@ jobs: uses: docker/build-push-action@v6 with: context: . + platforms: linux/amd64,linux/arm64/v8 push: true tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index 80d5fe2e2..4d422b7dc 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -72,5 +72,6 @@ jobs: uses: docker/build-push-action@v6 with: context: . + platforms: linux/amd64,linux/arm64/v8 push: true tags: ${{ steps.meta.outputs.tags }} From ee89a9676a3c778cfd03d1e83e1f641a549ec8d7 Mon Sep 17 00:00:00 2001 From: Ian Bush Date: Wed, 26 Jun 2024 13:17:50 +0100 Subject: [PATCH 031/258] Add MongoDB index to dataset property in attachments --- src/attachments/schemas/attachment.schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attachments/schemas/attachment.schema.ts b/src/attachments/schemas/attachment.schema.ts index e23d13d97..d7203fe78 100644 --- a/src/attachments/schemas/attachment.schema.ts +++ b/src/attachments/schemas/attachment.schema.ts @@ -43,7 +43,7 @@ export class Attachment extends OwnableClass { caption: string; @ApiProperty({ type: String, required: false }) - @Prop({ type: String, ref: "Dataset", required: false }) + @Prop({ type: String, ref: "Dataset", index: true, required: false }) datasetId: string; @ApiProperty({ type: String, required: false }) From bdca3ec8c59ba949077a10100355eef6c4fd4f69 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 27 Jun 2024 16:06:20 +0200 Subject: [PATCH 032/258] first version of backwar compatible full query --- .github/ISSUE_TEMPLATE/issue-.md | 19 ------------- src/common/scientific-relation.enum.ts | 1 + src/common/utils.ts | 39 ++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 22 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/issue-.md diff --git a/.github/ISSUE_TEMPLATE/issue-.md b/.github/ISSUE_TEMPLATE/issue-.md deleted file mode 100644 index 60f04d42d..000000000 --- a/.github/ISSUE_TEMPLATE/issue-.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: 'Issue ' -about: Describe this issue purpose here. - ---- - -## Issue Name - -### Summary - -### Steps to Reproduce - -### Current Behaviour - -### Expected Behaviour - -### Extra Details - -Here you should include details about the system (if it is unique) and possible information about a fix (feel free to link to code where relevant). Screenshots/GIFs are also fine here. diff --git a/src/common/scientific-relation.enum.ts b/src/common/scientific-relation.enum.ts index 1eb550bf0..e9acf37b9 100644 --- a/src/common/scientific-relation.enum.ts +++ b/src/common/scientific-relation.enum.ts @@ -3,4 +3,5 @@ export enum ScientificRelation { EQUAL_TO_NUMERIC = "EQUAL_TO_NUMERIC", GREATER_THAN = "GREATER_THAN", LESS_THAN = "LESS_THAN", + CONTAINS_STRING = "CONTAINS_STRING", } diff --git a/src/common/utils.ts b/src/common/utils.ts index 7e16add43..d6feb520d 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -86,13 +86,29 @@ export const convertToRequestedUnit = ( }; }; +const buildCondition = ( + key: string, + value: string | number, + operator: string, +): Record => { + const conditions: Record = { $or: [] }; + conditions["$or"] = ["", ".v", ".value"].map((suffix) => { + return { + [`${key}${suffix}`]: { [`${operator}`]: value }, + }; + }); + return conditions; +}; + export const mapScientificQuery = ( key: string, scientific: IScientificFilter[] = [], ): Record => { const scientificFilterQuery: Record = {}; + const scientificFilterQueryOr: Record[] = []; const keyToFieldMapping: Record = { + scientificMetadata: "scientificMetadata", scientific: "scientificMetadata", characteristics: "sampleCharacteristics", }; @@ -112,7 +128,9 @@ export const mapScientificQuery = ( switch (relation) { case ScientificRelation.EQUAL_TO_STRING: { - scientificFilterQuery[`${matchKeyGeneric}.value`] = { $eq: rhs }; + scientificFilterQueryOr.push( + buildCondition(matchKeyGeneric, rhs, "$eq"), + ); break; } case ScientificRelation.EQUAL_TO_NUMERIC: { @@ -131,7 +149,9 @@ export const mapScientificQuery = ( scientificFilterQuery[matchKeyMeasurement] = { $gt: valueSI }; scientificFilterQuery[matchUnit] = { $eq: unitSI }; } else { - scientificFilterQuery[`${matchKeyGeneric}.value`] = { $gt: rhs }; + scientificFilterQueryOr.push( + buildCondition(matchKeyGeneric, rhs, "$gt"), + ); } break; } @@ -141,12 +161,25 @@ export const mapScientificQuery = ( scientificFilterQuery[matchKeyMeasurement] = { $lt: valueSI }; scientificFilterQuery[matchUnit] = { $eq: unitSI }; } else { - scientificFilterQuery[`${matchKeyGeneric}.value`] = { $lt: rhs }; + scientificFilterQueryOr.push( + buildCondition(matchKeyGeneric, rhs, "$lt"), + ); } break; } + case ScientificRelation.CONTAINS_STRING: { + scientificFilterQueryOr.push( + buildCondition(matchKeyGeneric, rhs, `/${rhs}/`), + ); + break; + } } }); + if (scientificFilterQueryOr.length == 1) { + scientificFilterQuery["$or"] = scientificFilterQueryOr[0]["$or"]; + } else if (scientificFilterQueryOr.length > 1) { + scientificFilterQuery["$and"] = scientificFilterQueryOr; + } return scientificFilterQuery; }; From bd900520d65b9f8ae1606ae01992b68ed1014bac Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 27 Jun 2024 16:26:02 +0200 Subject: [PATCH 033/258] fixed unit tests --- src/samples/samples.service.spec.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/samples/samples.service.spec.ts b/src/samples/samples.service.spec.ts index 9425bec06..1933161b4 100644 --- a/src/samples/samples.service.spec.ts +++ b/src/samples/samples.service.spec.ts @@ -91,9 +91,23 @@ describe("SamplesService", () => { $text: { $search: "test", }, - "sampleCharacteristics.test.value": { - $eq: "test", - }, + $or: [ + { + "sampleCharacteristics.test": { + $eq: "test", + }, + }, + { + "sampleCharacteristics.test.v": { + $eq: "test", + }, + }, + { + "sampleCharacteristics.test.value": { + $eq: "test", + }, + }, + ], }; await service.fullquery(filter); From 61be0dd562c56b22498d351bcd7b1b676e35f0e1 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 27 Jun 2024 16:52:54 +0200 Subject: [PATCH 034/258] Update README.md (#1292) --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 1a150b78f..29f8d3337 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,15 @@ The repo for backend v3.x is archived and read-only If you have any questions, please feel free to contact any member of the development team, or the SciCat team at ESS. +## Contributing +If you're planning to contribute to this project by adding new functionality, we encourage you to discuss it first in the Discussions tab. This helps ensure that your proposed changes align with the project's goals and prevents duplicate efforts. Here's how you can initiate a discussion: + +1. Go to the [Discussions tab](https://github.com/SciCatProject/scicat-backend-next/discussions). +2. Start a new discussion thread outlining your proposed changes. +3. Wait for feedback and consensus before proceeding with creating a pull request. + +Thank you for your interest in contributing to our project! + ## Get started 1. `git clone https://github.com/SciCatProject/scicat-backend-next.git` From f0486fad19c94cbb9e23e024a28e17a2100d8f34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 15:37:11 +0000 Subject: [PATCH 035/258] build(deps): bump mongoose from 8.4.3 to 8.4.4 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.3 to 8.4.4. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.3...8.4.4) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb3cfed35..57123f5e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10767,9 +10767,9 @@ } }, "node_modules/mongoose": { - "version": "8.4.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.3.tgz", - "integrity": "sha512-GxPVLD+I/dxVkgcts2r2QmJJvS62/++btVj3RFt8YnHt+DSOp1Qjj62YEvgZaElwIOTcc4KGJM95X5LlrU1qQg==", + "version": "8.4.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.4.tgz", + "integrity": "sha512-Nya808odIJoHP4JuJKbWA2eIaerXieu59kE8pQlvJpUBoSKWUyhLji0g1WMVaYXWmzPYXP2Jd6XdR4KJE8RELw==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From 5e16854a210157e1285959c15279ea3e7f6914d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 15:50:31 +0000 Subject: [PATCH 036/258] build(deps-dev): bump @typescript-eslint/parser from 7.13.1 to 7.14.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.13.1 to 7.14.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.14.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57123f5e8..54604f4d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3377,15 +3377,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4" }, "engines": { @@ -3404,6 +3404,105 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", From 1342f1fc36b0d873045f52b4d07c49588cb0930d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:02:38 +0000 Subject: [PATCH 037/258] build(deps): bump @nestjs/core from 10.3.9 to 10.3.10 Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 10.3.9 to 10.3.10. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.10/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54604f4d8..ab9c9f0c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2348,16 +2348,16 @@ } }, "node_modules/@nestjs/core": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.9.tgz", - "integrity": "sha512-NzZUfWAmaf8sqhhwoRA+CuqxQe+P4Rz8PZp5U7CdCbjyeB9ZVGcBkihcJC9wMdtiOWHRndB2J8zRfs5w06jK3w==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.10.tgz", + "integrity": "sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "3.2.0", - "tslib": "2.6.2", + "tslib": "2.6.3", "uid": "2.0.2" }, "funding": { @@ -2384,6 +2384,11 @@ } } }, + "node_modules/@nestjs/core/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@nestjs/elasticsearch": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@nestjs/elasticsearch/-/elasticsearch-10.0.1.tgz", From 19f87fa4fbb0f67e52572eb5c0961fab0184a121 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:13:07 +0000 Subject: [PATCH 038/258] build(deps-dev): bump @nestjs/testing from 10.3.9 to 10.3.10 Bumps [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) from 10.3.9 to 10.3.10. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.10/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab9c9f0c7..56df43883 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2606,12 +2606,12 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.9.tgz", - "integrity": "sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.10.tgz", + "integrity": "sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==", "dev": true, "dependencies": { - "tslib": "2.6.2" + "tslib": "2.6.3" }, "funding": { "type": "opencollective", @@ -2632,6 +2632,12 @@ } } }, + "node_modules/@nestjs/testing/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", From a4b8fbe1583816bf0b55f835733bba4443b6c2ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:23:31 +0000 Subject: [PATCH 039/258] build(deps): bump mathjs from 13.0.0 to 13.0.1 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.0.0 to 13.0.1. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.0.0...v13.0.1) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56df43883..2440ba6e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9953,11 +9953,11 @@ } }, "node_modules/mathjs": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.0.tgz", - "integrity": "sha512-Jy9/01M5lTRLxlkxnvPmvWq6EFwzq8guIspeQ9p66AY+8Pih3Jf8Us5fSZ9kC8gl7iRNHUQ+SJpitX41aa6agw==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.1.tgz", + "integrity": "sha512-38IzJ/MY0erNp7apXJp6DZwUYHOuvlqRqk2KtMo9GPqrTmCaLb1vTzw/Fib3PessXEMs52wnJaga0pd9xkIjjA==", "dependencies": { - "@babel/runtime": "^7.24.6", + "@babel/runtime": "^7.24.7", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", @@ -9965,7 +9965,7 @@ "javascript-natural-sort": "^0.7.1", "seedrandom": "^3.0.5", "tiny-emitter": "^2.1.0", - "typed-function": "^4.1.1" + "typed-function": "^4.2.1" }, "bin": { "mathjs": "bin/cli.js" @@ -13870,11 +13870,11 @@ } }, "node_modules/typed-function": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.1.tgz", - "integrity": "sha512-Pq1DVubcvibmm8bYcMowjVnnMwPVMeh0DIdA8ad8NZY2sJgapANJmiigSUwlt+EgXxpfIv8MWrQXTIzkfYZLYQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/typedarray": { From 36a8b6799c15044ea3d0cff565afc85329b78962 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:33:48 +0000 Subject: [PATCH 040/258] build(deps): bump @nestjs/config from 3.2.2 to 3.2.3 Bumps [@nestjs/config](https://github.com/nestjs/config) from 3.2.2 to 3.2.3. - [Release notes](https://github.com/nestjs/config/releases) - [Changelog](https://github.com/nestjs/config/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/config/compare/3.2.2...3.2.3) --- updated-dependencies: - dependency-name: "@nestjs/config" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2440ba6e1..7c3736333 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2321,32 +2321,19 @@ } }, "node_modules/@nestjs/config": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.2.2.tgz", - "integrity": "sha512-vGICPOui5vE6kPz1iwQ7oCnp3qWgqxldPmBQ9onkVoKlBtyc83KJCr7CjuVtf4OdovMAVcux1d8Q6jglU2ZphA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.2.3.tgz", + "integrity": "sha512-p6yv/CvoBewJ72mBq4NXgOAi2rSQNWx3a+IMJLVKS2uiwFCOQQuiIatGwq6MRjXV3Jr+B41iUO8FIf4xBrZ4/w==", "dependencies": { "dotenv": "16.4.5", "dotenv-expand": "10.0.0", - "lodash": "4.17.21", - "uuid": "9.0.1" + "lodash": "4.17.21" }, "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "rxjs": "^7.1.0" } }, - "node_modules/@nestjs/config/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@nestjs/core": { "version": "10.3.10", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.10.tgz", From 1d52ca77fe5749f1b900c9456d0b0db4064e3a92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:44:09 +0000 Subject: [PATCH 041/258] build(deps-dev): bump mocha from 10.4.0 to 10.5.2 Bumps [mocha](https://github.com/mochajs/mocha) from 10.4.0 to 10.5.2. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.4.0...v10.5.2) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c3736333..9a4d9f626 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10619,14 +10619,14 @@ } }, "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.5.2.tgz", + "integrity": "sha512-9btlN3JKCefPf+vKd/kcKz2SXxi12z6JswkGfaAF0saQvnsqLJk504ZmbxhSoENge08E9dsymozKgFMTl5PQsA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.3", + "chokidar": "^3.5.3", "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", From dae0ec7d6314df4dcc28dbd38838579f869f6786 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:54:19 +0000 Subject: [PATCH 042/258] build(deps): bump @nestjs/platform-express from 10.3.9 to 10.3.10 Bumps [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) from 10.3.9 to 10.3.10. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.10/packages/platform-express) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a4d9f626..c4d2e3c7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2450,15 +2450,15 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.9.tgz", - "integrity": "sha512-si/UzobP6YUtYtCT1cSyQYHHzU3yseqYT6l7OHSMVvfG1+TqxaAqI6nmrix02LO+l1YntHRXEs3p+v9a7EfrSQ==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.10.tgz", + "integrity": "sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", "express": "4.19.2", "multer": "1.4.4-lts.1", - "tslib": "2.6.2" + "tslib": "2.6.3" }, "funding": { "type": "opencollective", @@ -2469,6 +2469,11 @@ "@nestjs/core": "^10.0.0" } }, + "node_modules/@nestjs/platform-express/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@nestjs/schematics": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.1.tgz", From cbe095980d5c2f02ec6c966c5d6dbe3c4ccf2172 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:04:42 +0000 Subject: [PATCH 043/258] build(deps): bump @nestjs/common from 10.3.9 to 10.3.10 Bumps [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) from 10.3.9 to 10.3.10. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.3.10/packages/common) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4d2e3c7c..8ce895a46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2293,12 +2293,12 @@ } }, "node_modules/@nestjs/common": { - "version": "10.3.9", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.9.tgz", - "integrity": "sha512-JAQONPagMa+sy/fcIqh/Hn3rkYQ9pQM51vXCFNOM5ujefxUVqn3gwFRMN8Y1+MxdUHipV+8daEj2jEm0IqJzOA==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.10.tgz", + "integrity": "sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.6.2", + "tslib": "2.6.3", "uid": "2.0.2" }, "funding": { @@ -2371,11 +2371,6 @@ } } }, - "node_modules/@nestjs/core/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@nestjs/elasticsearch": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@nestjs/elasticsearch/-/elasticsearch-10.0.1.tgz", @@ -2469,11 +2464,6 @@ "@nestjs/core": "^10.0.0" } }, - "node_modules/@nestjs/platform-express/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, "node_modules/@nestjs/schematics": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.1.tgz", @@ -2624,12 +2614,6 @@ } } }, - "node_modules/@nestjs/testing/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -13813,9 +13797,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-check": { "version": "0.4.0", From 64f046553fabde51c86703c6be2016f76b68f453 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:15:03 +0000 Subject: [PATCH 044/258] build(deps): bump @nestjs/swagger from 7.3.1 to 7.4.0 Bumps [@nestjs/swagger](https://github.com/nestjs/swagger) from 7.3.1 to 7.4.0. - [Release notes](https://github.com/nestjs/swagger/releases) - [Changelog](https://github.com/nestjs/swagger/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/swagger/compare/7.3.1...7.4.0) --- updated-dependencies: - dependency-name: "@nestjs/swagger" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ce895a46..530ea3df2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2039,9 +2039,9 @@ } }, "node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==" + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==" }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.5", @@ -2487,16 +2487,16 @@ "dev": true }, "node_modules/@nestjs/swagger": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.3.1.tgz", - "integrity": "sha512-LUC4mr+5oAleEC/a2j8pNRh1S5xhKXJ1Gal5ZdRjt9XebQgbngXCdW7JTA9WOEcwGtFZN9EnKYdquzH971LZfw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", + "integrity": "sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==", "dependencies": { - "@microsoft/tsdoc": "^0.14.2", + "@microsoft/tsdoc": "^0.15.0", "@nestjs/mapped-types": "2.0.5", "js-yaml": "4.1.0", "lodash": "4.17.21", "path-to-regexp": "3.2.0", - "swagger-ui-dist": "5.11.2" + "swagger-ui-dist": "5.17.14" }, "peerDependencies": { "@fastify/static": "^6.0.0 || ^7.0.0", @@ -13257,9 +13257,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.2.tgz", - "integrity": "sha512-jQG0cRgJNMZ7aCoiFofnoojeSaa/+KgWaDlfgs8QN+BXoGMpxeMVY5OEnjq4OlNvF3yjftO8c9GRAgcHlO+u7A==" + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" }, "node_modules/swagger-ui-express": { "version": "5.0.1", From a6f09d1e80d8022e1ac06dcee7d030e79a5c1b92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:25:10 +0000 Subject: [PATCH 045/258] build(deps-dev): bump @types/lodash from 4.17.5 to 4.17.6 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.5 to 4.17.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 530ea3df2..fe07a54e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3094,9 +3094,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", + "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", "dev": true }, "node_modules/@types/luxon": { From 8064149fb30e8c9a81ac28cf4a257e255416d5ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:31:43 +0000 Subject: [PATCH 046/258] build(deps): bump rimraf from 5.0.7 to 5.0.8 Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.7 to 5.0.8. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.7...v5.0.8) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe07a54e2..f8103b478 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12317,9 +12317,9 @@ } }, "node_modules/rimraf": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", - "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", + "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", "dependencies": { "glob": "^10.3.7" }, @@ -12327,7 +12327,7 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14.18" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" From f9f7c25a0344c97660d43910c8cc2d2ec47f342a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:41:41 +0000 Subject: [PATCH 047/258] build(deps): bump dependabot/fetch-metadata from 2.1.0 to 2.2.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge-dependabot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge-dependabot.yaml b/.github/workflows/auto-merge-dependabot.yaml index 5ceef930d..c9fc4b674 100644 --- a/.github/workflows/auto-merge-dependabot.yaml +++ b/.github/workflows/auto-merge-dependabot.yaml @@ -15,7 +15,7 @@ jobs: ## Extract information about the dependencies being updated by a Dependabot-generated PR - name: Dependabot metadata id: dependabot-metadata - uses: dependabot/fetch-metadata@v2.1.0 + uses: dependabot/fetch-metadata@v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 1e8b799d332b9b36fe9779208a14f1b536768be0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:42:22 +0000 Subject: [PATCH 048/258] build(deps-dev): bump @types/node from 20.14.8 to 20.14.10 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.8 to 20.14.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f8103b478..22cd1ae9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3139,9 +3139,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "dependencies": { "undici-types": "~5.26.4" } From dea95d1bc500b0b0d741c71ddf40e6588787694c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:53:12 +0000 Subject: [PATCH 049/258] build(deps): bump @nestjs/mongoose from 10.0.6 to 10.0.10 Bumps [@nestjs/mongoose](https://github.com/nestjs/mongoose) from 10.0.6 to 10.0.10. - [Release notes](https://github.com/nestjs/mongoose/releases) - [Changelog](https://github.com/nestjs/mongoose/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/mongoose/compare/10.0.6...10.0.10) --- updated-dependencies: - dependency-name: "@nestjs/mongoose" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22cd1ae9d..a69480799 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2425,9 +2425,9 @@ } }, "node_modules/@nestjs/mongoose": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-10.0.6.tgz", - "integrity": "sha512-J8jFgSvCDEKMXU57QAIdXIlWQsOFWK+x0PM1KI/0zHe3/4JrAtFGTFD08hRX3IHk+WJT9g/XQIpMSNM7/10Jlg==", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-10.0.10.tgz", + "integrity": "sha512-3Ff60ock8nwlAJC823TG91Qy+Qc6av+ddIb6n6wlFsTK0akDF/aTcagX8cF8uI8mWxCWjEwEsgv99vo6p0yJ+w==", "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", From 8cd8b60c395a07f7ea78dbfb3270a1144ce08edb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:03:24 +0000 Subject: [PATCH 050/258] build(deps-dev): bump mocha from 10.5.2 to 10.6.0 Bumps [mocha](https://github.com/mochajs/mocha) from 10.5.2 to 10.6.0. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.5.2...v10.6.0) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 107 +++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index a69480799..7d5b1e702 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5643,9 +5643,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -5974,9 +5974,9 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -10608,31 +10608,31 @@ } }, "node_modules/mocha": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.5.2.tgz", - "integrity": "sha512-9btlN3JKCefPf+vKd/kcKz2SXxi12z6JswkGfaAF0saQvnsqLJk504ZmbxhSoENge08E9dsymozKgFMTl5PQsA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -10642,15 +10642,6 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -10682,9 +10673,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10759,9 +10750,9 @@ } }, "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" @@ -12671,9 +12662,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -12848,15 +12839,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -13423,15 +13405,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -14568,9 +14541,9 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { From 12fedba360318c29f3e5ce7790ce70a424aeacbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:13:53 +0000 Subject: [PATCH 051/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.13.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 76 +++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d5b1e702..9e5419cfe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3331,16 +3331,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", + "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/type-utils": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3491,13 +3491,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", + "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3508,13 +3508,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", + "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/utils": "7.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3535,9 +3535,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3548,13 +3548,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", + "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3585,9 +3585,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -3600,15 +3600,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", + "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3622,12 +3622,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", + "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.15.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From f0611f9b89798f8cca320d3d9bc9a7162154e229 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:24:04 +0000 Subject: [PATCH 052/258] build(deps): bump mathjs from 13.0.1 to 13.0.2 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.0.1 to 13.0.2. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.0.1...v13.0.2) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e5419cfe..9dc673e82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9929,9 +9929,9 @@ } }, "node_modules/mathjs": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.1.tgz", - "integrity": "sha512-38IzJ/MY0erNp7apXJp6DZwUYHOuvlqRqk2KtMo9GPqrTmCaLb1vTzw/Fib3PessXEMs52wnJaga0pd9xkIjjA==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.2.tgz", + "integrity": "sha512-8vK/+InU4FTphRTWsrnvRsgSjbyNupRQYDDIXLuEGDZtJsGdbA9dVV4HZ0amBQb+RXplRjVJNGZZfB0WoHWFWA==", "dependencies": { "@babel/runtime": "^7.24.7", "complex.js": "^2.1.1", From d6863d3cbaeb8a485d392d04c3fe2d93d38c8f36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:34:44 +0000 Subject: [PATCH 053/258] build(deps): bump mongoose from 8.4.4 to 8.4.5 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.4 to 8.4.5. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.4...8.4.5) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9dc673e82..802951039 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10844,9 +10844,9 @@ } }, "node_modules/mongoose": { - "version": "8.4.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.4.tgz", - "integrity": "sha512-Nya808odIJoHP4JuJKbWA2eIaerXieu59kE8pQlvJpUBoSKWUyhLji0g1WMVaYXWmzPYXP2Jd6XdR4KJE8RELw==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.5.tgz", + "integrity": "sha512-E5KjBThxST2uFSKKXuiMa9H9Zx4DLTSLuxodAnIzJRixNwc1ARTlJUK1m0a80EB+ZKGP4QNTasyUYRG9DUSHOA==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From a0e8e71c299a8e395412291e5260c795d68dd44c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:45:14 +0000 Subject: [PATCH 054/258] build(deps-dev): bump @nestjs/schematics from 10.1.1 to 10.1.2 Bumps [@nestjs/schematics](https://github.com/nestjs/schematics) from 10.1.1 to 10.1.2. - [Release notes](https://github.com/nestjs/schematics/releases) - [Changelog](https://github.com/nestjs/schematics/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/schematics/compare/10.1.1...10.1.2) --- updated-dependencies: - dependency-name: "@nestjs/schematics" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 95 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 802951039..36aac3762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2465,27 +2465,108 @@ } }, "node_modules/@nestjs/schematics": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.1.tgz", - "integrity": "sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.2.tgz", + "integrity": "sha512-S0bMtZM5U4mAiqkhRyZkXgjmOHBS5P/lp/vEydgMR4F7csOShc3jFeKVs1Eghd9xCFezGKy3SHy7hFT6dpPhWQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", "comment-json": "4.2.3", - "jsonc-parser": "3.2.1", + "jsonc-parser": "3.3.1", "pluralize": "8.0.0" }, "peerDependencies": { "typescript": ">=4.8.2" } }, - "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", + "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core/node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", + "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.3.8", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, + "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/schematics/node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@nestjs/swagger": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", From c6044ee8feb6bd727d9bd60d2be14f0dfce771cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:55:32 +0000 Subject: [PATCH 055/258] build(deps-dev): bump @typescript-eslint/parser from 7.14.1 to 7.15.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.14.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++------------------------------------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36aac3762..f12c1ee8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3445,15 +3445,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "debug": "^4.3.4" }, "engines": { @@ -3472,105 +3472,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", From 9248b3e8e48da5892db0f0f3824f105e310b41fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:05:55 +0000 Subject: [PATCH 056/258] build(deps-dev): bump @nestjs/cli from 10.3.2 to 10.4.2 Bumps [@nestjs/cli](https://github.com/nestjs/nest-cli) from 10.3.2 to 10.4.2. - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/10.3.2...10.4.2) --- updated-dependencies: - dependency-name: "@nestjs/cli" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 602 +++++++++++++++------------------------------- 1 file changed, 197 insertions(+), 405 deletions(-) diff --git a/package-lock.json b/package-lock.json index f12c1ee8e..2d85451a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -128,15 +128,15 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.1.2.tgz", - "integrity": "sha512-ku+/W/HMCBacSWFppenr9y6Lx8mDuTuQvn1IkTyBLiJOpWnzgVbx9kHDeaDchGa1PwLlJUBBrv27t3qgJOIDPw==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", + "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", "dev": true, "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "picomatch": "3.0.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", "rxjs": "7.8.1", "source-map": "0.7.4" }, @@ -155,26 +155,26 @@ } }, "node_modules/@angular-devkit/core/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@angular-devkit/schematics": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.1.2.tgz", - "integrity": "sha512-8S9RuM8olFN/gwN+mjbuF1CwHX61f0i59EGXz9tXLnKRUTjsRR+8vVMTAmX0dvVAT5fJTG/T69X+HX7FeumdqA==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", + "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.5", + "@angular-devkit/core": "17.3.8", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", "ora": "5.4.1", "rxjs": "7.8.1" }, @@ -185,15 +185,15 @@ } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.1.2.tgz", - "integrity": "sha512-bvXykYzSST05qFdlgIzUguNOb3z0hCa8HaTwtqdmQo9aFPf+P+/AC56I64t1iTchMjQtf3JrBQhYM25gUdcGbg==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.3.8.tgz", + "integrity": "sha512-TjmiwWJarX7oqvNiRAroQ5/LeKUatxBOCNEuKXO/PV8e7pn/Hr/BqfFm+UcYrQoFdZplmtNAfqmbqgVziKvCpA==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", "ansi-colors": "4.1.3", - "inquirer": "9.2.12", + "inquirer": "9.2.15", "symbol-observable": "4.0.0", "yargs-parser": "21.1.1" }, @@ -227,47 +227,19 @@ "node": ">= 12" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "9.2.12", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.12.tgz", - "integrity": "sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==", + "version": "9.2.15", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", + "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", "dev": true, "dependencies": { - "@ljharb/through": "^2.3.11", + "@ljharb/through": "^2.3.12", "ansi-escapes": "^4.3.2", "chalk": "^5.3.0", "cli-cursor": "^3.1.0", "cli-width": "^4.1.0", "external-editor": "^3.1.0", - "figures": "^5.0.0", + "figures": "^3.2.0", "lodash": "^4.17.21", "mute-stream": "1.0.0", "ora": "^5.4.1", @@ -278,19 +250,7 @@ "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { @@ -1929,12 +1889,12 @@ } }, "node_modules/@ljharb/through": { - "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", + "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -2139,32 +2099,29 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.3.2.tgz", - "integrity": "sha512-aWmD1GLluWrbuC4a1Iz/XBk5p74Uj6nIVZj6Ov03JbTfgtWqGFLtXuMetvzMiHxfrHehx/myt2iKAPRhKdZvTg==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.2.tgz", + "integrity": "sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", - "@angular-devkit/schematics-cli": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", + "@angular-devkit/schematics-cli": "17.3.8", "@nestjs/schematics": "^10.0.1", "chalk": "4.1.2", "chokidar": "3.6.0", - "cli-table3": "0.6.3", + "cli-table3": "0.6.5", "commander": "4.1.1", "fork-ts-checker-webpack-plugin": "9.0.2", - "glob": "10.3.10", + "glob": "10.4.2", "inquirer": "8.2.6", "node-emoji": "1.11.0", "ora": "5.4.1", - "rimraf": "4.4.1", - "shelljs": "0.8.5", - "source-map-support": "0.5.21", "tree-kill": "1.2.2", "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.90.1", + "webpack": "5.92.1", "webpack-node-externals": "3.0.0" }, "bin": { @@ -2174,7 +2131,7 @@ "node": ">= 16.14" }, "peerDependencies": { - "@swc/cli": "^0.1.62 || ^0.3.0", + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0", "@swc/core": "^1.3.62" }, "peerDependenciesMeta": { @@ -2186,15 +2143,6 @@ } } }, - "node_modules/@nestjs/cli/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/@nestjs/cli/node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2219,66 +2167,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/@nestjs/cli/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@nestjs/cli/node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -2480,93 +2368,12 @@ "typescript": ">=4.8.2" } }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core/node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", - "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "jsonc-parser": "3.2.1", - "magic-string": "0.30.8", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, - "node_modules/@nestjs/schematics/node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@nestjs/schematics/node_modules/picomatch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", - "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@nestjs/swagger": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", @@ -3685,9 +3492,9 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -3707,9 +3514,9 @@ "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { @@ -3730,15 +3537,15 @@ "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { @@ -3766,28 +3573,28 @@ "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", @@ -3795,24 +3602,24 @@ } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -3821,12 +3628,12 @@ } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -3904,10 +3711,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -4782,13 +4589,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5142,9 +4954,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dependencies": { "string-width": "^4.2.0" }, @@ -5859,16 +5671,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -6236,9 +6051,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -6269,6 +6084,17 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -7431,11 +7257,11 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.3.tgz", - "integrity": "sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "es-errors": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -7482,21 +7308,22 @@ } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7528,10 +7355,27 @@ "balanced-match": "^1.0.0" } }, + "node_modules/glob/node_modules/jackspeak": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", + "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7657,11 +7501,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8006,15 +7850,6 @@ "node": ">=12.0.0" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/ip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", @@ -9365,9 +9200,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, "node_modules/jsonfile": { @@ -9789,9 +9624,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -10094,9 +9929,9 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -11378,6 +11213,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/param-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", @@ -11552,15 +11392,15 @@ "devOptional": true }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -12141,18 +11981,6 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/reflect-metadata": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", @@ -12672,15 +12500,16 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12719,43 +12548,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -14147,9 +13939,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -14354,26 +14146,26 @@ } }, "node_modules/webpack": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", - "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -14381,7 +14173,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { From 07cb98cbd924122115e76bbe3a5298fde1ceb77d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:26:21 +0000 Subject: [PATCH 057/258] build(deps-dev): bump prettier from 3.3.2 to 3.3.3 Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d85451a2..888d7bc4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11569,9 +11569,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From 2a0ab93b4e0dcc16ab72dfc14e076d904ada9f08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:37:04 +0000 Subject: [PATCH 058/258] build(deps-dev): bump @typescript-eslint/parser from 7.15.0 to 7.16.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 888d7bc4c..2d66c8628 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3252,15 +3252,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", - "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", + "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "debug": "^4.3.4" }, "engines": { @@ -3279,6 +3279,105 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", From 2d5f05161b9a30904bcdfa0cddd82c3089b0b689 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:47:57 +0000 Subject: [PATCH 059/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 161 +++++++++------------------------------------- 1 file changed, 31 insertions(+), 130 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d66c8628..7fe878175 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3219,16 +3219,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", + "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/type-utils": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3279,7 +3279,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", @@ -3296,113 +3296,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", - "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", + "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/utils": "7.16.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3423,9 +3324,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", - "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3436,13 +3337,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", - "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3488,15 +3389,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", + "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3510,12 +3411,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", - "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/types": "7.16.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From e09d93296a213d3583c554d0b2202f70cef33d66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:58:40 +0000 Subject: [PATCH 060/258] build(deps): bump mongoose from 8.4.5 to 8.5.1 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.5 to 8.5.1. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.5...8.5.1) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7fe878175..686adc9b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10576,9 +10576,9 @@ } }, "node_modules/mongodb": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz", - "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", + "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -10661,13 +10661,13 @@ } }, "node_modules/mongoose": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.5.tgz", - "integrity": "sha512-E5KjBThxST2uFSKKXuiMa9H9Zx4DLTSLuxodAnIzJRixNwc1ARTlJUK1m0a80EB+ZKGP4QNTasyUYRG9DUSHOA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", + "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.6.2", + "mongodb": "6.7.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", From 0f65c81de1ce82c10f4e0a0102c07a4e73b9ac0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:09:27 +0000 Subject: [PATCH 061/258] build(deps): bump rimraf from 5.0.8 to 6.0.1 Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.8 to 6.0.1. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.8...v6.0.1) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 101 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 686adc9b9..ab3e36fbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "passport-ldapauth": "^3.0.1", "passport-local": "^1.0.0", "reflect-metadata": "^0.2.2", - "rimraf": "^5.0.0", + "rimraf": "^6.0.1", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", "uuid": "^10.0.0" @@ -7311,6 +7311,7 @@ "version": "10.4.2", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "devOptional": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -7351,6 +7352,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -7359,6 +7361,7 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "devOptional": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -7376,6 +7379,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "devOptional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -12118,17 +12122,102 @@ } }, "node_modules/rimraf": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", - "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", "dependencies": { - "glob": "^10.3.7" + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=18" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" diff --git a/package.json b/package.json index ed5b6f9fb..62021d8b6 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "passport-ldapauth": "^3.0.1", "passport-local": "^1.0.0", "reflect-metadata": "^0.2.2", - "rimraf": "^5.0.0", + "rimraf": "^6.0.1", "rxjs": "^7.5.7", "swagger-ui-express": "^5.0.0", "uuid": "^10.0.0" From 03414a54130919a3386a629a4f569e91481f16fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:41:41 +0000 Subject: [PATCH 062/258] build(deps): bump dependabot/fetch-metadata from 2.1.0 to 2.2.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge-dependabot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge-dependabot.yaml b/.github/workflows/auto-merge-dependabot.yaml index 5ceef930d..c9fc4b674 100644 --- a/.github/workflows/auto-merge-dependabot.yaml +++ b/.github/workflows/auto-merge-dependabot.yaml @@ -15,7 +15,7 @@ jobs: ## Extract information about the dependencies being updated by a Dependabot-generated PR - name: Dependabot metadata id: dependabot-metadata - uses: dependabot/fetch-metadata@v2.1.0 + uses: dependabot/fetch-metadata@v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From e4bd7fd0be1d4cfb06fc7edd5620d3a545c3a910 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:31:43 +0000 Subject: [PATCH 063/258] build(deps): bump rimraf from 5.0.7 to 5.0.8 Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.7 to 5.0.8. - [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/rimraf/compare/v5.0.7...v5.0.8) --- updated-dependencies: - dependency-name: rimraf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe07a54e2..f8103b478 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12317,9 +12317,9 @@ } }, "node_modules/rimraf": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", - "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.8.tgz", + "integrity": "sha512-XSh0V2/yNhDEi8HwdIefD8MLgs4LQXPag/nEJWs3YUc3Upn+UHa1GyIkEg9xSSNt7HnkO5FjTvmcRzgf+8UZuw==", "dependencies": { "glob": "^10.3.7" }, @@ -12327,7 +12327,7 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14.18" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" From b0ffbbe41653241dc31e7ba075b4c221aa753048 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:42:22 +0000 Subject: [PATCH 064/258] build(deps-dev): bump @types/node from 20.14.8 to 20.14.10 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.8 to 20.14.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f8103b478..22cd1ae9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3139,9 +3139,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "dependencies": { "undici-types": "~5.26.4" } From e52910477457eb80c6937b15a6e797f0a8b29718 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:53:12 +0000 Subject: [PATCH 065/258] build(deps): bump @nestjs/mongoose from 10.0.6 to 10.0.10 Bumps [@nestjs/mongoose](https://github.com/nestjs/mongoose) from 10.0.6 to 10.0.10. - [Release notes](https://github.com/nestjs/mongoose/releases) - [Changelog](https://github.com/nestjs/mongoose/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/mongoose/compare/10.0.6...10.0.10) --- updated-dependencies: - dependency-name: "@nestjs/mongoose" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22cd1ae9d..a69480799 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2425,9 +2425,9 @@ } }, "node_modules/@nestjs/mongoose": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-10.0.6.tgz", - "integrity": "sha512-J8jFgSvCDEKMXU57QAIdXIlWQsOFWK+x0PM1KI/0zHe3/4JrAtFGTFD08hRX3IHk+WJT9g/XQIpMSNM7/10Jlg==", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-10.0.10.tgz", + "integrity": "sha512-3Ff60ock8nwlAJC823TG91Qy+Qc6av+ddIb6n6wlFsTK0akDF/aTcagX8cF8uI8mWxCWjEwEsgv99vo6p0yJ+w==", "peerDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", From 4eb6ee6a51cb71db19b1ba350f8413fe6a6d598b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:03:24 +0000 Subject: [PATCH 066/258] build(deps-dev): bump mocha from 10.5.2 to 10.6.0 Bumps [mocha](https://github.com/mochajs/mocha) from 10.5.2 to 10.6.0. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.5.2...v10.6.0) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 107 +++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index a69480799..7d5b1e702 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5643,9 +5643,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -5974,9 +5974,9 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -10608,31 +10608,31 @@ } }, "node_modules/mocha": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.5.2.tgz", - "integrity": "sha512-9btlN3JKCefPf+vKd/kcKz2SXxi12z6JswkGfaAF0saQvnsqLJk504ZmbxhSoENge08E9dsymozKgFMTl5PQsA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -10642,15 +10642,6 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -10682,9 +10673,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10759,9 +10750,9 @@ } }, "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" @@ -12671,9 +12662,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -12848,15 +12839,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -13423,15 +13405,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -14568,9 +14541,9 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { From 8158cac6c06a8aca0fa3e5724c5f1fc896c078a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:13:53 +0000 Subject: [PATCH 067/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.13.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 76 +++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d5b1e702..9e5419cfe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3331,16 +3331,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", + "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/type-utils": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3491,13 +3491,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", + "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3508,13 +3508,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", + "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/utils": "7.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3535,9 +3535,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3548,13 +3548,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", + "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3585,9 +3585,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -3600,15 +3600,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", + "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3622,12 +3622,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", + "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.15.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From 4410298330f9abd1a9256ecc9d7eda6b03215379 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:24:04 +0000 Subject: [PATCH 068/258] build(deps): bump mathjs from 13.0.1 to 13.0.2 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.0.1 to 13.0.2. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.0.1...v13.0.2) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e5419cfe..9dc673e82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9929,9 +9929,9 @@ } }, "node_modules/mathjs": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.1.tgz", - "integrity": "sha512-38IzJ/MY0erNp7apXJp6DZwUYHOuvlqRqk2KtMo9GPqrTmCaLb1vTzw/Fib3PessXEMs52wnJaga0pd9xkIjjA==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.2.tgz", + "integrity": "sha512-8vK/+InU4FTphRTWsrnvRsgSjbyNupRQYDDIXLuEGDZtJsGdbA9dVV4HZ0amBQb+RXplRjVJNGZZfB0WoHWFWA==", "dependencies": { "@babel/runtime": "^7.24.7", "complex.js": "^2.1.1", From 5f0bc695ef12759b7785756df7bb0d1b9d7d7161 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:34:44 +0000 Subject: [PATCH 069/258] build(deps): bump mongoose from 8.4.4 to 8.4.5 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.4 to 8.4.5. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.4...8.4.5) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9dc673e82..802951039 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10844,9 +10844,9 @@ } }, "node_modules/mongoose": { - "version": "8.4.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.4.tgz", - "integrity": "sha512-Nya808odIJoHP4JuJKbWA2eIaerXieu59kE8pQlvJpUBoSKWUyhLji0g1WMVaYXWmzPYXP2Jd6XdR4KJE8RELw==", + "version": "8.4.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.5.tgz", + "integrity": "sha512-E5KjBThxST2uFSKKXuiMa9H9Zx4DLTSLuxodAnIzJRixNwc1ARTlJUK1m0a80EB+ZKGP4QNTasyUYRG9DUSHOA==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From 5190531f28332cea9d2ff7dd601afcca87de3067 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:45:14 +0000 Subject: [PATCH 070/258] build(deps-dev): bump @nestjs/schematics from 10.1.1 to 10.1.2 Bumps [@nestjs/schematics](https://github.com/nestjs/schematics) from 10.1.1 to 10.1.2. - [Release notes](https://github.com/nestjs/schematics/releases) - [Changelog](https://github.com/nestjs/schematics/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/schematics/compare/10.1.1...10.1.2) --- updated-dependencies: - dependency-name: "@nestjs/schematics" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 95 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 802951039..36aac3762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2465,27 +2465,108 @@ } }, "node_modules/@nestjs/schematics": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.1.tgz", - "integrity": "sha512-o4lfCnEeIkfJhGBbLZxTuVWcGuqDCFwg5OrvpgRUBM7vI/vONvKKiB5riVNpO+JqXoH0I42NNeDb0m4V5RREig==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.2.tgz", + "integrity": "sha512-S0bMtZM5U4mAiqkhRyZkXgjmOHBS5P/lp/vEydgMR4F7csOShc3jFeKVs1Eghd9xCFezGKy3SHy7hFT6dpPhWQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", "comment-json": "4.2.3", - "jsonc-parser": "3.2.1", + "jsonc-parser": "3.3.1", "pluralize": "8.0.0" }, "peerDependencies": { "typescript": ">=4.8.2" } }, - "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", + "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core/node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", + "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.3.8", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, + "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/schematics/node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@nestjs/swagger": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", From e92e58fdaaf6a19d994456d5943176811165f342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:55:32 +0000 Subject: [PATCH 071/258] build(deps-dev): bump @typescript-eslint/parser from 7.14.1 to 7.15.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.14.1 to 7.15.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.15.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++------------------------------------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36aac3762..f12c1ee8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3445,15 +3445,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", "debug": "^4.3.4" }, "engines": { @@ -3472,105 +3472,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", From e9138690d8b58b62017fe39b372b47775f128980 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:05:55 +0000 Subject: [PATCH 072/258] build(deps-dev): bump @nestjs/cli from 10.3.2 to 10.4.2 Bumps [@nestjs/cli](https://github.com/nestjs/nest-cli) from 10.3.2 to 10.4.2. - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/10.3.2...10.4.2) --- updated-dependencies: - dependency-name: "@nestjs/cli" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 602 +++++++++++++++------------------------------- 1 file changed, 197 insertions(+), 405 deletions(-) diff --git a/package-lock.json b/package-lock.json index f12c1ee8e..2d85451a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -128,15 +128,15 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.1.2.tgz", - "integrity": "sha512-ku+/W/HMCBacSWFppenr9y6Lx8mDuTuQvn1IkTyBLiJOpWnzgVbx9kHDeaDchGa1PwLlJUBBrv27t3qgJOIDPw==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", + "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", "dev": true, "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "picomatch": "3.0.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", "rxjs": "7.8.1", "source-map": "0.7.4" }, @@ -155,26 +155,26 @@ } }, "node_modules/@angular-devkit/core/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@angular-devkit/schematics": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.1.2.tgz", - "integrity": "sha512-8S9RuM8olFN/gwN+mjbuF1CwHX61f0i59EGXz9tXLnKRUTjsRR+8vVMTAmX0dvVAT5fJTG/T69X+HX7FeumdqA==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", + "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.5", + "@angular-devkit/core": "17.3.8", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", "ora": "5.4.1", "rxjs": "7.8.1" }, @@ -185,15 +185,15 @@ } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "17.1.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.1.2.tgz", - "integrity": "sha512-bvXykYzSST05qFdlgIzUguNOb3z0hCa8HaTwtqdmQo9aFPf+P+/AC56I64t1iTchMjQtf3JrBQhYM25gUdcGbg==", + "version": "17.3.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.3.8.tgz", + "integrity": "sha512-TjmiwWJarX7oqvNiRAroQ5/LeKUatxBOCNEuKXO/PV8e7pn/Hr/BqfFm+UcYrQoFdZplmtNAfqmbqgVziKvCpA==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", "ansi-colors": "4.1.3", - "inquirer": "9.2.12", + "inquirer": "9.2.15", "symbol-observable": "4.0.0", "yargs-parser": "21.1.1" }, @@ -227,47 +227,19 @@ "node": ">= 12" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "9.2.12", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.12.tgz", - "integrity": "sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==", + "version": "9.2.15", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", + "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", "dev": true, "dependencies": { - "@ljharb/through": "^2.3.11", + "@ljharb/through": "^2.3.12", "ansi-escapes": "^4.3.2", "chalk": "^5.3.0", "cli-cursor": "^3.1.0", "cli-width": "^4.1.0", "external-editor": "^3.1.0", - "figures": "^5.0.0", + "figures": "^3.2.0", "lodash": "^4.17.21", "mute-stream": "1.0.0", "ora": "^5.4.1", @@ -278,19 +250,7 @@ "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { @@ -1929,12 +1889,12 @@ } }, "node_modules/@ljharb/through": { - "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", + "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -2139,32 +2099,29 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.3.2.tgz", - "integrity": "sha512-aWmD1GLluWrbuC4a1Iz/XBk5p74Uj6nIVZj6Ov03JbTfgtWqGFLtXuMetvzMiHxfrHehx/myt2iKAPRhKdZvTg==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.2.tgz", + "integrity": "sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.1.2", - "@angular-devkit/schematics": "17.1.2", - "@angular-devkit/schematics-cli": "17.1.2", + "@angular-devkit/core": "17.3.8", + "@angular-devkit/schematics": "17.3.8", + "@angular-devkit/schematics-cli": "17.3.8", "@nestjs/schematics": "^10.0.1", "chalk": "4.1.2", "chokidar": "3.6.0", - "cli-table3": "0.6.3", + "cli-table3": "0.6.5", "commander": "4.1.1", "fork-ts-checker-webpack-plugin": "9.0.2", - "glob": "10.3.10", + "glob": "10.4.2", "inquirer": "8.2.6", "node-emoji": "1.11.0", "ora": "5.4.1", - "rimraf": "4.4.1", - "shelljs": "0.8.5", - "source-map-support": "0.5.21", "tree-kill": "1.2.2", "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.90.1", + "webpack": "5.92.1", "webpack-node-externals": "3.0.0" }, "bin": { @@ -2174,7 +2131,7 @@ "node": ">= 16.14" }, "peerDependencies": { - "@swc/cli": "^0.1.62 || ^0.3.0", + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0", "@swc/core": "^1.3.62" }, "peerDependenciesMeta": { @@ -2186,15 +2143,6 @@ } } }, - "node_modules/@nestjs/cli/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/@nestjs/cli/node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2219,66 +2167,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/@nestjs/cli/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@nestjs/cli/node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -2480,93 +2368,12 @@ "typescript": ">=4.8.2" } }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.8.tgz", - "integrity": "sha512-Q8q0voCGudbdCgJ7lXdnyaxKHbNQBARH68zPQV72WT8NWy+Gw/tys870i6L58NWbBaCJEUcIj/kb6KoakSRu+Q==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core/node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { - "version": "17.3.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.8.tgz", - "integrity": "sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "17.3.8", - "jsonc-parser": "3.2.1", - "magic-string": "0.30.8", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, - "node_modules/@nestjs/schematics/node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@nestjs/schematics/node_modules/picomatch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", - "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@nestjs/swagger": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.0.tgz", @@ -3685,9 +3492,9 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -3707,9 +3514,9 @@ "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { @@ -3730,15 +3537,15 @@ "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { @@ -3766,28 +3573,28 @@ "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", @@ -3795,24 +3602,24 @@ } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -3821,12 +3628,12 @@ } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -3904,10 +3711,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -4782,13 +4589,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5142,9 +4954,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dependencies": { "string-width": "^4.2.0" }, @@ -5859,16 +5671,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -6236,9 +6051,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -6269,6 +6084,17 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -7431,11 +7257,11 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.3.tgz", - "integrity": "sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "es-errors": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -7482,21 +7308,22 @@ } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7528,10 +7355,27 @@ "balanced-match": "^1.0.0" } }, + "node_modules/glob/node_modules/jackspeak": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", + "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7657,11 +7501,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8006,15 +7850,6 @@ "node": ">=12.0.0" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/ip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", @@ -9365,9 +9200,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, "node_modules/jsonfile": { @@ -9789,9 +9624,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -10094,9 +9929,9 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -11378,6 +11213,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/param-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", @@ -11552,15 +11392,15 @@ "devOptional": true }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -12141,18 +11981,6 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/reflect-metadata": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", @@ -12672,15 +12500,16 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12719,43 +12548,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -14147,9 +13939,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -14354,26 +14146,26 @@ } }, "node_modules/webpack": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", - "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -14381,7 +14173,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { From 0dc264cadcda9054a81416e8adc39772681c3120 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:26:21 +0000 Subject: [PATCH 073/258] build(deps-dev): bump prettier from 3.3.2 to 3.3.3 Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d85451a2..888d7bc4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11569,9 +11569,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From 38f2fc3f93deddac3ba454cda37cb3a522c6bdd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:37:04 +0000 Subject: [PATCH 074/258] build(deps-dev): bump @typescript-eslint/parser from 7.15.0 to 7.16.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 888d7bc4c..2d66c8628 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3252,15 +3252,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", - "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", + "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "debug": "^4.3.4" }, "engines": { @@ -3279,6 +3279,105 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", From 2dde5c8d46eac790fb16cbb08bd28f86ef121c23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:47:57 +0000 Subject: [PATCH 075/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.15.0 to 7.16.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 161 +++++++++------------------------------------- 1 file changed, 31 insertions(+), 130 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d66c8628..7fe878175 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3219,16 +3219,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", + "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/type-utils": "7.16.0", + "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3279,7 +3279,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", @@ -3296,113 +3296,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", - "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", + "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/typescript-estree": "7.16.0", + "@typescript-eslint/utils": "7.16.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3423,9 +3324,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", - "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3436,13 +3337,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", - "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/visitor-keys": "7.16.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3488,15 +3389,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", + "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" + "@typescript-eslint/scope-manager": "7.16.0", + "@typescript-eslint/types": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3510,12 +3411,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", - "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/types": "7.16.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From 0b463dd21adeeaf96d79a5b28d685d2a106cee1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 15:58:40 +0000 Subject: [PATCH 076/258] build(deps): bump mongoose from 8.4.5 to 8.5.1 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.5 to 8.5.1. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.4.5...8.5.1) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7fe878175..686adc9b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10576,9 +10576,9 @@ } }, "node_modules/mongodb": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz", - "integrity": "sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", + "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -10661,13 +10661,13 @@ } }, "node_modules/mongoose": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.4.5.tgz", - "integrity": "sha512-E5KjBThxST2uFSKKXuiMa9H9Zx4DLTSLuxodAnIzJRixNwc1ARTlJUK1m0a80EB+ZKGP4QNTasyUYRG9DUSHOA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", + "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.6.2", + "mongodb": "6.7.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", From 53f3710702775fbe441c98e90d79889e0fb3fb48 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 19 Jul 2024 08:59:06 +0200 Subject: [PATCH 077/258] fix: Remove unnecessary properties from datasetMappings and add new mapping for scientificMetadata query --- src/common/utils.ts | 2 +- .../configuration/datasetFieldMapping.ts | 10 +- .../configuration/indexSetting.ts | 16 ++- src/elastic-search/elastic-search.service.ts | 4 +- src/elastic-search/helpers/utils.ts | 136 ++++++++++++------ .../interfaces/es-common.type.ts | 15 ++ 6 files changed, 128 insertions(+), 55 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index d6feb520d..3a872ff3f 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -108,7 +108,6 @@ export const mapScientificQuery = ( const scientificFilterQueryOr: Record[] = []; const keyToFieldMapping: Record = { - scientificMetadata: "scientificMetadata", scientific: "scientificMetadata", characteristics: "sampleCharacteristics", }; @@ -180,6 +179,7 @@ export const mapScientificQuery = ( } else if (scientificFilterQueryOr.length > 1) { scientificFilterQuery["$and"] = scientificFilterQueryOr; } + return scientificFilterQuery; }; diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index 988bb5b7e..5fca391e8 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -33,15 +33,7 @@ export const datasetMappings: MappingObject = { scientificMetadata: { type: "nested", dynamic: true, - properties: { - runNumber: { - properties: { - value: { - type: "long", - }, - }, - }, - }, + properties: {}, }, history: { type: "nested", diff --git a/src/elastic-search/configuration/indexSetting.ts b/src/elastic-search/configuration/indexSetting.ts index bbb60a9f2..7f7f680e5 100644 --- a/src/elastic-search/configuration/indexSetting.ts +++ b/src/elastic-search/configuration/indexSetting.ts @@ -43,13 +43,25 @@ export const dynamic_template: Record[] = [ }, }, }, + { + double_as_double: { + path_match: "scientificMetadata.*.*", + match_mapping_type: "double", + mapping: { + type: "double", + coerce: true, + ignore_malformed: true, + }, + }, + }, { date_as_keyword: { path_match: "scientificMetadata.*.*", match_mapping_type: "date", mapping: { - type: "keyword", - ignore_above: 256, + type: "date", + format: "strict_date_optional_time||epoch_millis", + ignore_malformed: true, }, }, }, diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 69782558b..afc4f557a 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -26,9 +26,9 @@ import { import { ConfigService } from "@nestjs/config"; import { sleep } from "src/common/utils"; import { - transformKeysInObject, initialSyncTransform, transformFacets, + addValueType, } from "./helpers/utils"; import { SortFields } from "./providers/fields.enum"; @@ -362,7 +362,7 @@ export class ElasticSearchService implements OnModuleInit { async updateInsertDocument(data: Partial) { //NOTE: Replace all keys with lower case, also replace spaces and dot with underscore delete data._id; - const transformedScientificMetadata = transformKeysInObject( + const transformedScientificMetadata = addValueType( data.scientificMetadata as Record, ); diff --git a/src/elastic-search/helpers/utils.ts b/src/elastic-search/helpers/utils.ts index 0a0198b4b..57e4242e1 100644 --- a/src/elastic-search/helpers/utils.ts +++ b/src/elastic-search/helpers/utils.ts @@ -3,12 +3,16 @@ import { AggregationsFrequentItemSetsBucketKeys, } from "@elastic/elasticsearch/lib/api/types"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { IFilter, ITransformedFullFacets } from "../interfaces/es-common.type"; +import { + IFilter, + IQuery, + ITransformedFullFacets, +} from "../interfaces/es-common.type"; export const transformKey = (key: string): string => { return key.trim().replace(/[.]/g, "\\.").replace(/ /g, "_").toLowerCase(); }; -export const transformKeysInObject = (obj: Record) => { +export const addValueType = (obj: Record) => { const newObj: Record = {}; for (const [key, value] of Object.entries(obj)) { @@ -16,6 +20,7 @@ export const transformKeysInObject = (obj: Record) => { const isNumberValueType = typeof (value as Record)?.value === "number"; + if (isNumberValueType) { (value as Record)["value_type"] = "number"; } else { @@ -66,51 +71,100 @@ export const initialSyncTransform = (obj: DatasetClass) => { return modifiedDocInObject; }; -export const convertToElasticSearchQuery = ( - scientificQuery: Record, -) => { +const extractNestedQueryOperationValue = (query: IQuery) => { + const field = Object.keys(query)[0]; + const operationWithPrefix = Object.keys(query[field])[0]; + + const value = + typeof query[field][operationWithPrefix] === "string" + ? (query[field][operationWithPrefix] as string).trim() + : query[field][operationWithPrefix]; + + const operation = operationWithPrefix.replace("$", ""); + + return { operation, value, field }; +}; + +export const convertToElasticSearchQuery = (scientificQuery: any) => { const filters: IFilter[] = []; for (const field in scientificQuery) { - const query = scientificQuery[field] as Record; - const operation = Object.keys(query)[0]; - const value = - typeof query[operation] === "string" - ? (query[operation] as string).trim() - : query[operation]; - - const esOperation = operation.replace("$", ""); - - // NOTE-EXAMPLE: - // trasnformedKey = "scientificMetadata.someKey.value" - // firstPart = "scientificMetadata", - // middlePart = "someKey" - const { transformedKey, firstPart, middlePart } = transformMiddleKey(field); - - let filter = {}; - - const fieldType = field.split(".").pop(); - - if (fieldType === "valueSI" || fieldType === "value") { - const numberFilter = { - term: { - [`${firstPart}.${middlePart}.value_type`]: - typeof value === "number" ? "number" : "string", + const query = scientificQuery[field] as any; + + if (field === "$and") { + query.forEach((query: any) => { + const shouldQueries = query.$or.map((orQuery: any) => { + const { operation, value, field } = + extractNestedQueryOperationValue(orQuery); + const filterType = operation === "eq" ? "term" : "range"; + return { + [filterType]: { + [field]: operation === "eq" ? value : { [operation]: value }, + }, + }; + }); + filters.push({ + bool: { + should: shouldQueries, + minimum_should_match: 1, + }, + }); + }); + } else if (field === "$or") { + const shouldQueries = query.map((query: any) => { + const { operation, value, field } = + extractNestedQueryOperationValue(query); + const filterType = operation === "eq" ? "term" : "range"; + return { + [filterType]: { + [field]: operation === "eq" ? value : { [operation]: value }, + }, + }; + }); + filters.push({ + bool: { + should: shouldQueries, + minimum_should_match: 1, }, - }; - filters.push(numberFilter); + }); + } else { + const operation = Object.keys(query)[0]; + const value = + typeof query[operation] === "string" + ? (query[operation] as string).trim() + : query[operation]; + const esOperation = operation.replace("$", ""); + + // NOTE: + // trasnformedKey = "scientificMetadata.someKey.value" + // firstPart = "scientificMetadata", + // middlePart = "someKey" + // lastPart = "value" + const { transformedKey, firstPart, middlePart, lastPart } = + transformMiddleKey(field); + + if (lastPart === "valueSI" || lastPart === "value") { + const numberFilter = { + term: { + [`${firstPart}.${middlePart}.value_type`]: + typeof value === "number" ? "number" : "string", + }, + }; + filters.push(numberFilter); + } + + const filter = + esOperation === "eq" + ? { + term: { [`${transformedKey}`]: value }, + } + : { + range: { [`${transformedKey}`]: { [esOperation]: value } }, + }; + + filters.push(filter); } - - filter = - esOperation === "eq" - ? { - term: { [`${transformedKey}`]: value }, - } - : { range: { [`${transformedKey}`]: { [esOperation]: value } } }; - - filters.push(filter); } - return filters; }; diff --git a/src/elastic-search/interfaces/es-common.type.ts b/src/elastic-search/interfaces/es-common.type.ts index 8cc66f227..5a0844ba2 100644 --- a/src/elastic-search/interfaces/es-common.type.ts +++ b/src/elastic-search/interfaces/es-common.type.ts @@ -20,6 +20,12 @@ export interface IShould { term?: { [key: string]: string | undefined; }; + range?: { + [key: string]: { + gte?: string | number; + lte?: string | number; + }; + }; } export interface IBoolShould { @@ -56,6 +62,10 @@ export interface IFilter { }; }; }; + bool?: { + should: IShould[]; + minimum_should_match?: number; + }; } export interface IFullFacets { @@ -81,3 +91,8 @@ export interface ITransformedFullFacets { } | { totalSets: number }; } + +type Operation = "$eq" | "$neq" | "$gte" | "$gt" | "$lte" | "$lt"; +export interface IQuery { + [key: string]: any; +} From 03b8695437f6a27685c18129be15a94cb27bd887 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 19 Jul 2024 09:26:00 +0200 Subject: [PATCH 078/258] fix: Update wrong dataset length assertion in DatasetFilter test --- test/DatasetFilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DatasetFilter.js b/test/DatasetFilter.js index 37b71bf79..9e53596de 100644 --- a/test/DatasetFilter.js +++ b/test/DatasetFilter.js @@ -808,7 +808,7 @@ describe("0400: DatasetFilter: Test retrieving datasets using filtering capabili .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.length.should.be.equal(0); + res.body.length.should.be.equal(1); }); }); From c17099f73611720e6a0e4bba98593eee509dc4ee Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 19 Jul 2024 10:01:08 +0200 Subject: [PATCH 079/258] Add test_field_string to RawCorrect3 in DatasetFilter test --- test/DatasetFilter.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/DatasetFilter.js b/test/DatasetFilter.js index 9e53596de..5dedb8e5a 100644 --- a/test/DatasetFilter.js +++ b/test/DatasetFilter.js @@ -62,6 +62,10 @@ const RawCorrect3 = { value: 6, unit: "", }, + test_field_string: { + value: "test_string_value", + unit: "", + }, }, datasetName: "This is the third correct test raw dataset", description: @@ -790,9 +794,9 @@ describe("0400: DatasetFilter: Test retrieving datasets using filtering capabili mode: {}, scientific: [ { - lhs: "test_field_1", + lhs: "test_field_string", relation: "EQUAL_TO_STRING", - rhs: "6", + rhs: "test_string_value", unit: "", }, ], From 4959954a3addf54430ee5ab04bdc80fc9f1c1f82 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 00:05:47 +0200 Subject: [PATCH 080/258] refactored createIndex function and changed mapping of date type to keyword partially. --- .../configuration/datasetFieldMapping.ts | 3 ++ .../configuration/indexSetting.ts | 27 +++++++++++----- src/elastic-search/elastic-search.service.ts | 32 ++++++++----------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index 5fca391e8..429555ee8 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -30,6 +30,9 @@ export const datasetMappings: MappingObject = { creationTime: { type: "date", }, + endTime: { + type: "date", + }, scientificMetadata: { type: "nested", dynamic: true, diff --git a/src/elastic-search/configuration/indexSetting.ts b/src/elastic-search/configuration/indexSetting.ts index 7f7f680e5..bb026d996 100644 --- a/src/elastic-search/configuration/indexSetting.ts +++ b/src/elastic-search/configuration/indexSetting.ts @@ -22,13 +22,25 @@ export const special_character_filter: AnalysisPatternReplaceCharFilter = { //Dynamic templates export const dynamic_template: Record[] = [ + // NOTE: date as keyword is temporary solution for date format issue { - string_as_keyword: { + date_as_keyword: { path_match: "scientificMetadata.*.*", - match_mapping_type: "string", + match_mapping_type: "date", + mapping: { + type: "keyword", + }, + }, + }, + // NOTE: This is a workaround for the issue where the start_time field is not being + // parsed correctly. This is a temporary solution until + // we can find a better way to handle date format. + { + start_time_as_keyword: { + path_match: "scientificMetadata.start_time.*", + match_mapping_type: "long", mapping: { type: "keyword", - ignore_above: 256, }, }, }, @@ -55,13 +67,12 @@ export const dynamic_template: Record[] = [ }, }, { - date_as_keyword: { + string_as_keyword: { path_match: "scientificMetadata.*.*", - match_mapping_type: "date", + match_mapping_type: "string", mapping: { - type: "date", - format: "strict_date_optional_time||epoch_millis", - ignore_malformed: true, + type: "keyword", + ignore_above: 256, }, }, }, diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index afc4f557a..12a02353f 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -86,6 +86,10 @@ export class ElasticSearchService implements OnModuleInit { const isIndexExists = await this.isIndexExists(this.defaultIndex); if (!isIndexExists) { await this.createIndex(this.defaultIndex); + Logger.log( + `New index ${this.defaultIndex}is created `, + "ElasticSearch", + ); } this.connected = true; Logger.log("Elasticsearch Connected", "ElasticSearch"); @@ -141,26 +145,18 @@ export class ElasticSearchService implements OnModuleInit { index, body: { settings: defaultElasticSettings, + mappings: { + dynamic: true, + dynamic_templates: dynamic_template, + numeric_detection: true, + date_detection: true, + dynamic_date_formats: [ + "yyyy-MM-dd'T'HH:mm:ss|| yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZ||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'||yyyy-MM-dd'T'HH:mm:ss.SSS", + ], + properties: datasetMappings, + }, }, }); - await this.esService.indices.close({ index }); - await this.esService.indices.putSettings({ - index, - body: { - settings: defaultElasticSettings, - }, - }); - await this.esService.indices.putMapping({ - index, - dynamic: true, - body: { - dynamic_templates: dynamic_template, - properties: datasetMappings, - }, - }); - await this.esService.indices.open({ - index, - }); Logger.log( `Elasticsearch Index Created-> Index: ${index}`, "Elasticsearch", From 3c64305dd7a0717559a85d478451101f8f0c11ea Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 01:12:48 +0200 Subject: [PATCH 081/258] replaced any types with actual types. --- src/elastic-search/helpers/utils.ts | 28 +++++++++++-------- .../interfaces/es-common.type.ts | 9 ++++-- .../providers/query-builder.service.ts | 3 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/elastic-search/helpers/utils.ts b/src/elastic-search/helpers/utils.ts index 57e4242e1..9c8d28242 100644 --- a/src/elastic-search/helpers/utils.ts +++ b/src/elastic-search/helpers/utils.ts @@ -5,8 +5,9 @@ import { import { DatasetClass } from "src/datasets/schemas/dataset.schema"; import { IFilter, - IQuery, ITransformedFullFacets, + nestedQueryObject, + ScientificQuery, } from "../interfaces/es-common.type"; export const transformKey = (key: string): string => { @@ -71,7 +72,7 @@ export const initialSyncTransform = (obj: DatasetClass) => { return modifiedDocInObject; }; -const extractNestedQueryOperationValue = (query: IQuery) => { +const extractNestedQueryOperationValue = (query: nestedQueryObject) => { const field = Object.keys(query)[0]; const operationWithPrefix = Object.keys(query[field])[0]; @@ -85,15 +86,17 @@ const extractNestedQueryOperationValue = (query: IQuery) => { return { operation, value, field }; }; -export const convertToElasticSearchQuery = (scientificQuery: any) => { +export const convertToElasticSearchQuery = ( + scientificQuery: ScientificQuery, +): IFilter[] => { const filters: IFilter[] = []; for (const field in scientificQuery) { - const query = scientificQuery[field] as any; + const query = scientificQuery[field]; - if (field === "$and") { - query.forEach((query: any) => { - const shouldQueries = query.$or.map((orQuery: any) => { + if (field === "$and" && Array.isArray(query)) { + query.forEach((query: { $or: nestedQueryObject[] }) => { + const shouldQueries = query.$or.map((orQuery: nestedQueryObject) => { const { operation, value, field } = extractNestedQueryOperationValue(orQuery); const filterType = operation === "eq" ? "term" : "range"; @@ -110,8 +113,8 @@ export const convertToElasticSearchQuery = (scientificQuery: any) => { }, }); }); - } else if (field === "$or") { - const shouldQueries = query.map((query: any) => { + } else if (field === "$or" && Array.isArray(query)) { + const shouldQueries = query.map((query: nestedQueryObject) => { const { operation, value, field } = extractNestedQueryOperationValue(query); const filterType = operation === "eq" ? "term" : "range"; @@ -129,10 +132,11 @@ export const convertToElasticSearchQuery = (scientificQuery: any) => { }); } else { const operation = Object.keys(query)[0]; + const value = - typeof query[operation] === "string" - ? (query[operation] as string).trim() - : query[operation]; + typeof (query as Record)[operation] === "string" + ? (query as Record)[operation].trim() + : (query as Record)[operation]; const esOperation = operation.replace("$", ""); // NOTE: diff --git a/src/elastic-search/interfaces/es-common.type.ts b/src/elastic-search/interfaces/es-common.type.ts index 5a0844ba2..8b49f5e01 100644 --- a/src/elastic-search/interfaces/es-common.type.ts +++ b/src/elastic-search/interfaces/es-common.type.ts @@ -92,7 +92,10 @@ export interface ITransformedFullFacets { | { totalSets: number }; } -type Operation = "$eq" | "$neq" | "$gte" | "$gt" | "$lte" | "$lt"; -export interface IQuery { - [key: string]: any; +export interface ScientificQuery { + [key: string]: Record | "$and" | "$or"; +} + +export interface nestedQueryObject { + [key: string]: Record; } diff --git a/src/elastic-search/providers/query-builder.service.ts b/src/elastic-search/providers/query-builder.service.ts index 930f877f9..8d11fb6aa 100644 --- a/src/elastic-search/providers/query-builder.service.ts +++ b/src/elastic-search/providers/query-builder.service.ts @@ -7,6 +7,7 @@ import { IFullFacets, IShould, ObjectType, + ScientificQuery, } from "../interfaces/es-common.type"; import { FilterFields, @@ -125,7 +126,7 @@ export class SearchQueryService { ); const esScientificFilterQuery = convertToElasticSearchQuery( - scientificFilterQuery, + scientificFilterQuery as ScientificQuery, ); filterArray.push({ nested: { From e0fbd1a226528ff88cf1c623d838b1a570ae31bd Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 22 Jul 2024 09:54:42 +0200 Subject: [PATCH 082/258] Update indexSetting.ts --- src/elastic-search/configuration/indexSetting.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elastic-search/configuration/indexSetting.ts b/src/elastic-search/configuration/indexSetting.ts index bb026d996..7fc473aae 100644 --- a/src/elastic-search/configuration/indexSetting.ts +++ b/src/elastic-search/configuration/indexSetting.ts @@ -22,7 +22,7 @@ export const special_character_filter: AnalysisPatternReplaceCharFilter = { //Dynamic templates export const dynamic_template: Record[] = [ - // NOTE: date as keyword is temporary solution for date format issue + // NOTE: date as keyword is temporary solution for date format inconsistency issue in the scientificMetadata field { date_as_keyword: { path_match: "scientificMetadata.*.*", From 58b7cd7f94073cba2d15a6c9d2e816b852cea851 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:19:57 +0000 Subject: [PATCH 083/258] build(deps-dev): bump @types/node from 20.14.10 to 20.14.11 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.10 to 20.14.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab3e36fbc..ace601b1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3027,9 +3027,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dependencies": { "undici-types": "~5.26.4" } From d1aadd5eecff46b5a727889151ef6c85558d8dea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:30:41 +0000 Subject: [PATCH 084/258] build(deps-dev): bump mocha from 10.6.0 to 10.7.0 Bumps [mocha](https://github.com/mochajs/mocha) from 10.6.0 to 10.7.0. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.6.0...v10.7.0) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ace601b1d..ce6bc8064 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10429,9 +10429,9 @@ } }, "node_modules/mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", + "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", From d71e79791a5f1e49001d82e633e7d881b7edca96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:41:31 +0000 Subject: [PATCH 085/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.16.0 to 7.16.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 264 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 246 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce6bc8064..d8d199d0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3219,16 +3219,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", - "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/type-utils": "7.16.0", - "@typescript-eslint/utils": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3251,6 +3251,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", @@ -3297,13 +3344,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", - "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3323,6 +3370,88 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", @@ -3389,15 +3518,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3410,6 +3539,105 @@ "eslint": "^8.56.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", From 6f6f37d23c148e7999974930ef21f7657b4c8a95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:52:02 +0000 Subject: [PATCH 086/258] build(deps-dev): bump @typescript-eslint/parser from 7.16.0 to 7.16.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.16.0 to 7.16.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.16.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 256 +++------------------------------------------- 1 file changed, 14 insertions(+), 242 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8d199d0a..58eb61f54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3251,63 +3251,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/parser": { "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "7.16.1", "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", - "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -3327,13 +3280,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3370,7 +3323,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", @@ -3383,7 +3336,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", @@ -3411,88 +3364,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3539,65 +3410,7 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", @@ -3614,47 +3427,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ucast/core": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@ucast/core/-/core-1.10.2.tgz", From 6d8606abae28f02c469e7f4b544545f2b2e363b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:02:45 +0000 Subject: [PATCH 087/258] build(deps): bump mathjs from 13.0.2 to 13.0.3 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.0.2 to 13.0.3. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.0.2...v13.0.3) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 58eb61f54..987d3feb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -842,9 +842,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -9750,11 +9750,11 @@ } }, "node_modules/mathjs": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.2.tgz", - "integrity": "sha512-8vK/+InU4FTphRTWsrnvRsgSjbyNupRQYDDIXLuEGDZtJsGdbA9dVV4HZ0amBQb+RXplRjVJNGZZfB0WoHWFWA==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.3.tgz", + "integrity": "sha512-GpP9OW6swA5POZXvgpc/1FYkAr8lKgV04QHS1tIU60klFfplVCYaNzn6qy0vSp0hAQQN7shcx9CeB507dlLujA==", "dependencies": { - "@babel/runtime": "^7.24.7", + "@babel/runtime": "^7.24.8", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", From e37d6b70e90c8925a77fe74bb3f4852b434a9ddd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:13:44 +0000 Subject: [PATCH 088/258] build(deps-dev): bump eslint-plugin-prettier from 5.1.3 to 5.2.1 Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.1.3 to 5.2.1. - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.1.3...v5.2.1) --- updated-dependencies: - dependency-name: eslint-plugin-prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 321 ++-------------------------------------------- 1 file changed, 14 insertions(+), 307 deletions(-) diff --git a/package-lock.json b/package-lock.json index 987d3feb3..6788f0abb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2607,19 +2607,11 @@ "node": ">=14" } }, - "node_modules/@pkgr/utils": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", - "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.3.0", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.6.0" - }, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, @@ -2627,24 +2619,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@pkgr/utils/node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", @@ -4232,15 +4206,6 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4394,18 +4359,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4539,36 +4492,6 @@ "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bundle-name/node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -5508,156 +5431,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/default-browser/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, - "node_modules/default-browser/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/default-browser/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -5686,18 +5459,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6284,13 +6045,13 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "synckit": "^0.9.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -7912,7 +7673,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "devOptional": true, + "optional": true, "bin": { "is-docker": "cli.js" }, @@ -7983,39 +7744,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -8126,7 +7854,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "devOptional": true, + "optional": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -13136,12 +12864,12 @@ "dev": true }, "node_modules/synckit": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", - "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { - "@pkgr/utils": "^2.4.2", + "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" }, "engines": { @@ -13331,18 +13059,6 @@ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tlds": { "version": "1.240.0", "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.240.0.tgz", @@ -13788,15 +13504,6 @@ "node": ">= 0.8" } }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", From 76df8ac24eaefa8e3d94349bdd06148596e62502 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:24:27 +0000 Subject: [PATCH 089/258] build(deps-dev): bump @types/lodash from 4.17.6 to 4.17.7 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.6 to 4.17.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6788f0abb..d0c686826 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2956,9 +2956,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", - "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", "dev": true }, "node_modules/@types/luxon": { From 24351dacdb265dc9b827ebcd982f9c469f05cb32 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 11:00:40 +0200 Subject: [PATCH 090/258] replace deprecated instance of casl abilitybuilder with updated one --- src/casl/casl-ability.factory.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 0861325c3..14e558e05 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -1,9 +1,10 @@ import { - Ability, AbilityBuilder, - AbilityClass, ExtractSubjectType, InferSubjects, + MongoAbility, + MongoQuery, + createMongoAbility, } from "@casl/ability"; import { Injectable } from "@nestjs/common"; import { Attachment } from "src/attachments/schemas/attachment.schema"; @@ -46,15 +47,17 @@ type Subjects = | typeof ElasticSearchActions > | "all"; +type PossibleAbilities = [Action, Subjects]; +type Conditions = MongoQuery; -export type AppAbility = Ability<[Action, Subjects]>; +export type AppAbility = MongoAbility; @Injectable() export class CaslAbilityFactory { createForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder< - Ability<[Action, Subjects]> - >(Ability as AbilityClass); + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); // // admin groups // const stringAdminGroups = process.env.ADMIN_GROUPS || ""; From c29a1e13b24e3f8ec388d8de50677d62b8bb0a0c Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 15:33:15 +0200 Subject: [PATCH 091/258] feat: Added findByIdAccess endpoint to Proposal and Sample services --- src/proposals/proposals.controller.ts | 48 +++++++++++++++-- src/samples/samples.controller.ts | 78 ++++++++++++++++++++------- 2 files changed, 104 insertions(+), 22 deletions(-) diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 324bd0b2f..d69fff109 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -181,7 +181,7 @@ export class ProposalsController { ); if (!canDoAction) { - throw new ForbiddenException("Unauthorized access"); + throw new ForbiddenException("Unauthorized to this proposal"); } } return proposal; @@ -516,8 +516,8 @@ export class ProposalsController { return this.proposalsService.fullfacet(parsedFilters); } - // GET /proposals/:id - @UseGuards(AuthenticatedPoliciesGuard) + // GET /proposals/:pid + @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @@ -532,7 +532,7 @@ export class ProposalsController { type: String, }) @ApiResponse({ - status: 200, + status: HttpStatus.OK, type: ProposalClass, isArray: false, description: "Return proposal with pid specified", @@ -546,9 +546,49 @@ export class ProposalsController { proposalId, Action.ProposalsRead, ); + return proposal; } + // GET /proposals/:pid/access + @UseGuards(PoliciesGuard) + @CheckPolicies((ability: AppAbility) => + ability.can(Action.ProposalsRead, ProposalClass), + ) + @Get("/:pid/access") + @ApiOperation({ + summary: "Check user access to a specific proposal.", + description: + "Returns a boolean indicating whether the user has access to the proposal with the specified ID.", + }) + @ApiParam({ + name: "pid", + description: "ID of the proposal to check access for", + type: String, + }) + @ApiResponse({ + status: HttpStatus.OK, + type: Boolean, + description: + "Returns true if the user has access to the specified proposal, otherwise false.", + }) + async findByIdAccess( + @Req() request: Request, + @Param("pid") proposalId: string, + ): Promise<{ canAccess: boolean }> { + const proposal = await this.proposalsService.findOne({ + proposalId, + }); + if (!proposal) return { canAccess: false }; + + const canAccess = await this.permissionChecker( + Action.ProposalsRead, + proposal, + request, + ); + return { canAccess: canAccess }; + } + // PATCH /proposals/:pid @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 4f49a3dac..5666d0768 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -63,6 +63,7 @@ import { Request } from "express"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { IDatasetFields } from "src/datasets/interfaces/dataset-filters.interface"; import { CreateSubAttachmentDto } from "src/attachments/dto/create-sub-attachment.dto"; +import { AuthenticatedPoliciesGuard } from "src/casl/guards/auth-check.guard"; @ApiBearerAuth() @ApiTags("samples") @@ -165,9 +166,8 @@ export class SamplesController { if (sample) { const canDoAction = await this.permissionChecker(group, sample, request); - if (!canDoAction) { - throw new ForbiddenException("Unauthorized to update this sample"); + throw new ForbiddenException("Unauthorized to this sample"); } } @@ -242,7 +242,7 @@ export class SamplesController { return mergedFilters; } // POST /samples - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleCreate, SampleClass), ) @@ -280,7 +280,7 @@ export class SamplesController { } // GET /samples - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @@ -314,7 +314,7 @@ export class SamplesController { } // GET /samples/fullquery - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @@ -391,7 +391,7 @@ export class SamplesController { } // GET /samples/metadataKeys - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @@ -463,7 +463,7 @@ export class SamplesController { } // GET /samples/findOne - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @@ -546,12 +546,54 @@ export class SamplesController { @Req() request: Request, @Param("id") id: string, ): Promise { - await this.checkPermissionsForSample(request, id, Action.SampleRead); - return this.samplesService.findOne({ sampleId: id }); + const sample = await this.checkPermissionsForSample( + request, + id, + Action.SampleRead, + ); + return sample; } - // PATCH /samples/:id + // GET /samples/:id/access @UseGuards(PoliciesGuard) + @CheckPolicies((ability: AppAbility) => + ability.can(Action.SampleRead, SampleClass), + ) + @Get("/:id/access") + @ApiOperation({ + summary: "Check user access to a specific sample.", + description: + "Returns a boolean indicating whether the user has access to the sample with the specified ID.", + }) + @ApiParam({ + name: "pid", + description: "ID of the sample to check access for", + type: String, + }) + @ApiResponse({ + status: HttpStatus.OK, + type: Boolean, + description: + "Returns true if the user has access to the specified sample, otherwise false.", + }) + async findByIdAccess( + @Req() request: Request, + @Param("id") id: string, + ): Promise<{ canAccess: boolean }> { + const sample = await this.samplesService.findOne({ + sampleId: id, + }); + if (!sample) return { canAccess: false }; + const canAccess = await this.permissionChecker( + Action.SampleRead, + sample, + request, + ); + return { canAccess }; + } + + // PATCH /samples/:id + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleUpdate, SampleClass), ) @@ -618,7 +660,7 @@ export class SamplesController { } // POST /samples/:id/attachments - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleAttachmentDelete, SampleClass), ) @@ -670,7 +712,7 @@ export class SamplesController { } // GET /samples/:id/attachments - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleAttachmentRead, SampleClass), ) @@ -704,7 +746,7 @@ export class SamplesController { } // GET /samples/:id/attachments/:fk - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleAttachmentRead, SampleClass), ) @@ -747,7 +789,7 @@ export class SamplesController { } // DELETE /samples/:id/attachments/:fk - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleAttachmentDelete, SampleClass), ) @@ -789,7 +831,7 @@ export class SamplesController { } // POST /samples/:id/datasets - /* @UseGuards(PoliciesGuard) + /* @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Dataset)) @Post("/:id/datasets") async createDataset( @@ -802,7 +844,7 @@ export class SamplesController { */ // GET /samples/:id/datasets - @UseGuards(PoliciesGuard) + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleDatasetRead, SampleClass), ) @@ -865,7 +907,7 @@ export class SamplesController { } // PATCH /samples/:id/datasets/:fk - /* @UseGuards(PoliciesGuard) + /* @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, Dataset)) @Patch("/:id/datasets/:fk") async findOneDatasetAndUpdate( @@ -880,7 +922,7 @@ export class SamplesController { } */ // DELETE /samples/:id/datasets/:fk - /* @UseGuards(PoliciesGuard) + /* @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Delete, Dataset)) @Delete("/:id/datasets/:fk") async findOneDatasetAndRemove( From d5f2985f78cc62ddc9911245e41fb03b318004fc Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 16:51:46 +0200 Subject: [PATCH 092/258] update MongoDB test database configurable --- test/config/pretest.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/config/pretest.js b/test/config/pretest.js index e884f4e73..7351a4827 100644 --- a/test/config/pretest.js +++ b/test/config/pretest.js @@ -3,7 +3,8 @@ var chaiHttp = require("chai-http"); const { MongoClient } = require("mongodb"); -const uri = "mongodb://localhost:27017/scicat"; +const testDbName = process.env.MONGDB_TEST_NAME || "scicat-test"; +const uri = `mongodb://localhost:27017/${testDbName}`; const client = new MongoClient(uri); @@ -16,4 +17,4 @@ loadChai(); global.appUrl = "http://localhost:3000"; global.request = require("supertest"); -global.db = client.db("scicat"); +global.db = client.db(testDbName); From 366c0d8837844c795a1d95616db4fb9f3e9fb253 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 17:16:26 +0200 Subject: [PATCH 093/258] update authentication guards in proposals and samples controllers --- src/proposals/proposals.controller.ts | 1 - src/samples/samples.controller.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index d69fff109..bbddc2410 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -33,7 +33,6 @@ import { ApiTags, } from "@nestjs/swagger"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; -import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { Action } from "src/casl/action.enum"; diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 5666d0768..9c5deb377 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -280,7 +280,7 @@ export class SamplesController { } // GET /samples - @UseGuards(AuthenticatedPoliciesGuard) + @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @@ -712,7 +712,7 @@ export class SamplesController { } // GET /samples/:id/attachments - @UseGuards(AuthenticatedPoliciesGuard) + @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleAttachmentRead, SampleClass), ) From 5562747f8bdd922200b852e6b0466dff4bf9b9bd Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 22 Jul 2024 17:18:12 +0200 Subject: [PATCH 094/258] corrected test http status code for SampleAuthrozation and ProposalAuthorization --- test/ProposalAuthorization.js | 42 ++++++++++++-- test/SampleAuthorization.js | 100 +++++++++++++++++----------------- 2 files changed, 88 insertions(+), 54 deletions(-) diff --git a/test/ProposalAuthorization.js b/test/ProposalAuthorization.js index 4e4a9a200..1ba2f3af4 100644 --- a/test/ProposalAuthorization.js +++ b/test/ProposalAuthorization.js @@ -17,6 +17,8 @@ let proposalPid1 = null, encodedProposalPid2 = null, proposalPid3 = null, encodedProposalPid3 = null; +// proposalPid10 = null, +// encodedProposalPid10 = null; const proposal1 = { ...TestData.ProposalCorrectMin, @@ -39,6 +41,14 @@ const proposal3 = { accessGroups: ["group3"], }; +// const proposal10 = { +// ...TestData.ProposalCorrectMin, +// proposalId: "20170271", +// ownerGroup: "admin", +// accessGroups: ["admin"], +// isPublished: true, +// }; + describe("1400: ProposalAuthorization: Test access to proposal", () => { before(() => { db.collection("Proposal").deleteMany({}); @@ -104,7 +114,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { done(); }); - it("0010: adds proposal 1", async () => { + it("0000: adds proposal 1", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal1) @@ -120,7 +130,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0020: adds proposal 2", async () => { + it("0010: adds proposal 2", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal2) @@ -136,7 +146,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0030: adds proposal 3", async () => { + it("0020: adds proposal 3", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal3) @@ -152,14 +162,38 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + // it("0030: adds proposal 10", async () => { + // return request(appUrl) + // .post("/api/v3/proposals") + // .send(proposal10) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("ownerGroup").and.equal("admin"); + // res.body.should.have.property("proposalId").and.be.string; + // proposalPid10 = res.body["proposalId"]; + // encodedProposalPid10 = encodeURIComponent(proposalPid10); + // }); + // }); + it("0040: cannot access proposal as unauthenticated user", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid2) .set("Accept", "application/json") .expect("Content-Type", /json/) - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); + // it("0045: can access public proposal as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/proposals/" + encodedProposalPid10) + // .set("Accept", "application/json") + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode); + // }); + it("0050: admin can list all proposals", async () => { return request(appUrl) .get("/api/v3/proposals") diff --git a/test/SampleAuthorization.js b/test/SampleAuthorization.js index a8fcfcb25..1f834f9b0 100644 --- a/test/SampleAuthorization.js +++ b/test/SampleAuthorization.js @@ -485,7 +485,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0180: adds a new sample as an unauthenticated user with owner group as sampleingestor, which should fail", async () => { @@ -498,7 +498,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0190: adds a new sample as an unauthenticated user with owner group as user1, which should fail", async () => { @@ -511,7 +511,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0200: adds a new sample as an unauthenticated user with its owner group, which should fail", async () => { @@ -524,7 +524,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0210: adds a new sample as Archive Manager with owner group as adminingestor, which should fail", async () => { @@ -977,7 +977,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId1 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0420: adds an attachment as an unauthenticated user to sample 2, which should fail", async () => { @@ -985,7 +985,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId2 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0430: adds an attachment as an unauthenticated user to sample 3, which should fail", async () => { @@ -993,7 +993,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId3 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0440: adds an attachment as an unauthenticated user to sample 4, which should fail", async () => { @@ -1001,7 +1001,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId4 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("0450: adds an attachment as Archive Manager to sample 1, which should fail", async () => { @@ -2733,126 +2733,126 @@ describe("2250: Sample Authorization", () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1335: fetch all attachments for sample 1 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1340: access sample 2 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); - it("1345: fetch all attachments for sample 1 as Unauthenticated User, which should fail", async () => { + it("1345: fetch all attachments for sample 2 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId2 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1350: access sample 3 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1355: fetch all attachments for sample 5 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId3 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1360: access sample 4 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1365: fetch all attachments for sample 4 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId4 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1370: access sample 5 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1375: fetch all attachments for sample 5 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId5 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1380: access sample 6 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1385: fetch all attachments for sample 6 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId6 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1390: access sample 7 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1395: fetch all attachments for sample 7 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId7 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1400: access sample 8 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1405: fetch all attachments for sample 8 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId8 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1410: access sample 9 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1415: fetch all attachments for sample 9 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId9 + "/attachments") .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1420: access public sample 10 as Unauthenticated User", async () => { @@ -2882,7 +2882,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1435: fetch all attachments for sample 5 as Archive Manager, which should fail", async () => { @@ -2890,7 +2890,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId1 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1440: access sample 2 as Archive Manager, which should fail", async () => { @@ -2898,7 +2898,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1445: fetch all attachments for sample 2 as Archive Manager, which should fail", async () => { @@ -2906,7 +2906,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId2 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1450: access sample 3 as Archive Manager, which should fail", async () => { @@ -2914,7 +2914,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1455: fetch all attachments for sample 5 as Archive Manager, which should fail", async () => { @@ -2922,7 +2922,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId3 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1460: access sample 4 as Archive Manager, which should fail", async () => { @@ -2930,7 +2930,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1465: fetch all attachments for sample 4 as Archive Manager, which should fail", async () => { @@ -2938,7 +2938,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId4 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1470: access sample 5 as Archive Manager, which should fail", async () => { @@ -2946,7 +2946,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1475: fetch all attachments for sample 5 as Archive Manager, which should fail", async () => { @@ -2954,7 +2954,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId5 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1480: access sample 6 as Archive Manager, which should fail", async () => { @@ -2962,14 +2962,14 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1485: fetch all attachments for sample 6 as Archive Manager, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId6 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1490: access sample 7 as Archive Manager, which should fail", async () => { @@ -2977,7 +2977,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1495: fetch all attachments for sample 7 as Archive Manager, which should fail", async () => { @@ -2985,7 +2985,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId7 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1500: access sample 8 as Archive Manager, which should fail", async () => { @@ -2993,7 +2993,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1505: fetch all attachments for sample 8 as Archive Manager, which should fail", async () => { @@ -3001,7 +3001,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId8 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1510: access sample 9 as Archive Manager, which should fail", async () => { @@ -3009,7 +3009,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1515: fetch all attachments for sample 9 as Archive Manager, which should fail", async () => { @@ -3017,7 +3017,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId5 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); it("1520: access public sample 10 as Archive Manager", async () => { @@ -3037,7 +3037,7 @@ describe("2250: Sample Authorization", () => { .get("/api/v3/Samples/" + sampleId7 + "/attachments") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.AccessForbiddenStatusCode); }); // modify sample @@ -3576,7 +3576,7 @@ describe("2250: Sample Authorization", () => { .patch("/api/v3/Samples/" + sampleId1) .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("2280: update sample characteristic for public sample 10 as Unauthenticated User, which should fail", async () => { @@ -3592,7 +3592,7 @@ describe("2250: Sample Authorization", () => { .patch("/api/v3/Samples/" + sampleId10) .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") - .expect(TestData.CreationForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); // delete sample attachment @@ -3600,7 +3600,7 @@ describe("2250: Sample Authorization", () => { return request(appUrl) .delete("/api/v3/samples/" + sampleId1 + "/attachments/" + attachmentId1) .set("Accept", "application/json") - .expect(TestData.DeleteForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("4010: delete attachment 10 from sample 10 as Unauthenticated User, which should fail", async () => { @@ -3609,7 +3609,7 @@ describe("2250: Sample Authorization", () => { "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, ) .set("Accept", "application/json") - .expect(TestData.DeleteForbiddenStatusCode); + .expect(TestData.UnauthorizedStatusCode); }); it("4020: delete attachment 1 from sample 1 as User 5, which should fail", async () => { From d723ac9a862f6d66ba57762bf374a2690ca23449 Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Mon, 22 Jul 2024 18:40:45 +0200 Subject: [PATCH 095/258] added mongodb name env var for github api testing job. --- .github/workflows/test.yml | 1 + test/config/pretest.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a977c611..c7fdc3f8a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -131,6 +131,7 @@ jobs: env: ELASTICSEARCH_ENABLED: ${{ matrix.elasticsearch_enabled }} MONGODB_URI: mongodb://localhost:27017/scicat + MONGODB_TEST: scicat EXPRESS_SESSION_SECRET: a_scicat_secret JWT_SECRET: a_scicat_secret PORT: 3000 diff --git a/test/config/pretest.js b/test/config/pretest.js index 7351a4827..086d61e92 100644 --- a/test/config/pretest.js +++ b/test/config/pretest.js @@ -3,7 +3,7 @@ var chaiHttp = require("chai-http"); const { MongoClient } = require("mongodb"); -const testDbName = process.env.MONGDB_TEST_NAME || "scicat-test"; +const testDbName = process.env.MONGODB_TEST || "scicat-test"; const uri = `mongodb://localhost:27017/${testDbName}`; const client = new MongoClient(uri); From 5f3b02b20f48fe43342490af8430dcc6e6772394 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 23 Jul 2024 11:09:56 +0200 Subject: [PATCH 096/258] added api tests of new access checking endpoint for sample Auth and proposal Auth --- test/ProposalAuthorization.js | 118 ++++++++++++++++++++++++++++++++-- test/SampleAuthorization.js | 82 +++++++++++++++++++++++ 2 files changed, 195 insertions(+), 5 deletions(-) diff --git a/test/ProposalAuthorization.js b/test/ProposalAuthorization.js index 1ba2f3af4..05aa0e66c 100644 --- a/test/ProposalAuthorization.js +++ b/test/ProposalAuthorization.js @@ -218,6 +218,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + it("0061: check admin access to proposal 1 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0070: full query for proposals for admin", async () => { return request(appUrl) .get("/api/v3/proposals/fullquery") @@ -242,6 +254,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + it("0081: check admin access to proposal 2 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0090: access proposal 3 as admin", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid3) @@ -254,6 +278,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + it("0091: check admin access to proposal 3 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0100: list of proposals for user 1", async () => { return request(appUrl) .get("/api/v3/proposals") @@ -267,15 +303,27 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0110: access proposal 1 as user 1", async () => { + it("0110: access proposal 1 as user 1 should fail", async () => { return request(appUrl) - .get("/api/v3/proposals/" + 20170268) + .get("/api/v3/proposals/" + encodedProposalPid1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect("Content-Type", /json/) .expect(TestData.AccessForbiddenStatusCode); }); + it("0111: check user 1 access to proposal 1 should return false", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + it("0120: access proposal 2 as user 1", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid2) @@ -288,7 +336,19 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0130: access proposal 3 as user 1", async () => { + it("0121: check user 1 access to proposal 2 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + + it("0130: access proposal 3 as user 1 should fail", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid3) .set("Accept", "application/json") @@ -297,6 +357,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { .expect(TestData.AccessForbiddenStatusCode); }); + it("0131: check user 1 access to proposal 3 should return false", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + it("0140: full query for proposals for user 1", async () => { return request(appUrl) .get("/api/v3/proposals/fullquery") @@ -323,7 +395,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0160: access proposal 1 as user 2", async () => { + it("0160: access proposal 1 as user 2 should fail", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid1) .set("Accept", "application/json") @@ -332,7 +404,19 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { .expect(TestData.AccessForbiddenStatusCode); }); - it("0160: access proposal 2 as user 2", async () => { + it("0161: check user 2 access to proposal 1 should return false", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + + it("0165: access proposal 2 as user 2", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid2) .set("Accept", "application/json") @@ -344,6 +428,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + it("0166: check user 2 access to proposal 2 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0170: access proposal 3 as user 2", async () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid3) @@ -356,6 +452,18 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); + it("0171: check user 2 access to proposal 3 should return true", async () => { + return request(appUrl) + .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0180: full query for proposals for user 2", async () => { return request(appUrl) .get("/api/v3/proposals/fullquery") diff --git a/test/SampleAuthorization.js b/test/SampleAuthorization.js index 1f834f9b0..5317a4b38 100644 --- a/test/SampleAuthorization.js +++ b/test/SampleAuthorization.js @@ -1349,6 +1349,18 @@ describe("2250: Sample Authorization", () => { }); }); + it("0641: check Admin Ingestor access to public sample 1 should return true", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0645: fetch all attachments for sample 1 as Admin Ingestor", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1 + "/attachments") @@ -1585,6 +1597,18 @@ describe("2250: Sample Authorization", () => { .expect(TestData.CreationForbiddenStatusCode); }); + it("0731: check Sample Ingestor access to sample 1 should return false", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + it("0735: fetch all attachments for sample 1 as Sample Ingestor, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1 + "/attachments") @@ -1605,6 +1629,18 @@ describe("2250: Sample Authorization", () => { }); }); + it("0741: check Sample Ingestor access to sample 2 should return true", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId2 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0745: fetch all attachments for sample 2 as Sample Ingestor", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId2 + "/attachments") @@ -1769,6 +1805,18 @@ describe("2250: Sample Authorization", () => { .expect(TestData.CreationForbiddenStatusCode); }); + it("0831: check User 1 access to sample 2 should return false", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId1 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + it("0835: fetch all attachments for sample 1 as User 1, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1 + "/attachments") @@ -1805,6 +1853,18 @@ describe("2250: Sample Authorization", () => { }); }); + it("0851: check User 1 access to sample 3 should return true", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId3 + "/access") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("0855: fetch all attachments for sample 3 as User 1", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId3 + "/attachments") @@ -2736,6 +2796,17 @@ describe("2250: Sample Authorization", () => { .expect(TestData.AccessForbiddenStatusCode); }); + it("1331: check unauthenticated user access to sample 1 should return false", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId1 + "/access") + .set("Accept", "application/json") + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(false); + }); + }); + it("1335: fetch all attachments for sample 1 as Unauthenticated User, which should fail", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId1 + "/attachments") @@ -2866,6 +2937,17 @@ describe("2250: Sample Authorization", () => { }); }); + it("1421: check unauthenticated user access to public sample 10 should return true", async () => { + return request(appUrl) + .get("/api/v3/Samples/" + sampleId10 + "/access") + .set("Accept", "application/json") + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("canAccess").and.be.equal(true); + }); + }); + it("1425: fetch all attachments for sample 10 as Unauthenticated User", async () => { return request(appUrl) .get("/api/v3/Samples/" + sampleId10 + "/attachments") From 865cca4e2cf70049c1706982e472dee53ce35709 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 23 Jul 2024 11:21:27 +0200 Subject: [PATCH 097/258] chore: Update MongoDB test database name configuration --- .env.example | 1 + README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.env.example b/.env.example index 32b3cdc9a..801b3a454 100644 --- a/.env.example +++ b/.env.example @@ -17,6 +17,7 @@ LOGBOOK_BASE_URL="http://localhost:3030/scichatapi" METADATA_KEYS_RETURN_LIMIT=100 METADATA_PARENT_INSTANCES_RETURN_LIMIT=100 MONGODB_URI="mongodb://:@:27017/" +MONGDB_TEST_NAME="scicat-test" OAI_PROVIDER_ROUTE="" PID_PREFIX="" PUBLIC_URL_PREFIX="https://doi.esss.se/detail/" diff --git a/README.md b/README.md index 29f8d3337..d25d4a129 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ If you have any questions, please feel free to contact any member of the develop or the SciCat team at ESS. ## Contributing + If you're planning to contribute to this project by adding new functionality, we encourage you to discuss it first in the Discussions tab. This helps ensure that your proposed changes align with the project's goals and prevents duplicate efforts. Here's how you can initiate a discussion: 1. Go to the [Discussions tab](https://github.com/SciCatProject/scicat-backend-next/discussions). @@ -148,6 +149,7 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `METADATA_KEYS_RETURN_LIMIT` | number | Yes | The return limit for the `/Datasets/metadataKeys` endpoint. | | | `METADATA_PARENT_INSTANCES_RETURN_LIMIT` | number | Yes | The return limit of Datasets to extract metadata keys from for the `/Datasets/metadataKeys` endpoint. | | | `MONGODB_URI` | string | | The URI for your MongoDB instance. | | +| `MONGDB_TEST_NAME` | string | | The DB name for your MongoDB instance that runs on the local testing environment. |"scicat-test"| | `OAI_PROVIDER_ROUTE` | string | Yes | URI to OAI provider, used for the `/publisheddata/:id/resync` endpoint. | | | `PID_PREFIX` | string | | The facility PID prefix, with trailing slash. | | | `PUBLIC_URL_PREFIX` | string | | The base URL to the facility Landing Page. | | From f705241cdc0240f54a192542c724ad3c50430f42 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 23 Jul 2024 16:48:13 +0200 Subject: [PATCH 098/258] some fixes based on comment --- .env.example | 1 - .github/workflows/test.yml | 3 +-- README.md | 1 - src/proposals/proposals.controller.ts | 6 ++--- src/samples/samples.controller.ts | 4 +-- test/ProposalAuthorization.js | 26 +++++++++--------- test/SampleAuthorization.js | 38 +++++++++++++-------------- test/TestData.js | 1 + test/config/pretest.js | 2 +- 9 files changed, 40 insertions(+), 42 deletions(-) diff --git a/.env.example b/.env.example index 801b3a454..32b3cdc9a 100644 --- a/.env.example +++ b/.env.example @@ -17,7 +17,6 @@ LOGBOOK_BASE_URL="http://localhost:3030/scichatapi" METADATA_KEYS_RETURN_LIMIT=100 METADATA_PARENT_INSTANCES_RETURN_LIMIT=100 MONGODB_URI="mongodb://:@:27017/" -MONGDB_TEST_NAME="scicat-test" OAI_PROVIDER_ROUTE="" PID_PREFIX="" PUBLIC_URL_PREFIX="https://doi.esss.se/detail/" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c7fdc3f8a..93512ad10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -130,8 +130,7 @@ jobs: - name: API tests env: ELASTICSEARCH_ENABLED: ${{ matrix.elasticsearch_enabled }} - MONGODB_URI: mongodb://localhost:27017/scicat - MONGODB_TEST: scicat + MONGODB_URI: mongodb://localhost:27017/scicat-test-db EXPRESS_SESSION_SECRET: a_scicat_secret JWT_SECRET: a_scicat_secret PORT: 3000 diff --git a/README.md b/README.md index d25d4a129..9b9df853b 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,6 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `METADATA_KEYS_RETURN_LIMIT` | number | Yes | The return limit for the `/Datasets/metadataKeys` endpoint. | | | `METADATA_PARENT_INSTANCES_RETURN_LIMIT` | number | Yes | The return limit of Datasets to extract metadata keys from for the `/Datasets/metadataKeys` endpoint. | | | `MONGODB_URI` | string | | The URI for your MongoDB instance. | | -| `MONGDB_TEST_NAME` | string | | The DB name for your MongoDB instance that runs on the local testing environment. |"scicat-test"| | `OAI_PROVIDER_ROUTE` | string | Yes | URI to OAI provider, used for the `/publisheddata/:id/resync` endpoint. | | | `PID_PREFIX` | string | | The facility PID prefix, with trailing slash. | | | `PUBLIC_URL_PREFIX` | string | | The base URL to the facility Landing Page. | | diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index bbddc2410..3fddfa348 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -549,12 +549,12 @@ export class ProposalsController { return proposal; } - // GET /proposals/:pid/access + // GET /proposals/:pid/authorization @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) - @Get("/:pid/access") + @Get("/:pid/authorization") @ApiOperation({ summary: "Check user access to a specific proposal.", description: @@ -585,7 +585,7 @@ export class ProposalsController { proposal, request, ); - return { canAccess: canAccess }; + return { canAccess }; } // PATCH /proposals/:pid diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 9c5deb377..a5077fcdf 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -554,12 +554,12 @@ export class SamplesController { return sample; } - // GET /samples/:id/access + // GET /samples/:id/authorization @UseGuards(PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) - @Get("/:id/access") + @Get("/:id/authorization") @ApiOperation({ summary: "Check user access to a specific sample.", description: diff --git a/test/ProposalAuthorization.js b/test/ProposalAuthorization.js index 05aa0e66c..022a7ec16 100644 --- a/test/ProposalAuthorization.js +++ b/test/ProposalAuthorization.js @@ -114,7 +114,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { done(); }); - it("0000: adds proposal 1", async () => { + it("0010: adds proposal 1", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal1) @@ -130,7 +130,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0010: adds proposal 2", async () => { + it("0020: adds proposal 2", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal2) @@ -146,7 +146,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - it("0020: adds proposal 3", async () => { + it("0030: adds proposal 3", async () => { return request(appUrl) .post("/api/v3/proposals") .send(proposal3) @@ -162,7 +162,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { }); }); - // it("0030: adds proposal 10", async () => { + // it("0035: adds proposal 10", async () => { // return request(appUrl) // .post("/api/v3/proposals") // .send(proposal10) @@ -220,7 +220,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0061: check admin access to proposal 1 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -256,7 +256,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0081: check admin access to proposal 2 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid2 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -280,7 +280,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0091: check admin access to proposal 3 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid3 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -314,7 +314,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0111: check user 1 access to proposal 1 should return false", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -338,7 +338,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0121: check user 1 access to proposal 2 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid2 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -359,7 +359,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0131: check user 1 access to proposal 3 should return false", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid3 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -406,7 +406,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0161: check user 2 access to proposal 1 should return false", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid1 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect("Content-Type", /json/) @@ -430,7 +430,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0166: check user 2 access to proposal 2 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid2 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid2 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect("Content-Type", /json/) @@ -454,7 +454,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { it("0171: check user 2 access to proposal 3 should return true", async () => { return request(appUrl) - .get("/api/v3/proposals/" + encodedProposalPid3 + "/access") + .get("/api/v3/proposals/" + encodedProposalPid3 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect("Content-Type", /json/) diff --git a/test/SampleAuthorization.js b/test/SampleAuthorization.js index 5317a4b38..1baea17c8 100644 --- a/test/SampleAuthorization.js +++ b/test/SampleAuthorization.js @@ -485,7 +485,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0180: adds a new sample as an unauthenticated user with owner group as sampleingestor, which should fail", async () => { @@ -498,7 +498,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0190: adds a new sample as an unauthenticated user with owner group as user1, which should fail", async () => { @@ -511,7 +511,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0200: adds a new sample as an unauthenticated user with its owner group, which should fail", async () => { @@ -524,7 +524,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples") .send(sample) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0210: adds a new sample as Archive Manager with owner group as adminingestor, which should fail", async () => { @@ -977,7 +977,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId1 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0420: adds an attachment as an unauthenticated user to sample 2, which should fail", async () => { @@ -985,7 +985,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId2 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0430: adds an attachment as an unauthenticated user to sample 3, which should fail", async () => { @@ -993,7 +993,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId3 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0440: adds an attachment as an unauthenticated user to sample 4, which should fail", async () => { @@ -1001,7 +1001,7 @@ describe("2250: Sample Authorization", () => { .post("/api/v3/Samples/" + sampleId4 + "/attachments") .send(TestData.AttachmentCorrect) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("0450: adds an attachment as Archive Manager to sample 1, which should fail", async () => { @@ -1351,7 +1351,7 @@ describe("2250: Sample Authorization", () => { it("0641: check Admin Ingestor access to public sample 1 should return true", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 + "/access") + .get("/api/v3/Samples/" + sampleId1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1599,7 +1599,7 @@ describe("2250: Sample Authorization", () => { it("0731: check Sample Ingestor access to sample 1 should return false", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 + "/access") + .get("/api/v3/Samples/" + sampleId1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1631,7 +1631,7 @@ describe("2250: Sample Authorization", () => { it("0741: check Sample Ingestor access to sample 2 should return true", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 + "/access") + .get("/api/v3/Samples/" + sampleId2 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1807,7 +1807,7 @@ describe("2250: Sample Authorization", () => { it("0831: check User 1 access to sample 2 should return false", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 + "/access") + .get("/api/v3/Samples/" + sampleId1 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1855,7 +1855,7 @@ describe("2250: Sample Authorization", () => { it("0851: check User 1 access to sample 3 should return true", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 + "/access") + .get("/api/v3/Samples/" + sampleId3 + "/authorization") .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2798,7 +2798,7 @@ describe("2250: Sample Authorization", () => { it("1331: check unauthenticated user access to sample 1 should return false", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 + "/access") + .get("/api/v3/Samples/" + sampleId1 + "/authorization") .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) @@ -2939,7 +2939,7 @@ describe("2250: Sample Authorization", () => { it("1421: check unauthenticated user access to public sample 10 should return true", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 + "/access") + .get("/api/v3/Samples/" + sampleId10 + "/authorization") .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) @@ -3658,7 +3658,7 @@ describe("2250: Sample Authorization", () => { .patch("/api/v3/Samples/" + sampleId1) .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("2280: update sample characteristic for public sample 10 as Unauthenticated User, which should fail", async () => { @@ -3674,7 +3674,7 @@ describe("2250: Sample Authorization", () => { .patch("/api/v3/Samples/" + sampleId10) .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); // delete sample attachment @@ -3682,7 +3682,7 @@ describe("2250: Sample Authorization", () => { return request(appUrl) .delete("/api/v3/samples/" + sampleId1 + "/attachments/" + attachmentId1) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("4010: delete attachment 10 from sample 10 as Unauthenticated User, which should fail", async () => { @@ -3691,7 +3691,7 @@ describe("2250: Sample Authorization", () => { "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, ) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode); + .expect(TestData.CreationUnauthorizedStatusCode); }); it("4020: delete attachment 1 from sample 1 as User 5, which should fail", async () => { diff --git a/test/TestData.js b/test/TestData.js index f5ca82fbd..91fd1bb28 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -18,6 +18,7 @@ const TestData = { BadRequestStatusCode: 400, AccessForbiddenStatusCode: 403, UnauthorizedStatusCode: 401, + CreationUnauthorizedStatusCode: 401, ConflictStatusCode: 409, ApplicationErrorStatusCode: 500, LoginSuccessfulStatusCode: 201, diff --git a/test/config/pretest.js b/test/config/pretest.js index 086d61e92..b1864ac4b 100644 --- a/test/config/pretest.js +++ b/test/config/pretest.js @@ -3,7 +3,7 @@ var chaiHttp = require("chai-http"); const { MongoClient } = require("mongodb"); -const testDbName = process.env.MONGODB_TEST || "scicat-test"; +const testDbName = "scicat-test-db"; const uri = `mongodb://localhost:27017/${testDbName}`; const client = new MongoClient(uri); From ec6a2927a82d2bbc40ec050c8e4632d8aa22521f Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 24 Jul 2024 11:52:35 +0200 Subject: [PATCH 099/258] chore: Update MongoDB test database configuration --- test/config/pretest.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/config/pretest.js b/test/config/pretest.js index b1864ac4b..f935d2239 100644 --- a/test/config/pretest.js +++ b/test/config/pretest.js @@ -1,20 +1,19 @@ /* eslint-disable @typescript-eslint/no-var-requires */ //NOTE: Here we load and initialize some global variables that are used throughout the tests - +require("dotenv").config(); var chaiHttp = require("chai-http"); + const { MongoClient } = require("mongodb"); -const testDbName = "scicat-test-db"; -const uri = `mongodb://localhost:27017/${testDbName}`; -const client = new MongoClient(uri); +const client = new MongoClient(process.env.MONGODB_URI); async function loadChai() { const { chai } = import("chai"); chai.use(chaiHttp); await client.connect(); } -loadChai(); +loadChai(); global.appUrl = "http://localhost:3000"; global.request = require("supertest"); -global.db = client.db(testDbName); +global.db = client.db(); From 9bccdaeb676f03dd3e8a86c0671bea1d7b45eb1b Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 15:17:52 +0200 Subject: [PATCH 100/258] Enable FiltersConfig and ScientificConditions on the BE --- src/users/schemas/user-settings.schema.ts | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index d0682b629..f365d2f83 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -5,6 +5,31 @@ import { Document } from "mongoose"; export type UserSettingsDocument = UserSettings & Document; +// Define possible filter component types as a union of string literals +export type FilterComponentType = + | "LocationFilterComponent" + | "PidFilterComponent" + | "PidFilterContainsComponent" + | "PidFilterStartsWithComponent" + | "GroupFilterComponent" + | "TypeFilterComponent" + | "KeywordFilterComponent" + | "DateRangeFilterComponent" + | "TextFilterComponent"; + +// Define the Filter interface +export interface FilterConfig { + type: FilterComponentType; + visible: boolean; +} + +// Define the Condition interface +export interface ScientificCondition { + field: string; + value: string; + operator: string; +} + @Schema({ collection: "UserSetting", toJSON: { @@ -43,6 +68,22 @@ export class UserSettings { @ApiProperty({ type: String, required: true }) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }) userId: string; + + @ApiProperty({ + type: [Object], + default: [], + description: "Array of filters the user has set", + }) + @Prop({ type: [{ type: Object }], default: [] }) + filters: FilterConfig[]; + + @ApiProperty({ + type: [Object], + default: [], + description: "Array of conditions the user has set", + }) + @Prop({ type: [{ type: Object }], default: [] }) + conditions: ScientificCondition[]; } export const UserSettingsSchema = SchemaFactory.createForClass(UserSettings); From 3df26971dd22c4c6e0adcd11df4e047865281795 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 15:24:55 +0200 Subject: [PATCH 101/258] Add default value --- src/users/schemas/user-settings.schema.ts | 27 +++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index f365d2f83..c93c473d0 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -71,10 +71,33 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: [], + default: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], description: "Array of filters the user has set", }) - @Prop({ type: [{ type: Object }], default: [] }) + @Prop({ + type: [{ type: Object }], + default: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + }) filters: FilterConfig[]; @ApiProperty({ From 680317c7939f437689588d57d9f94d16acf5a8e7 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 16:32:34 +0200 Subject: [PATCH 102/258] Fix cp non existing file --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62021d8b6..0b7c48859 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start\"", "test:api:jest": "jest --config ./test/config/jest-e2e.json --maxWorkers=50%", "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js ", - "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.json.test functionalAccounts.json" + "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.test.json functionalAccounts.json" }, "dependencies": { "@casl/ability": "^6.3.2", From ff7f08116f4d49ee6fd4d6d44d5372ed6d182ae6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:44:26 +0000 Subject: [PATCH 103/258] build(deps-dev): bump @typescript-eslint/parser from 7.16.1 to 7.17.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.16.1 to 7.17.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.17.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0c686826..a59228822 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3226,15 +3226,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", - "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "debug": "^4.3.4" }, "engines": { @@ -3253,6 +3253,105 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", + "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", + "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", + "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", + "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.17.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.16.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", From 9a167f51e82ea4d021d7ced45c13617bd129724e Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Mon, 29 Jul 2024 17:54:23 +0200 Subject: [PATCH 104/258] updated configuration for new FE datafiles actions --- src/config/frontend.config.json | 62 ++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 8c5833abf..ba6121643 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -2,21 +2,21 @@ "accessTokenPrefix": "Bearer ", "addDatasetEnabled": false, "archiveWorkflowEnabled": false, + "datasetReduceEnabled": false, "datasetJsonScientificMetadata": true, - "datasetReduceEnabled": true, "editDatasetSampleEnabled": true, "editMetadataEnabled": true, "editPublishedData": false, "addSampleEnabled": false, "externalAuthEndpoint": "/api/v3/auth/msad", - "facility": "ESS", - "loginFacilityLabel": "ESS", + "facility": "SciCat Vanilla", + "siteIcon": "site-header-logo.png", + "loginFacilityLabel": "SciCat Vanilla", "loginLdapLabel": "Ldap", "loginLocalLabel": "Local", "loginFacilityEnabled": true, "loginLdapEnabled": true, "loginLocalEnabled": true, - "facilityLoginLabel": "ESS", "localLoginLabel": "Local", "fileColorEnabled": true, "fileDownloadEnabled": true, @@ -24,9 +24,9 @@ "ingestManual": null, "jobsEnabled": true, "jsonMetadataEnabled": true, - "jupyterHubUrl": "https://jupyterhub.esss.lu.se/", + "jupyterHubUrl": "", "landingPage": "doi.ess.eu/detail/", - "lbBaseURL": "", + "lbBaseURL": "http://127.0.0.1:3000", "localColumns": [ { "name": "select", @@ -112,7 +112,7 @@ "maxDirectDownloadSize": 5000000000, "metadataPreviewEnabled": true, "metadataStructure": "", - "multipleDownloadAction": "https://scicatfileserver.esss.dk/zip", + "multipleDownloadAction": "http:/127.0.0.1:3012/zip", "multipleDownloadEnabled": true, "oAuth2Endpoints": [ { @@ -134,5 +134,51 @@ "tableSciDataEnabled": true, "datasetDetailsShowMissingProposalId": false, "notificationInterceptorEnabled": true, - "metadataEditingUnitListDisabled": true + "metadataEditingUnitListDisabled": true, + "datafilesActionsEnabled" : true, + "datafilesActions" : [ + { + "id" : "eed8efec-4354-11ef-a3b5-d75573a5d37f", + "order" : 4, + "label" : "Download All", + "files" : "all", + "mat_icon" : "download", + "url" : "", + "target" : "_blank", + "enabled" : "#SizeLimit", + "authorization" : ["#datasetAccess", "#datasetPublic" ] + }, + { + "id" : "3072fafc-4363-11ef-b9f9-ebf568222d26", + "order" : 3, + "label" : "Download Selected", + "files" : "selected", + "mat_icon" : "download", + "url" : "", + "target" : "_blank", + "enabled" : "#Selected && #SizeLimit", + "authorization" : ["#datasetAccess", "#datasetPublic" ] + }, + { + "id" : "4f974f0e-4364-11ef-9c63-03d19f813f4e", + "order" : 2, + "label" : "Notebook All", + "files" : "all", + "icon" : "/assets/icons/jupyter_logo.png", + "url" : "", + "target" : "_blank", + "authorization" : ["#datasetAccess", "#datasetPublic" ] + }, + { + "id" : "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd", + "order" : 1, + "label" : "Notebook Selected", + "files" : "selected", + "icon" : "/assets/icons/jupyter_logo.png", + "url" : "", + "target" : "_blank", + "enabled" : "#Selected", + "authorization" : ["#datasetAccess", "#datasetPublic" ] + } + ] } From 56da1d67534a6ad5c59ddb9c38a4e59c8175eb1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:44:56 +0000 Subject: [PATCH 105/258] build(deps-dev): bump @nestjs/schematics from 10.1.2 to 10.1.3 Bumps [@nestjs/schematics](https://github.com/nestjs/schematics) from 10.1.2 to 10.1.3. - [Release notes](https://github.com/nestjs/schematics/releases) - [Changelog](https://github.com/nestjs/schematics/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/schematics/compare/10.1.2...10.1.3) --- updated-dependencies: - dependency-name: "@nestjs/schematics" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a59228822..fd8fa2c92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2353,9 +2353,9 @@ } }, "node_modules/@nestjs/schematics": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.2.tgz", - "integrity": "sha512-S0bMtZM5U4mAiqkhRyZkXgjmOHBS5P/lp/vEydgMR4F7csOShc3jFeKVs1Eghd9xCFezGKy3SHy7hFT6dpPhWQ==", + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.3.tgz", + "integrity": "sha512-aLJ4Nl/K/u6ZlgLa0NjKw5CuBOIgc6vudF42QvmGueu5FaMGM6IJrAuEvB5T2kr0PAfVwYmDFBBHCWdYhTw4Tg==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", From 71e5a1ab3f0057c3baa40fdc6109ba1497fa9868 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2024 08:07:47 +0000 Subject: [PATCH 106/258] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.16.1 to 7.18.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.18.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 70 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd8fa2c92..926aa47fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3193,16 +3193,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3353,13 +3353,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3370,13 +3370,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3397,9 +3397,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3410,13 +3410,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3462,15 +3462,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3484,12 +3484,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From d42f8c487c00879f3a70d71d082f44fd490c502e Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 30 Jul 2024 14:18:13 +0200 Subject: [PATCH 107/258] chore: enbaled datasetReduce in config (#1349) --- src/config/frontend.config.json | 78 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index ba6121643..9ae4a1688 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -2,7 +2,7 @@ "accessTokenPrefix": "Bearer ", "addDatasetEnabled": false, "archiveWorkflowEnabled": false, - "datasetReduceEnabled": false, + "datasetReduceEnabled": true, "datasetJsonScientificMetadata": true, "editDatasetSampleEnabled": true, "editMetadataEnabled": true, @@ -135,50 +135,50 @@ "datasetDetailsShowMissingProposalId": false, "notificationInterceptorEnabled": true, "metadataEditingUnitListDisabled": true, - "datafilesActionsEnabled" : true, - "datafilesActions" : [ - { - "id" : "eed8efec-4354-11ef-a3b5-d75573a5d37f", - "order" : 4, - "label" : "Download All", - "files" : "all", - "mat_icon" : "download", - "url" : "", - "target" : "_blank", - "enabled" : "#SizeLimit", - "authorization" : ["#datasetAccess", "#datasetPublic" ] + "datafilesActionsEnabled": true, + "datafilesActions": [ + { + "id": "eed8efec-4354-11ef-a3b5-d75573a5d37f", + "order": 4, + "label": "Download All", + "files": "all", + "mat_icon": "download", + "url": "", + "target": "_blank", + "enabled": "#SizeLimit", + "authorization": ["#datasetAccess", "#datasetPublic"] }, { - "id" : "3072fafc-4363-11ef-b9f9-ebf568222d26", - "order" : 3, - "label" : "Download Selected", - "files" : "selected", - "mat_icon" : "download", - "url" : "", - "target" : "_blank", - "enabled" : "#Selected && #SizeLimit", - "authorization" : ["#datasetAccess", "#datasetPublic" ] + "id": "3072fafc-4363-11ef-b9f9-ebf568222d26", + "order": 3, + "label": "Download Selected", + "files": "selected", + "mat_icon": "download", + "url": "", + "target": "_blank", + "enabled": "#Selected && #SizeLimit", + "authorization": ["#datasetAccess", "#datasetPublic"] }, { - "id" : "4f974f0e-4364-11ef-9c63-03d19f813f4e", - "order" : 2, - "label" : "Notebook All", - "files" : "all", - "icon" : "/assets/icons/jupyter_logo.png", - "url" : "", - "target" : "_blank", - "authorization" : ["#datasetAccess", "#datasetPublic" ] + "id": "4f974f0e-4364-11ef-9c63-03d19f813f4e", + "order": 2, + "label": "Notebook All", + "files": "all", + "icon": "/assets/icons/jupyter_logo.png", + "url": "", + "target": "_blank", + "authorization": ["#datasetAccess", "#datasetPublic"] }, { - "id" : "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd", - "order" : 1, - "label" : "Notebook Selected", - "files" : "selected", - "icon" : "/assets/icons/jupyter_logo.png", - "url" : "", - "target" : "_blank", - "enabled" : "#Selected", - "authorization" : ["#datasetAccess", "#datasetPublic" ] + "id": "fa3ce6ee-482d-11ef-95e9-ff2c80dd50bd", + "order": 1, + "label": "Notebook Selected", + "files": "selected", + "icon": "/assets/icons/jupyter_logo.png", + "url": "", + "target": "_blank", + "enabled": "#Selected", + "authorization": ["#datasetAccess", "#datasetPublic"] } ] } From 9153eeb35e5da2ed181ef79c4042893f6f28ab27 Mon Sep 17 00:00:00 2001 From: Sofya Laskina <44316816+sofyalaski@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:23:58 +0200 Subject: [PATCH 108/258] remove nested structure in tests authorization (#1350) * remove nested structure in tests authorization * remove a mistake * fix requested changes * fix indent --- test/DatasetAuthorization.js | 97 +++++++------------- test/DatasetFilter.js | 78 +++++----------- test/DatasetLifecycle.js | 33 +++---- test/DatasetSimple.js | 32 ++----- test/DerivedDataset.js | 62 ++++--------- test/DerivedDatasetDatablock.js | 35 +++---- test/DerivedDatasetOrigDatablock.js | 38 +++----- test/ElasticSearch.js | 32 ++----- test/Instrument.js | 47 +++------- test/InstrumentsFilter.js | 78 +++++----------- test/Jobs.js | 66 ++++++++------ test/LoginUtils.js | 50 +++++----- test/OrigDatablockForRawDataset.js | 32 ++----- test/Policy.js | 34 +++---- test/Proposal.js | 47 +++------- test/ProposalAuthorization.js | 99 +++++++------------- test/PublishedData.js | 32 ++----- test/RandomizedDatasetPermissions.js | 80 ++++++---------- test/RawDataset.js | 47 +++------- test/RawDatasetDatablock.js | 36 +++----- test/RawDatasetOrigDatablock.js | 38 +++----- test/ResetDataset.js | 32 ++----- test/Sample.js | 34 +++---- test/SampleAuthorization.js | 128 +++++++++----------------- test/UserAuthorization.js | 132 +++++++++++---------------- test/Users.js | 20 ++-- 26 files changed, 503 insertions(+), 936 deletions(-) diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index bcecc2b03..ab707200d 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -45,71 +45,38 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (tokenVal) => { - accessTokenUser3 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - utils.getToken( - appUrl, - { - username: "admin", - password: TestData.Accounts["admin"]["password"], - }, - (tokenVal) => { - accessTokenAdmin = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }); - + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenAdmin = await utils.getToken(appUrl, { + username: "admin", + password: TestData.Accounts["admin"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + }); + afterEach((done) => { sandbox.restore(); done(); diff --git a/test/DatasetFilter.js b/test/DatasetFilter.js index 5dedb8e5a..4fedab6f9 100644 --- a/test/DatasetFilter.js +++ b/test/DatasetFilter.js @@ -96,59 +96,31 @@ describe("0400: DatasetFilter: Test retrieving datasets using filtering capabili before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser3 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); afterEach((done) => { diff --git a/test/DatasetLifecycle.js b/test/DatasetLifecycle.js index 2f3fed3bc..3b26585de 100644 --- a/test/DatasetLifecycle.js +++ b/test/DatasetLifecycle.js @@ -16,30 +16,19 @@ describe("0500: DatasetLifecycle: Test facet and filter queries", () => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); + it("0010: adds a new raw dataset", async () => { return request(appUrl) .post("/api/v3/Datasets") diff --git a/test/DatasetSimple.js b/test/DatasetSimple.js index efaf246e0..897b79e9f 100644 --- a/test/DatasetSimple.js +++ b/test/DatasetSimple.js @@ -16,28 +16,16 @@ describe("0200: Dataset Simple: Check different dataset types and their inherita db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); function deleteDataset(item) { diff --git a/test/DerivedDataset.js b/test/DerivedDataset.js index 61b960799..1ccadc9ce 100644 --- a/test/DerivedDataset.js +++ b/test/DerivedDataset.js @@ -17,48 +17,26 @@ describe("0700: DerivedDataset: Derived Datasets", () => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); async function deleteDataset(item) { diff --git a/test/DerivedDatasetDatablock.js b/test/DerivedDatasetDatablock.js index ca62c7fc8..8ef6ff8c7 100644 --- a/test/DerivedDatasetDatablock.js +++ b/test/DerivedDatasetDatablock.js @@ -10,32 +10,19 @@ describe("0750: DerivedDatasetDatablock: Test Datablocks and their relation to d let datablockId1 = null; let datablockId2 = null; + before(() => { + db.collection("Dataset").deleteMany({}); + }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); - beforeEach((done) => { - before(() => { - db.collection("Dataset").deleteMany({}); + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], }); - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); }); it("0100:adds a new derived dataset", async () => { diff --git a/test/DerivedDatasetOrigDatablock.js b/test/DerivedDatasetOrigDatablock.js index a8566b816..8dcc066e3 100644 --- a/test/DerivedDatasetOrigDatablock.js +++ b/test/DerivedDatasetOrigDatablock.js @@ -11,32 +11,20 @@ describe("0800: DerivedDatasetOrigDatablock: Test OrigDatablocks and their relat let origDatablockId1 = null; let origDatablockId2 = null; - beforeEach((done) => { - before(() => { - db.collection("Dataset").deleteMany({}); - db.collection("OrigDatablock").deleteMany({}); + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("OrigDatablock").deleteMany({}); + }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], }); - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); }); it("0010: adds a new derived dataset", async () => { diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js index 221a57043..cfec71f29 100644 --- a/test/ElasticSearch.js +++ b/test/ElasticSearch.js @@ -45,28 +45,16 @@ const scientificMetadata = (values) => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); it("0010: adds a new raw dataset with scientificMetadata", async () => { diff --git a/test/Instrument.js b/test/Instrument.js index 613f5f621..385f5ebe9 100644 --- a/test/Instrument.js +++ b/test/Instrument.js @@ -20,38 +20,21 @@ describe("0900: Instrument: instrument management, creation, update, deletion an before(() => { db.collection("Instrument").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - done(); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); it("0010: adds new instrument #1 as ingestor", async () => { diff --git a/test/InstrumentsFilter.js b/test/InstrumentsFilter.js index a3958f90d..83981f3c1 100644 --- a/test/InstrumentsFilter.js +++ b/test/InstrumentsFilter.js @@ -45,59 +45,31 @@ describe("1000: InstrumentFilter: Test retrieving instruments using filtering ca before(() => { db.collection("Instrument").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (tokenVal) => { - accessTokenUser3 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); afterEach((done) => { diff --git a/test/Jobs.js b/test/Jobs.js index 9fa9375c9..b36393792 100644 --- a/test/Jobs.js +++ b/test/Jobs.js @@ -21,38 +21,46 @@ var publicJobIds = []; var origDatablockId = null; describe.skip("1100: Jobs: Test New Job Model", () => { - before((done) => { + before(() => { db.collection("Dataset").deleteMany({}); db.collection("Job").deleteMany({}); + }); - archiveJob = { ...TestData.ArchiveJob }; - retrieveJob = { ...TestData.RetrieveJob }; - publicJob = { ...TestData.PublicJob }; - done(); - }); - - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async () => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenUser51 = await utils.getToken(appUrl, { + username: "user5.1", + password: TestData.Accounts["user5.1"]["password"], + }); + + accessTokenUser52 = await utils.getToken(appUrl, { + username: "user5.2", + password: TestData.Accounts["user5.2"]["password"], + }); + + accessTokenAdmin = await utils.getToken(appUrl, { + username: "admin", + password: TestData.Accounts["admin"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); it("0010: adds a new raw dataset", async () => { diff --git a/test/LoginUtils.js b/test/LoginUtils.js index b54f82ea3..0a1cb950e 100644 --- a/test/LoginUtils.js +++ b/test/LoginUtils.js @@ -1,31 +1,35 @@ /* eslint-disable @typescript-eslint/no-var-requires */ var request = require("supertest"); -exports.getToken = function (appUrl, user, cb) { - request(appUrl) - .post("/api/v3/Users/Login?include=user") - .send(user) - .set("Accept", "application/json") - .end((err, res) => { - if (err) { - cb(err); - } else { - cb(res.body.id); - } - }); +exports.getToken = function (appUrl, user) { + return new Promise((resolve, reject) => { + request(appUrl) + .post("/api/v3/Users/Login?include=user") + .send(user) + .set("Accept", "application/json") + .end((err, res) => { + if (err) { + reject(err); + } else { + resolve(res.body.id); + } + }); + }); }; -exports.getIdAndToken = function (appUrl, user, cb) { - request(appUrl) - .post("/api/v3/Users/Login?include=user") - .send(user) - .set("Accept", "application/json") - .end((err, res) => { - if (err) { - cb(err); - } else { - cb(res.body.userId, res.body.id); - } +exports.getIdAndToken = function (appUrl, user) { + return new Promise((resolve, reject) => { + request(appUrl) + .post("/api/v3/Users/Login?include=user") + .send(user) + .set("Accept", "application/json") + .end((err, res) => { + if (err) { + reject(err); + } else { + resolve({userId:res.body.userId, token:res.body.id}); + } + }); }); }; diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index e7d226d62..057134d35 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -23,28 +23,16 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati db.collection("Dataset").deleteMany({}); db.collection("OrigDatablock").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); origDatablockData1 = { ...TestData.OrigDataBlockCorrect1, diff --git a/test/Policy.js b/test/Policy.js index e6b3b9fa4..7339542fb 100644 --- a/test/Policy.js +++ b/test/Policy.js @@ -25,30 +25,18 @@ describe("1300: Policy: Simple Policy tests", () => { before(() => { db.collection("Policy").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + }); + it("0010: adds a new policy", async () => { return request(appUrl) .post("/api/v3/Policies") diff --git a/test/Proposal.js b/test/Proposal.js index 411aa220f..cb0ae6661 100644 --- a/test/Proposal.js +++ b/test/Proposal.js @@ -15,38 +15,21 @@ describe("1500: Proposal: Simple Proposal", () => { before(() => { db.collection("Proposal").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "proposalIngestor", - password: TestData.Accounts["proposalIngestor"]["password"], - }, - (tokenVal) => { - accessTokenProposalIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenProposalIngestor = await utils.getToken(appUrl, { + username: "proposalIngestor", + password: TestData.Accounts["proposalIngestor"]["password"], + }); + + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); // the following two function definition prepare for diff --git a/test/ProposalAuthorization.js b/test/ProposalAuthorization.js index 022a7ec16..8294895f3 100644 --- a/test/ProposalAuthorization.js +++ b/test/ProposalAuthorization.js @@ -9,7 +9,7 @@ let accessTokenProposalIngestor = null, accessTokenArchiveManager = null, accessTokenAdminIngestor = null, accessTokenUser1 = null, - accessTokenUser2 = null; + accessTokenUser3 = null; let proposalPid1 = null, encodedProposalPid1 = null, @@ -53,60 +53,31 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { before(() => { db.collection("Proposal").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - - utils.getToken( - appUrl, - { - username: "proposalIngestor", - password: TestData.Accounts["proposalIngestor"]["password"], - }, - (tokenVal) => { - accessTokenProposalIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenProposalIngestor = await utils.getToken(appUrl, { + username: "proposalIngestor", + password: TestData.Accounts["proposalIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); afterEach((done) => { @@ -386,7 +357,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals") .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { @@ -399,7 +370,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid1) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.AccessForbiddenStatusCode); }); @@ -408,7 +379,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid1 + "/authorization") .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.SuccessfulGetStatusCode) .then((res) => { @@ -420,7 +391,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid2) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.SuccessfulGetStatusCode) .then((res) => { @@ -432,7 +403,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid2 + "/authorization") .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.SuccessfulGetStatusCode) .then((res) => { @@ -444,7 +415,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid3) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.SuccessfulGetStatusCode) .then((res) => { @@ -456,7 +427,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/" + encodedProposalPid3 + "/authorization") .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect("Content-Type", /json/) .expect(TestData.SuccessfulGetStatusCode) .then((res) => { @@ -468,7 +439,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get("/api/v3/proposals/fullquery") .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { @@ -482,7 +453,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { return request(appUrl) .get(`/api/v3/proposals/fullfacet`) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { diff --git a/test/PublishedData.js b/test/PublishedData.js index 69531a188..dccfbfcb1 100644 --- a/test/PublishedData.js +++ b/test/PublishedData.js @@ -38,28 +38,16 @@ describe("1600: PublishedData: Test of access to published data", () => { db.collection("Dataset").deleteMany({}); db.collection("PublishedData").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); afterEach((done) => { diff --git a/test/RandomizedDatasetPermissions.js b/test/RandomizedDatasetPermissions.js index 9a31f8eb2..c69781853 100644 --- a/test/RandomizedDatasetPermissions.js +++ b/test/RandomizedDatasetPermissions.js @@ -188,61 +188,33 @@ describe("1700: Randomized Datasets: permission test with bigger amount of data" before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (tokenVal) => { - accessTokenUser3 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + }); + it("0010: access private dataset as unauthenticated user", async () => { await addAllDatasets(); const randomGroup = randomIntFromInterval(1, 4); diff --git a/test/RawDataset.js b/test/RawDataset.js index 89a04f3dd..c150faa40 100644 --- a/test/RawDataset.js +++ b/test/RawDataset.js @@ -18,38 +18,21 @@ describe("1900: RawDataset: Raw Datasets", () => { db.collection("Dataset").deleteMany({}); db.collection("Proposals").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "proposalIngestor", - password: TestData.Accounts["proposalIngestor"]["password"], - }, - (tokenVal) => { - accessProposalToken = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); - }, - ); + beforeEach(async() => { + accessProposalToken = await utils.getToken(appUrl, { + username: "proposalIngestor", + password: TestData.Accounts["proposalIngestor"]["password"], + }); + + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); it("0010: adds a new proposal", async () => { diff --git a/test/RawDatasetDatablock.js b/test/RawDatasetDatablock.js index fae50686b..952230220 100644 --- a/test/RawDatasetDatablock.js +++ b/test/RawDatasetDatablock.js @@ -9,32 +9,20 @@ describe("1800: RawDatasetDatablock: Test Datablocks and their relation to raw D var datasetPid = null; var datablockId = null; var datablockId2 = null; + + before(() => { + db.collection("Dataset").deleteMany({}); + }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); - beforeEach((done) => { - before(() => { - db.collection("Dataset").deleteMany({}); + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], }); - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); }); it("0010: adds a new raw dataset", async () => { diff --git a/test/RawDatasetOrigDatablock.js b/test/RawDatasetOrigDatablock.js index fc46197a1..553d5bbb0 100644 --- a/test/RawDatasetOrigDatablock.js +++ b/test/RawDatasetOrigDatablock.js @@ -14,32 +14,20 @@ describe("2000: RawDatasetOrigDatablock: Test OrigDatablocks and their relation origDatablockWithEmptyChkAlg = null, origDatablockWithValidChkAlg = null; - beforeEach((done) => { - before(() => { - db.collection("Dataset").deleteMany({}); - db.collection("OrigDatablock").deleteMany({}); + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("OrigDatablock").deleteMany({}); + }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], }); - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); origDatablockData1 = { ...TestData.OrigDataBlockCorrect1 }; origDatablockData2 = { ...TestData.OrigDataBlockCorrect2 }; diff --git a/test/ResetDataset.js b/test/ResetDataset.js index a737bbd3e..66f97ead0 100644 --- a/test/ResetDataset.js +++ b/test/ResetDataset.js @@ -150,28 +150,16 @@ var foundId1 = null; var foundId2 = null; describe("2100: ResetDataset: Create Dataset and its Datablocks, then reset Datablocks and embedded Datasetlifecycle status", () => { - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); // first get existing datasets with the test archieId to allow to delete them diff --git a/test/Sample.js b/test/Sample.js index 3baccdb69..3e05d007c 100644 --- a/test/Sample.js +++ b/test/Sample.js @@ -14,29 +14,17 @@ describe("2200: Sample: Simple Sample", () => { before(() => { db.collection("Sample").deleteMany({}); db.collection("Dataset").deleteMany({}); - }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); - }, - ); - }, - ); + }); + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); }); it("0010: adds a new sample", async () => { diff --git a/test/SampleAuthorization.js b/test/SampleAuthorization.js index 1baea17c8..d9f78c39b 100644 --- a/test/SampleAuthorization.js +++ b/test/SampleAuthorization.js @@ -39,93 +39,47 @@ describe("2250: Sample Authorization", () => { before(() => { db.collection("Sample").deleteMany({}); }); - beforeEach((done) => { - utils.getToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (tokenVal) => { - accessTokenAdminIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "sampleIngestor", - password: TestData.Accounts["sampleIngestor"]["password"], - }, - (tokenVal) => { - accessTokenSampleIngestor = tokenVal; - utils.getToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (tokenVal) => { - accessTokenUser1 = tokenVal; - utils.getToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (tokenVal) => { - accessTokenUser2 = tokenVal; - utils.getToken( - appUrl, - { - username: "archiveManager", - password: - TestData.Accounts["archiveManager"]["password"], - }, - (tokenVal) => { - accessTokenArchiveManager = tokenVal; - utils.getToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (tokenVal) => { - accessTokenUser3 = tokenVal; - utils.getToken( - appUrl, - { - username: "user4", - password: - TestData.Accounts["user4"]["password"], - }, - (tokenVal) => { - accessTokenUser4 = tokenVal; - utils.getToken( - appUrl, - { - username: "user5.1", - password: - TestData.Accounts["user5.1"]["password"], - }, - (tokenVal) => { - accessTokenUser5 = tokenVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }); - + beforeEach(async() => { + accessTokenAdminIngestor = await utils.getToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + + accessTokenSampleIngestor = await utils.getToken(appUrl, { + username: "sampleIngestor", + password: TestData.Accounts["sampleIngestor"]["password"], + }); + accessTokenUser1 = await utils.getToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + + accessTokenUser2 = await utils.getToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + + accessTokenUser3 = await utils.getToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + + accessTokenUser4 = await utils.getToken(appUrl, { + username: "user4", + password: TestData.Accounts["user4"]["password"], + }); + + accessTokenUser5 = await utils.getToken(appUrl, { + username: "user5.1", + password: TestData.Accounts["user5.1"]["password"], + }); + + accessTokenArchiveManager = await utils.getToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + }); + it("0010: adds sample 1 as Admin Ingestor with owner group its own group", async () => { let sample = { ...TestData.SampleCorrect, diff --git a/test/UserAuthorization.js b/test/UserAuthorization.js index 205b2ca34..a8fb227f0 100644 --- a/test/UserAuthorization.js +++ b/test/UserAuthorization.js @@ -21,87 +21,57 @@ let accessTokenAdminIngestor = null, userIdArchiveManager = null; describe("2300: User Authorization: test that user authorization are correct", () => { - beforeEach((done) => { - utils.getIdAndToken( - appUrl, - { - username: "adminIngestor", - password: TestData.Accounts["adminIngestor"]["password"], - }, - (idVal, tokenVal) => { - accessTokenAdminIngestor = tokenVal; - userIdIngestor = idVal; - utils.getIdAndToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (idVal, tokenVal) => { - accessTokenUser1 = tokenVal; - userIdUser1 = idVal; - utils.getIdAndToken( - appUrl, - { - username: "user2", - password: TestData.Accounts["user2"]["password"], - }, - (idVal, tokenVal) => { - accessTokenUser2 = tokenVal; - userIdUser2 = idVal; - utils.getIdAndToken( - appUrl, - { - username: "user3", - password: TestData.Accounts["user3"]["password"], - }, - (idVal, tokenVal) => { - accessTokenUser3 = tokenVal; - userIdUser3 = idVal; - utils.getIdAndToken( - appUrl, - { - username: "user4", - password: TestData.Accounts["user4"]["password"], - }, - (idVal, tokenVal) => { - accessTokenUser4 = tokenVal; - userIdUser4 = idVal; - utils.getIdAndToken( - appUrl, - { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], - }, - (idVal, tokenVal) => { - accessTokenArchiveManager = tokenVal; - userIdArchiveManager = idVal; - utils.getIdAndToken( - appUrl, - { - username: "admin", - password: TestData.Accounts["admin"]["password"], - }, - (idVal, tokenVal) => { - accessTokenAdmin = tokenVal; - userIdAdmin = idVal; - done(); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }, - ); - }); - + beforeEach(async() => { + const loginResponseIngestor = await utils.getIdAndToken(appUrl, { + username: "adminIngestor", + password: TestData.Accounts["adminIngestor"]["password"], + }); + userIdIngestor = loginResponseIngestor.userId; + accessTokenAdminIngestor = loginResponseIngestor.token; + + const loginResponseUser1 = await utils.getIdAndToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + userIdUser1 = loginResponseUser1.userId; + accessTokenUser1 = loginResponseUser1.token; + + const loginResponseUser2 = await utils.getIdAndToken(appUrl, { + username: "user2", + password: TestData.Accounts["user2"]["password"], + }); + userIdUser2 = loginResponseUser2.userId; + accessTokenUser2 = loginResponseUser2.token; + + const loginResponseUser3 = await utils.getIdAndToken(appUrl, { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }); + userIdUser3 = loginResponseUser3.userId + accessTokenUser3 = loginResponseUser3.token + + const loginResponseUser4 = await utils.getIdAndToken(appUrl, { + username: "user4", + password: TestData.Accounts["user4"]["password"], + }); + userIdUser4 = loginResponseUser4.userId; + accessTokenUser4 = loginResponseUser4.token; + + const loginResponseAdmin = await utils.getIdAndToken(appUrl, { + username: "admin", + password: TestData.Accounts["admin"]["password"], + }); + userIdAdmin = loginResponseAdmin.userId; + accessTokenAdmin = loginResponseAdmin.token; + + const loginResponseArchiveManager = await utils.getIdAndToken(appUrl, { + username: "archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }); + userIdArchiveManager = loginResponseArchiveManager.userId; + accessTokenArchiveManager = loginResponseArchiveManager.token; + }); + afterEach((done) => { sandbox.restore(); done(); diff --git a/test/Users.js b/test/Users.js index 12c8c9691..6a51db891 100644 --- a/test/Users.js +++ b/test/Users.js @@ -38,19 +38,13 @@ describe("2350: Users: Login with functional accounts", () => { }); describe("2360: Users settings", () => { - beforeEach((done) => { - utils.getIdAndToken( - appUrl, - { - username: "user1", - password: TestData.Accounts["user1"]["password"], - }, - (idVal, tokenVal) => { - accessTokenUser1 = tokenVal; - userIdUser1 = idVal; - done(); - }, - ); + beforeEach(async() => { + const loginResponseUser1 = await utils.getIdAndToken(appUrl, { + username: "user1", + password: TestData.Accounts["user1"]["password"], + }); + userIdUser1 = loginResponseUser1.userId; + accessTokenUser1 = loginResponseUser1.token; }); it("0010: Update users settings with valid value should sucess ", async () => { From 1c428ae47424c2c5777f864508afdb372032bc1e Mon Sep 17 00:00:00 2001 From: ingvord Date: Tue, 30 Jul 2024 20:56:08 +0200 Subject: [PATCH 109/258] Add test for filters and conditions in user settings --- src/users/dto/update-user-settings.dto.ts | 10 ++++++ .../create-user-settings.interceptor.ts | 3 ++ src/users/schemas/user-settings.schema.ts | 36 ++++++++----------- test/Users.js | 4 ++- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index 9c6741b9e..5aac97f77 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -1,4 +1,8 @@ import { ApiProperty, PartialType } from "@nestjs/swagger"; +import { + FilterConfig, + ScientificCondition, +} from "../schemas/user-settings.schema"; export class UpdateUserSettingsDto { @ApiProperty() @@ -9,6 +13,12 @@ export class UpdateUserSettingsDto { @ApiProperty({ type: Number, required: false, default: 25 }) readonly jobCount?: number; + + @ApiProperty() + readonly filters: FilterConfig[]; + + @ApiProperty() + readonly conditions: ScientificCondition[]; } export class PartialUpdateUserSettingsDto extends PartialType( diff --git a/src/users/interceptors/create-user-settings.interceptor.ts b/src/users/interceptors/create-user-settings.interceptor.ts index d059602db..2ecb7bbc0 100644 --- a/src/users/interceptors/create-user-settings.interceptor.ts +++ b/src/users/interceptors/create-user-settings.interceptor.ts @@ -8,6 +8,7 @@ import { import { Observable, tap } from "rxjs"; import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; import { UsersService } from "../users.service"; +import { kDefaultFilters } from "../schemas/user-settings.schema"; @Injectable() export class CreateUserSettingsInterceptor implements NestInterceptor { @@ -34,6 +35,8 @@ export class CreateUserSettingsInterceptor implements NestInterceptor { const createUserSettingsDto: CreateUserSettingsDto = { userId, columns: [], + filters: kDefaultFilters, + conditions: [], }; return this.usersService.createUserSettings( userId, diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index c93c473d0..fc56df5af 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -30,6 +30,18 @@ export interface ScientificCondition { operator: string; } +export const kDefaultFilters: FilterConfig[] = [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, +]; + @Schema({ collection: "UserSetting", toJSON: { @@ -71,32 +83,12 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, - ], + default: kDefaultFilters, description: "Array of filters the user has set", }) @Prop({ type: [{ type: Object }], - default: [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, - ], + default: kDefaultFilters, }) filters: FilterConfig[]; diff --git a/test/Users.js b/test/Users.js index 12c8c9691..72147ba09 100644 --- a/test/Users.js +++ b/test/Users.js @@ -53,7 +53,7 @@ describe("2360: Users settings", () => { ); }); - it("0010: Update users settings with valid value should sucess ", async () => { + it("0010: Update users settings with valid value should success ", async () => { return request(appUrl) .put(`/api/v3/Users/${userIdUser1}/settings`) .set("Accept", "application/json") @@ -64,6 +64,8 @@ describe("2360: Users settings", () => { res.body.should.have.property("userId", userIdUser1); res.body.should.have.property("datasetCount"); res.body.should.have.property("jobCount"); + res.body.should.have.property("filters"); + res.body.should.have.property("conditions"); }); }); }); From b107c708aee02a712fed960fde447e67c02aceb1 Mon Sep 17 00:00:00 2001 From: ingvord Date: Tue, 30 Jul 2024 22:17:40 +0200 Subject: [PATCH 110/258] Add tests --- src/users/users.controller.spec.ts | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 1b22d0350..6bedb6203 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -3,17 +3,43 @@ import { AuthService } from "src/auth/auth.service"; import { CaslModule } from "src/casl/casl.module"; import { UsersController } from "./users.controller"; import { UsersService } from "./users.service"; +import { UpdateUserSettingsDto } from "./dto/update-user-settings.dto"; class UsersServiceMock { findByIdUserIdentity(id: string) { return { id }; } + + async findByIdUserSettings(userId: string) { + return mockUserSettings; + } + + async findOneAndUpdateUserSettings( + userId: string, + updateUserSettingsDto: UpdateUserSettingsDto, + ) { + return { ...updateUserSettingsDto, _id: userId }; + } } +const mockUserSettings = { + _id: "user1", + userId: "user1", + columns: [], + datasetCount: 25, + jobCount: 25, + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + ], + conditions: [{ field: "status", value: "active", operator: "equals" }], +}; + class AuthServiceMock {} describe("UsersController", () => { let controller: UsersController; + let usersService: UsersService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -26,9 +52,58 @@ describe("UsersController", () => { }).compile(); controller = module.get(UsersController); + usersService = module.get(UsersService); + + // bypass authorization + jest + .spyOn(controller as UsersController, "checkUserAuthorization") + .mockImplementation(() => Promise.resolve()); }); it("should be defined", () => { expect(controller).toBeDefined(); }); + + it("should return user settings with filters and conditions", async () => { + jest + .spyOn(usersService, "findByIdUserSettings") + .mockResolvedValue(mockUserSettings); + + const userId = "user1"; + const result = await controller.getSettings( + { user: { _id: userId } }, + userId, + ); + + expect(result).toEqual(mockUserSettings); + expect(result.filters).toBeDefined(); + expect(result.filters.length).toBeGreaterThan(0); + expect(result.conditions).toBeDefined(); + expect(result.conditions.length).toBeGreaterThan(0); + }); + + it("should update user settings with filters and conditions", async () => { + const updatedSettings = { + ...mockUserSettings, + filters: [{ type: "PidFilterContainsComponent", visible: false }], + conditions: [{ field: "status", value: "inactive", operator: "equals" }], + }; + + jest + .spyOn(usersService, "findOneAndUpdateUserSettings") + .mockResolvedValue(updatedSettings); + + const userId = "user-id"; + const result = await controller.updateSettings( + { user: { _id: userId } }, + userId, + updatedSettings, + ); + + expect(result).toEqual(updatedSettings); + expect(result.filters).toBeDefined(); + expect(result.filters.length).toBe(1); + expect(result.conditions).toBeDefined(); + expect(result.conditions.length).toBe(1); + }); }); From 364f9ebc8b3c5173d550dd58ab4a7bd3fba5cd34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:44:13 +0000 Subject: [PATCH 111/258] build(deps-dev): bump @types/node from 20.14.11 to 22.0.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.11 to 22.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 926aa47fd..db4aec7de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "@types/lodash": "^4.14.180", "@types/luxon": "^3.1.0", "@types/mocha": "^10.0.0", - "@types/node": "^20.1.0", + "@types/node": "^22.0.0", "@types/node-fetch": "^2.6.2", "@types/nodemailer": "^6.4.4", "@types/passport-jwt": "^4.0.0", @@ -3001,11 +3001,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz", + "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.11.1" } }, "node_modules/@types/node-fetch": { @@ -13583,9 +13583,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==" }, "node_modules/universalify": { "version": "2.0.0", diff --git a/package.json b/package.json index 62021d8b6..f81c13691 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "@types/lodash": "^4.14.180", "@types/luxon": "^3.1.0", "@types/mocha": "^10.0.0", - "@types/node": "^20.1.0", + "@types/node": "^22.0.0", "@types/node-fetch": "^2.6.2", "@types/nodemailer": "^6.4.4", "@types/passport-jwt": "^4.0.0", From a294b62bc8b3bd045511a645e5dfcb37a264cdb3 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Wynen Date: Wed, 31 Jul 2024 14:16:44 +0200 Subject: [PATCH 112/258] Add a security policy (#864) * Add a security policy * Fix link * Update SECURITY.md * Update SECURITY.md --------- Co-authored-by: Jay --- SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..f7bb2b150 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +Only the latest version is supported. + +## Reporting a Vulnerability + +If you believe you have found a security vulnerability in SciCat, please +- ✅ report it to us by creating a [security advisory](https://github.com/SciCatProject/scicat-backend-next/security/advisories/new). +- ❌ do not report security vulnerabilities through public GitHub issues, discussions, or pull requests, etc. + +Please include as much information as you can to help us better understand and resolve the issue. +We work on fixing the issues [privately](https://docs.github.com/en/code-security/security-advisories/working-with-repository-security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-repository-security-vulnerability). + +## Disclosure + +We use GitHub [security advisories](https://github.com/SciCatProject/scicat-backend-next/security/advisories) to disclose fixed vulnerabilities. From 52be015e9229c387708af662d438c8792bbfe0ab Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 31 Jul 2024 14:32:27 +0200 Subject: [PATCH 113/258] ci: add GitHub Action to enforce PR title format --- .github/pr-title-checker-config.json | 15 +++++++++++++ ...endabot.yaml => auto-merge-dependabot.yml} | 0 .../{build-release.yaml => build-release.yml} | 0 .github/workflows/pr-title-checker.yml | 22 +++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 .github/pr-title-checker-config.json rename .github/workflows/{auto-merge-dependabot.yaml => auto-merge-dependabot.yml} (100%) rename .github/workflows/{build-release.yaml => build-release.yml} (100%) create mode 100644 .github/workflows/pr-title-checker.yml diff --git a/.github/pr-title-checker-config.json b/.github/pr-title-checker-config.json new file mode 100644 index 000000000..893159467 --- /dev/null +++ b/.github/pr-title-checker-config.json @@ -0,0 +1,15 @@ +{ + "LABEL": { + "name": "" + }, + "CHECKS": { + "NOTE": "You can test the regex here: https://regex101.com/r/nDeps5/1", + "regexp": "(^(?build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|BREAKING CHANGE)(?\\([\\w\\s*-]+\\))?(?!?): (?([a-z]).+[^.|\\s])$)", + "regexpFlags": "gm" + }, + "MESSAGES": { + "success": "All OK", + "failure": "PR title not following the semantic-release guidelines. Please check https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines for more information.", + "notice": "" + } +} diff --git a/.github/workflows/auto-merge-dependabot.yaml b/.github/workflows/auto-merge-dependabot.yml similarity index 100% rename from .github/workflows/auto-merge-dependabot.yaml rename to .github/workflows/auto-merge-dependabot.yml diff --git a/.github/workflows/build-release.yaml b/.github/workflows/build-release.yml similarity index 100% rename from .github/workflows/build-release.yaml rename to .github/workflows/build-release.yml diff --git a/.github/workflows/pr-title-checker.yml b/.github/workflows/pr-title-checker.yml new file mode 100644 index 000000000..07be7fd15 --- /dev/null +++ b/.github/workflows/pr-title-checker.yml @@ -0,0 +1,22 @@ +name: PR Title Checker + +on: + pull_request: + branches: + - master + types: + - opened + - edited + - synchronize + - labeled + - unlabeled + +jobs: + check-pr-title: + runs-on: ubuntu-latest + steps: + - uses: thehanimo/pr-title-checker@v1.4.1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + pass_on_octokit_error: false + configuration_path: .github/pr-title-checker-config.json #(optional. defaults to .github/pr-title-checker-config.json) From 4d7dcf2c11dc8911124d2d0c33a0e24e42e75182 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 1 Aug 2024 11:03:26 +0200 Subject: [PATCH 114/258] added pull request guidelines for PR titles in README --- README.md | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9b9df853b..e31f0812a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,44 @@ If you're planning to contribute to this project by adding new functionality, we Thank you for your interest in contributing to our project! +## Pull Request Guidelines + +When creating a pull request (PR) for this repository, it's important to follow the guidelines for PR titles and PR template to ensure consistency and clarity. Proper PR titles help maintain a clear and understandable project history and facilitate better release notes. + +### PR Title Format + +All PR titles must adhere to the conventional commits format. This format helps in automating the release process and generating changelogs. The format is as follows: + +``` +(): +``` + +type: The type of change being made. It must be one of the following: + +- `feat:` A new feature +- `fix:` A bug fix +- `ci:` Continuous integration-related changes. +- `docs:` Documentation only changes +- `style:` Changes that do not affect the meaning of the code (white -space, formatting, missing semi -colons, etc) +- `refactor:` A code change that neither fixes a bug nor adds a feature +- `revert`: Reverts a previous commit. +- `perf:` A code change that improves performance +- `test:` Adding missing or correcting existing tests +- `chore:` Changes to the build process or auxiliary tools and libraries such as documentation generation +- `build:` Changes that affect the build system or external dependencies. +- `BREAKING CHANGE:` A change that introduces a breaking API change. + +scope: An `optional` description of the section of the codebase affected by the changes (e.g., api, ui, docs). This is enclosed in parentheses. + +description: A brief summary of the changes made. + +### Examples + +- feat(api): add new endpoint for data retrieval +- fix(ui): correct button alignment on mobile devices +- docs: update contributing guidelines +- BREAKING CHANGE: refactor authentication middleware to use new library + ## Get started 1. `git clone https://github.com/SciCatProject/scicat-backend-next.git` @@ -246,16 +284,7 @@ The image below shows visualized workflow. The release log is automatically populated with all commit messages since the last tag, providing a detailed changelog for the release. By default semantic-release uses [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). -In order to generate detailed changelog for the release, the following type for the `commit message`/`PR title` should be used: - -- feat: message - A new feature -- fix: message - A bug fix -- docs: message - Documentation only changes -- style: message - Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) -- refactor: message - A code change that neither fixes a bug nor adds a feature -- perf: message - A code change that improves performance -- test: message - Adding missing or correcting existing tests -- chore: message - Changes to the build process or auxiliary tools and libraries such as documentation generation +In order to generate detailed changelog for the release, please follow the pull request guidelines for PR titles. ## License From c353df4cfdf286f85a7b155fa388da9509e0533f Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 1 Aug 2024 13:02:21 +0200 Subject: [PATCH 115/258] add docs for pr and release guide --- README.md | 68 ------------------- .../contributing/pr-guidelines.md | 37 ++++++++++ docs/developer-guide/release-guidelines.md | 27 ++++++++ 3 files changed, 64 insertions(+), 68 deletions(-) create mode 100644 docs/developer-guide/contributing/pr-guidelines.md create mode 100644 docs/developer-guide/release-guidelines.md diff --git a/README.md b/README.md index e31f0812a..50e87e5d3 100644 --- a/README.md +++ b/README.md @@ -32,44 +32,6 @@ If you're planning to contribute to this project by adding new functionality, we Thank you for your interest in contributing to our project! -## Pull Request Guidelines - -When creating a pull request (PR) for this repository, it's important to follow the guidelines for PR titles and PR template to ensure consistency and clarity. Proper PR titles help maintain a clear and understandable project history and facilitate better release notes. - -### PR Title Format - -All PR titles must adhere to the conventional commits format. This format helps in automating the release process and generating changelogs. The format is as follows: - -``` -(): -``` - -type: The type of change being made. It must be one of the following: - -- `feat:` A new feature -- `fix:` A bug fix -- `ci:` Continuous integration-related changes. -- `docs:` Documentation only changes -- `style:` Changes that do not affect the meaning of the code (white -space, formatting, missing semi -colons, etc) -- `refactor:` A code change that neither fixes a bug nor adds a feature -- `revert`: Reverts a previous commit. -- `perf:` A code change that improves performance -- `test:` Adding missing or correcting existing tests -- `chore:` Changes to the build process or auxiliary tools and libraries such as documentation generation -- `build:` Changes that affect the build system or external dependencies. -- `BREAKING CHANGE:` A change that introduces a breaking API change. - -scope: An `optional` description of the section of the codebase affected by the changes (e.g., api, ui, docs). This is enclosed in parentheses. - -description: A brief summary of the changes made. - -### Examples - -- feat(api): add new endpoint for data retrieval -- fix(ui): correct button alignment on mobile devices -- docs: update contributing guidelines -- BREAKING CHANGE: refactor authentication middleware to use new library - ## Get started 1. `git clone https://github.com/SciCatProject/scicat-backend-next.git` @@ -256,36 +218,6 @@ Following are the post that I found useful working on the migration: - https://docs.nestjs.com/openapi/types-and-parameters - https://docs.nestjs.com/openapi/decorators -## New Release Version Bump Workflow - -### Workflow Overview - -Scicat Backend controls new releases with the `GitHub-tag-and-release` GitHub Action. This workflow is triggered by push events to the release branch. It automates the version bumping and release processes based on semantic commit messages. Full documentation of the action package can be found on [github-tag-action](https://github.com/marketplace/actions/github-tag) - -The image below shows visualized workflow. -![image](https://github.com/SciCatProject/scicat-backend-next/assets/78078898/0f3c5386-4a16-4ed1-a2ee-d71ef6f34e99) - -### Workflow Trigger Condition - -> [!Caution] -> Any push to the `release` branch initiates the workflow. - -### Versioning and Release Strategy - -**Semantic Versioning:** - -- The version is automatically bumped according to the semantic PR titles, using the [semantic-release](https://github.com/semantic-release/semantic-release) conventions: - - - `fix:` prefixed titles generate a patch release. - - `feat:` prefixed titles generate a minor release. - - `BREAKING CHANGE:` in the commit message triggers a major release. - -**Auto-generated Release Notes:** - -The release log is automatically populated with all commit messages since the last tag, providing a detailed changelog for the release. By default semantic-release uses [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). - -In order to generate detailed changelog for the release, please follow the pull request guidelines for PR titles. - ## License This project is licensed under the GPL License - see the [LICENSE](LICENSE) file for details diff --git a/docs/developer-guide/contributing/pr-guidelines.md b/docs/developer-guide/contributing/pr-guidelines.md new file mode 100644 index 000000000..c91f31e8d --- /dev/null +++ b/docs/developer-guide/contributing/pr-guidelines.md @@ -0,0 +1,37 @@ +# Pull Request Guidelines + +When creating a pull request (PR) for this repository, it's important to follow the guidelines for PR titles and PR template to ensure consistency and clarity. Proper PR titles help maintain a clear and understandable project history and facilitate better release notes. + +## PR Title Format + +All PR titles must adhere to the conventional commits format. This format helps in automating the release process and generating changelogs. The format is as follows: + +``` +(): +``` + +type: The type of change being made. It must be one of the following: + +- `feat:` A new feature +- `fix:` A bug fix +- `ci:` Continuous integration-related changes. +- `docs:` Documentation only changes +- `style:` Changes that do not affect the meaning of the code (white -space, formatting, missing semi -colons, etc) +- `refactor:` A code change that neither fixes a bug nor adds a feature +- `revert`: Reverts a previous commit. +- `perf:` A code change that improves performance +- `test:` Adding missing or correcting existing tests +- `chore:` Changes to the build process or auxiliary tools and libraries such as documentation generation +- `build:` Changes that affect the build system or external dependencies. +- `BREAKING CHANGE:` A change that introduces a breaking API change. + +scope: An `optional` description of the section of the codebase affected by the changes (e.g., api, ui, docs). This is enclosed in parentheses. + +description: A brief summary of the changes made. + +## Examples + +- feat(api): add new endpoint for data retrieval +- fix(ui): correct button alignment on mobile devices +- docs: update contributing guidelines +- BREAKING CHANGE: refactor authentication middleware to use new library diff --git a/docs/developer-guide/release-guidelines.md b/docs/developer-guide/release-guidelines.md new file mode 100644 index 000000000..fb07eaee0 --- /dev/null +++ b/docs/developer-guide/release-guidelines.md @@ -0,0 +1,27 @@ +# New Release Version Bump Workflow + +## Workflow Overview + +Scicat Backend controls new releases with the `GitHub-tag-and-release` GitHub Action. This workflow is triggered by push events to the release branch. It automates the version bumping and release processes based on semantic commit messages. Full documentation of the action package can be found on [github-tag-action](https://github.com/marketplace/actions/github-tag) + +The image below shows visualized workflow. +![image](https://github.com/SciCatProject/scicat-backend-next/assets/78078898/0f3c5386-4a16-4ed1-a2ee-d71ef6f34e99) + +## Workflow Trigger Condition + +> [!Caution] +> Any push to the `release` branch initiates the workflow. + +## Versioning and Release Strategy + +**Semantic Versioning:** + +- The version is automatically bumped according to the semantic PR titles, using the [semantic-release](https://github.com/semantic-release/semantic-release) conventions: + + - `fix:` prefixed titles generate a patch release. + - `feat:` prefixed titles generate a minor release. + - `BREAKING CHANGE:` in the commit message triggers a major release. + +**Auto-generated Release Notes:** + +The release log is automatically populated with all commit messages since the last tag, providing a detailed changelog for the release. By default semantic-release uses [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines). From 0a0c792737683067434c433e101372caf490bc4e Mon Sep 17 00:00:00 2001 From: ingvord Date: Thu, 1 Aug 2024 18:19:57 +0200 Subject: [PATCH 116/258] Fix #1347 --- src/users/dto/create-user-settings.dto.ts | 2 ++ src/users/dto/update-user-settings.dto.ts | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/users/dto/create-user-settings.dto.ts b/src/users/dto/create-user-settings.dto.ts index 923d616bf..63095f1c2 100644 --- a/src/users/dto/create-user-settings.dto.ts +++ b/src/users/dto/create-user-settings.dto.ts @@ -1,7 +1,9 @@ import { ApiProperty } from "@nestjs/swagger"; import { UpdateUserSettingsDto } from "./update-user-settings.dto"; +import { IsString } from "class-validator"; export class CreateUserSettingsDto extends UpdateUserSettingsDto { @ApiProperty({ type: String, required: true }) + @IsString() readonly userId: string; } diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index 5aac97f77..8458e4e84 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -3,21 +3,27 @@ import { FilterConfig, ScientificCondition, } from "../schemas/user-settings.schema"; +import { IsArray, IsNumber } from "class-validator"; export class UpdateUserSettingsDto { @ApiProperty() + @IsArray() readonly columns: Record[]; @ApiProperty({ type: Number, required: false, default: 25 }) + @IsNumber() readonly datasetCount?: number; @ApiProperty({ type: Number, required: false, default: 25 }) + @IsNumber() readonly jobCount?: number; @ApiProperty() + @IsArray() readonly filters: FilterConfig[]; @ApiProperty() + @IsArray() readonly conditions: ScientificCondition[]; } From 7bf41f1ed3b9285cbf99a06b7434a2f648b2981a Mon Sep 17 00:00:00 2001 From: ingvord Date: Thu, 1 Aug 2024 19:24:37 +0200 Subject: [PATCH 117/258] Add default endpoints --- .../default-user-settings.interceptor.ts | 34 ++++++++++++++ src/users/users.controller.ts | 44 ++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/users/interceptors/default-user-settings.interceptor.ts diff --git a/src/users/interceptors/default-user-settings.interceptor.ts b/src/users/interceptors/default-user-settings.interceptor.ts new file mode 100644 index 000000000..f9eb647f1 --- /dev/null +++ b/src/users/interceptors/default-user-settings.interceptor.ts @@ -0,0 +1,34 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + Logger, + NestInterceptor, +} from "@nestjs/common"; +import { map, Observable, tap } from "rxjs"; +import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; +import { UsersService } from "../users.service"; +import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; + +@Injectable() +export class DefaultUserSettingsInterceptor implements NestInterceptor { + constructor(private usersService: UsersService) {} + async intercept( + context: ExecutionContext, + next: CallHandler, + ): Promise> { + return next.handle().pipe( + map(async () => { + Logger.log("DefaultUserSettingsInterceptor"); + const defaultUserSettings: UpdateUserSettingsDto = { + columns: [], + filters: kDefaultFilters, + conditions: [], + }; + console.log(defaultUserSettings); + return defaultUserSettings; + }), + ); + } +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index f5438de8b..b797ea2b4 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -12,6 +12,7 @@ import { Body, ForbiddenException, HttpCode, + CanActivate, } from "@nestjs/common"; import { ApiBearerAuth, @@ -31,7 +32,10 @@ import { Request } from "express"; import { JWTUser } from "../auth/interfaces/jwt-user.interface"; import { UserSettings } from "./schemas/user-settings.schema"; import { CreateUserSettingsDto } from "./dto/create-user-settings.dto"; -import { PartialUpdateUserSettingsDto } from "./dto/update-user-settings.dto"; +import { + PartialUpdateUserSettingsDto, + UpdateUserSettingsDto, +} from "./dto/update-user-settings.dto"; import { User } from "./schemas/user.schema"; import { CreateUserSettingsInterceptor } from "./interceptors/create-user-settings.interceptor"; import { AuthService } from "src/auth/auth.service"; @@ -44,6 +48,8 @@ import { CreateCustomJwt } from "./dto/create-custom-jwt.dto"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; +import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { DefaultUserSettingsInterceptor } from "./interceptors/default-user-settings.interceptor"; @ApiBearerAuth() @ApiTags("users") @@ -307,6 +313,42 @@ export class UsersController { return this.usersService.findOneAndDeleteUserSettings(id); } + @UseInterceptors(DefaultUserSettingsInterceptor) + @UseGuards( + class ByPassAuthenticatedPoliciesGuard + extends PoliciesGuard + implements CanActivate + { + async canActivate(): Promise { + return Promise.resolve(true); + } + }, + ) + @Get("/settings/default") + async getDefaultSettings(): Promise { + return Promise.resolve(new UserSettings()); + } + + @UseGuards(AuthenticatedPoliciesGuard) + @CheckPolicies((ability: AppAbility) => + ability.can(Action.UserCreateAny, User), + ) + @Post("/settings/default") + async postDefaultSettings( + @Req() request: Request, + @Body() createUserSettingsDto: CreateUserSettingsDto, + ): Promise { + await this.checkUserAuthorization( + request, + [Action.UserCreateAny], + createUserSettingsDto.userId, + ); + return this.usersService.createUserSettings( + "default", + createUserSettingsDto, + ); + } + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => { return ( From fb8a2d3b3f273a949576f892042bed49a294257a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:06:59 +0000 Subject: [PATCH 118/258] build(deps-dev): bump @types/chai from 4.3.16 to 4.3.17 Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.3.16 to 4.3.17. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai) --- updated-dependencies: - dependency-name: "@types/chai" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index db4aec7de..f2c6570b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2799,9 +2799,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "version": "4.3.17", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz", + "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", "dev": true }, "node_modules/@types/connect": { From 31d224a1d5a9ee2b9be90e63b45fd73d6c0b0654 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 6 Aug 2024 14:21:56 +0200 Subject: [PATCH 119/258] fix: replace docker-compose with docker compose on github workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 93512ad10..ba6213ed2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -173,5 +173,5 @@ jobs: run: | cp CI/ESS/docker-compose.api.yaml docker-compose.yaml cp functionalAccounts.json.test functionalAccounts.json - docker-compose up --build -d + docker compose up --build -d npm run test:api From f308a8786c2508738819c97f316aeb5f460b493c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:30:08 +0000 Subject: [PATCH 120/258] build(deps-dev): bump @types/node from 22.0.0 to 22.1.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.0.0 to 22.1.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2c6570b4..8f6ec72d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3001,11 +3001,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz", - "integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "dependencies": { - "undici-types": "~6.11.1" + "undici-types": "~6.13.0" } }, "node_modules/@types/node-fetch": { @@ -13583,9 +13583,9 @@ } }, "node_modules/undici-types": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", - "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" }, "node_modules/universalify": { "version": "2.0.0", From 82b06538270db06fdcdcd65007e2d7b29b1a648e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:40:59 +0000 Subject: [PATCH 121/258] build(deps): bump mongoose from 8.5.1 to 8.5.2 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.1 to 8.5.2. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.5.1...8.5.2) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f6ec72d5..928258f32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10492,9 +10492,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", - "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.2.tgz", + "integrity": "sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From 92fa4828c1abedabb5e646d09602ea7c83cca4fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:51:35 +0000 Subject: [PATCH 122/258] build(deps): bump luxon from 3.4.4 to 3.5.0 Bumps [luxon](https://github.com/moment/luxon) from 3.4.4 to 3.5.0. - [Changelog](https://github.com/moment/luxon/blob/master/CHANGELOG.md) - [Commits](https://github.com/moment/luxon/compare/3.4.4...3.5.0) --- updated-dependencies: - dependency-name: luxon dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 928258f32..f2ef7b7bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9447,9 +9447,9 @@ } }, "node_modules/luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", "engines": { "node": ">=12" } From 0fcf73fb34bc37ae2a11c8a2ddbc0efcda513887 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:02:22 +0000 Subject: [PATCH 123/258] build(deps-dev): bump @typescript-eslint/parser from 7.17.0 to 7.18.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.17.0 to 7.18.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.18.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 113 +++------------------------------------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2ef7b7bd..e71b8062e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3226,15 +3226,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -3253,105 +3253,6 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.18.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", From 72c557298fd91537e41a7401405805291da9ea43 Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Wed, 7 Aug 2024 14:28:43 +0200 Subject: [PATCH 124/258] wip: split casl into functions --- src/casl/casl-ability.factory.ts | 631 ++++++++++-------- src/datasets/datasets.controller.ts | 20 +- .../origdatablocks.controller.ts | 12 +- test/DatasetAuthorization.js | 2 +- test/config/jobconfig.json | 0 5 files changed, 357 insertions(+), 308 deletions(-) create mode 100755 test/config/jobconfig.json diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 14e558e05..0a410d24a 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -54,33 +54,91 @@ export type AppAbility = MongoAbility; @Injectable() export class CaslAbilityFactory { - createForUser(user: JWTUser) { + + createForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + /** + /* unauthenticated users + **/ + + cannot(Action.UserReadOwn, User); + cannot(Action.UserCreateOwn, User); + cannot(Action.UserUpdateOwn, User); + cannot(Action.UserDeleteOwn, User); + cannot(Action.UserReadAny, User); + cannot(Action.UserCreateAny, User); + cannot(Action.UserUpdateAny, User); + cannot(Action.UserDeleteAny, User); + } else { + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.Delete, PublishedData); + can(Action.Delete, Policy); + } + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.ReadAll, UserIdentity); + + // ------------------------------------- + // elasticsearch + // ------------------------------------- + // endpoint authorization + can(Action.Manage, ElasticSearchActions); + + // ------------------------------------- + // user endpoint, including useridentity + can(Action.UserReadAny, User); + can(Action.UserReadOwn, User); + can(Action.UserCreateAny, User); + can(Action.UserUpdateAny, User); + can(Action.UserDeleteAny, User); + can(Action.UserCreateJwt, User); + + // ------------------------------------- + // policies + can(Action.Update, Policy); + can(Action.Read, Policy); + can(Action.Create, Policy); + } else { + /** + /* authenticated users + **/ + cannot(Action.UserReadAny, User); + cannot(Action.UserCreateAny, User); + cannot(Action.UserUpdateAny, User); + cannot(Action.UserDeleteAny, User); + cannot(Action.UserCreateJwt, User); + } + can(Action.UserReadOwn, User, { _id: user._id }); + can(Action.UserCreateOwn, User, { _id: user._id }); + can(Action.UserUpdateOwn, User, { _id: user._id }); + can(Action.UserDeleteOwn, User, { _id: user._id }); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + createDatasetForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); - // // admin groups - // const stringAdminGroups = process.env.ADMIN_GROUPS || ""; - // const adminGroups: string[] = stringAdminGroups - // ? stringAdminGroups.split(",").map((v) => v.trim()) - // : []; - // // delete groups - // const stringDeleteGroups = process.env.DELETE_GROUPS || ""; - // const deleteGroups: string[] = stringDeleteGroups - // ? stringDeleteGroups.split(",").map((v) => v.trim()) - // : []; - // // create dataset groups - // const stringCreateDatasetGroups = - // process.env.CREATE_DATASET_GROUPS || "all"; - // const createDatasetGroups: string[] = stringCreateDatasetGroups - // .split(",") - // .map((v) => v.trim()); - - /* - / Set permissions for different type of users for the following subsystems: - / - Datasets (https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization/authorization_datasets.html) - / - OrigDatablocks (https://scicatproject.github.io/documentation/Development/v4.x/backend/authorization/authorization_origdatablocks.html) - */ if (!user) { /** /* unauthenticated users @@ -125,28 +183,14 @@ export class CaslAbilityFactory { isPublished: true, }); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - cannot(Action.OrigdatablockCreate, OrigDatablock); - cannot(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - isPublished: true, - }); - - cannot(Action.UserReadOwn, User); - cannot(Action.UserCreateOwn, User); - cannot(Action.UserUpdateOwn, User); - cannot(Action.UserDeleteOwn, User); - cannot(Action.UserReadAny, User); - cannot(Action.UserCreateAny, User); - cannot(Action.UserUpdateAny, User); - cannot(Action.UserDeleteAny, User); + // cannot(Action.UserReadOwn, User); + // cannot(Action.UserCreateOwn, User); + // cannot(Action.UserUpdateOwn, User); + // cannot(Action.UserDeleteOwn, User); + // cannot(Action.UserReadAny, User); + // cannot(Action.UserCreateAny, User); + // cannot(Action.UserUpdateAny, User); + // cannot(Action.UserDeleteAny, User); } else { if ( user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) @@ -172,17 +216,8 @@ export class CaslAbilityFactory { // - can(Action.DatasetDatablockDeleteAny, DatasetClass); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockDelete, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockDeleteAny, OrigDatablock); - - can(Action.Delete, PublishedData); - can(Action.Delete, Policy); + // can(Action.Delete, PublishedData); + // can(Action.Delete, Policy); } else { /* / user that does not belong to any of the group listed in DELETE_GROUPS @@ -197,12 +232,6 @@ export class CaslAbilityFactory { cannot(Action.DatasetOrigdatablockDelete, DatasetClass); // - cannot(Action.DatasetDatablockDelete, DatasetClass); - - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - cannot(Action.OrigdatablockDelete, OrigDatablock); } if ( @@ -212,16 +241,16 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in ADMIN_GROUPS */ - // this tests should be all removed, once we are done with authorization review - //can(Action.ListAll, DatasetClass); - // can(Action.ListAll, ProposalClass); - can(Action.ReadAll, UserIdentity); + // // this tests should be all removed, once we are done with authorization review + // //can(Action.ListAll, DatasetClass); + // // can(Action.ListAll, ProposalClass); + // can(Action.ReadAll, UserIdentity); - // ------------------------------------- - // elasticsearch - // ------------------------------------- - // endpoint authorization - can(Action.Manage, ElasticSearchActions); + // // ------------------------------------- + // // elasticsearch + // // ------------------------------------- + // // endpoint authorization + // can(Action.Manage, ElasticSearchActions); // ------------------------------------- // datasets @@ -266,33 +295,20 @@ export class CaslAbilityFactory { // ------------------------------------- can(Action.DatasetLogbookReadAny, DatasetClass); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockReadAny, OrigDatablock); - can(Action.OrigdatablockCreateAny, OrigDatablock); - can(Action.OrigdatablockUpdateAny, OrigDatablock); - - // ------------------------------------- - // user endpoint, including useridentity - can(Action.UserReadAny, User); - can(Action.UserReadOwn, User); - can(Action.UserCreateAny, User); - can(Action.UserUpdateAny, User); - can(Action.UserDeleteAny, User); - can(Action.UserCreateJwt, User); - - // ------------------------------------- - // policies - can(Action.Update, Policy); - can(Action.Read, Policy); - can(Action.Create, Policy); + // // ------------------------------------- + // // user endpoint, including useridentity + // can(Action.UserReadAny, User); + // can(Action.UserReadOwn, User); + // can(Action.UserCreateAny, User); + // can(Action.UserUpdateAny, User); + // can(Action.UserDeleteAny, User); + // can(Action.UserCreateJwt, User); + + // // ------------------------------------- + // // policies + // can(Action.Update, Policy); + // can(Action.Read, Policy); + // can(Action.Create, Policy); } else if ( user.currentGroups.some((g) => configuration().createDatasetPrivilegedGroups.includes(g), @@ -390,29 +406,6 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockCreateAny, OrigDatablock); - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - accessGroups: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockUpdateOwner, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); } else if ( user.currentGroups.some((g) => configuration().createDatasetWithPidGroups.includes(g), @@ -517,31 +510,6 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockCreateOwner, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - accessGroups: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - isPublished: true, - }); - can(Action.OrigdatablockUpdateOwner, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); } else if ( user.currentGroups.some((g) => configuration().createDatasetGroups.includes(g), @@ -648,31 +616,6 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockCreateOwner, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - accessGroups: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - isPublished: true, - }); - can(Action.OrigdatablockUpdateOwner, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); } else if (user) { /** /* authenticated users @@ -745,41 +688,193 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); - // ------------------------------------- - // origdatablock - // ------------------------------------- - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - cannot(Action.OrigdatablockCreate, OrigDatablock); - cannot(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - accessGroups: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - isPublished: true, - }); - cannot(Action.UserReadAny, User); - cannot(Action.UserCreateAny, User); - cannot(Action.UserUpdateAny, User); - cannot(Action.UserDeleteAny, User); - cannot(Action.UserCreateJwt, User); + // cannot(Action.UserReadAny, User); + // cannot(Action.UserCreateAny, User); + // cannot(Action.UserUpdateAny, User); + // cannot(Action.UserDeleteAny, User); + // cannot(Action.UserCreateJwt, User); } - can(Action.UserReadOwn, User, { _id: user._id }); - can(Action.UserCreateOwn, User, { _id: user._id }); - can(Action.UserUpdateOwn, User, { _id: user._id }); - can(Action.UserDeleteOwn, User, { _id: user._id }); + // can(Action.UserReadOwn, User, { _id: user._id }); + // can(Action.UserCreateOwn, User, { _id: user._id }); + // can(Action.UserUpdateOwn, User, { _id: user._id }); + // can(Action.UserDeleteOwn, User, { _id: user._id }); } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } - // ************************************ - // JOBS AUTHORIZATION - // ************************************ + createOrigDatablockForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + // endpoint authorization + can(Action.OrigdatablockDelete, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockDeleteAny, OrigDatablock); + } else { + /* + / user that does not belong to any of the group listed in DELETE_GROUPS + */ + + // endpoint authorization + cannot(Action.OrigdatablockDelete, OrigDatablock); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + // endpoint authorization + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockReadAny, OrigDatablock); + can(Action.OrigdatablockCreateAny, OrigDatablock); + can(Action.OrigdatablockUpdateAny, OrigDatablock); + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetPrivilegedGroups.includes(g), + ) + ) { + /** + /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + **/ + // endpoint authorization + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockCreateAny, OrigDatablock); + can(Action.OrigdatablockReadManyAccess, OrigDatablock); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + accessGroups: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockUpdateOwner, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetWithPidGroups.includes(g), + ) || + configuration().createDatasetWithPidGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_WITH_PID_GROUPS + **/ + + // endpoint authorization + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockCreateOwner, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadManyAccess, OrigDatablock); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + accessGroups: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + isPublished: true, + }); + can(Action.OrigdatablockUpdateOwner, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetGroups.includes(g), + ) || + configuration().createDatasetGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_GROUPS + **/ + + // endpoint authorization + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockCreateOwner, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadManyAccess, OrigDatablock); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + accessGroups: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + isPublished: true, + }); + can(Action.OrigdatablockUpdateOwner, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + } else if (user) { + /** + /* authenticated users + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + cannot(Action.OrigdatablockCreate, OrigDatablock); + cannot(Action.OrigdatablockUpdate, OrigDatablock); + // ------------------------------------- + // data instance authorization + can(Action.OrigdatablockReadManyAccess, OrigDatablock); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + accessGroups: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + isPublished: true, + }); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + + } + + createJobsForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + // ************************************ + // JOBS AUTHORIZATION + // ************************************ if (!user) { /** * unauthenticated users @@ -878,18 +973,25 @@ export class CaslAbilityFactory { }); } - // ************************************ - // PROPOSALS AUTHORIZATION - // ************************************ + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + createProposalsForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + // ************************************ + // PROPOSALS AUTHORIZATION + // ************************************ if (!user) { /** * unauthenticated users */ - // ------------------------------------- - // proposals - // ------------------------------------- // endpoint authorization can(Action.ProposalsRead, ProposalClass); cannot(Action.ProposalsCreate, ProposalClass); @@ -916,9 +1018,6 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in DELETE_GROUPS */ - // ------------------------------------- - // proposals - // ------------------------------------- // endpoint authorization can(Action.ProposalsDelete, ProposalClass); @@ -933,9 +1032,6 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in ADMIN_GROUPS */ - // ------------------------------------- - // proposals - // ------------------------------------- // endpoint authorization can(Action.ProposalsRead, ProposalClass); can(Action.ProposalsCreate, ProposalClass); @@ -964,9 +1060,6 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in PROPOSAL_GROUPS */ - // ------------------------------------- - // proposals - // ------------------------------------- // endpoint authorization can(Action.ProposalsRead, ProposalClass); @@ -1013,9 +1106,6 @@ export class CaslAbilityFactory { * authenticated users */ - // ------------------------------------- - // proposals - // ------------------------------------- // endpoint authorization can(Action.ProposalsRead, ProposalClass); cannot(Action.ProposalsCreate, ProposalClass); @@ -1049,10 +1139,23 @@ export class CaslAbilityFactory { isPublished: true, }); } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + + + createSamplesForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); // ************************************ // SAMPLES AUTHORIZATION // ************************************ + if (!user) { // ------------------------------------- // unauthenticated users @@ -1295,6 +1398,17 @@ export class CaslAbilityFactory { }); } } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + createInstrumentForUser(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); // ************************************ // INSTRUMENT AUTHORIZATION @@ -1339,77 +1453,12 @@ export class CaslAbilityFactory { } } - // Instrument permissions - //can(Action.Read, Instrument); - //if (user.currentGroups.some((g) => adminGroups.includes(g))) { - // can(Action.Manage, Instrument); - //} - - //can(Action.Manage, JobClass); - - can(Action.Read, Logbook); - - can(Action.Read, PublishedData); - can(Action.Update, PublishedData); - can(Action.Create, PublishedData); - - // can(Action.Manage, Attachment, { - // ownerGroup: { $in: user.currentGroups }, - // }); - // can(Action.Manage, Datablock, { - // ownerGroup: { $in: user.currentGroups }, - // }); - // can(Action.Manage, OrigDatablock, { - // ownerGroup: { $in: user.currentGroups }, - // }); - - // if (user.currentGroups.includes(Role.Admin)) { - // can(Action.Manage, "all"); - // } - // if (user.currentGroups.includes(Role.ArchiveManager)) { - // //cannot(Action.Create, DatasetClass); - // //cannot(Action.Update, DatasetClass); - // //can(Action.Delete, DatasetClass); - // cannot(Action.Manage, OrigDatablock); - // cannot(Action.Create, OrigDatablock); - // cannot(Action.Update, OrigDatablock); - // can(Action.Delete, OrigDatablock); - // cannot(Action.Manage, Datablock); - // cannot(Action.Create, Datablock); - // cannot(Action.Update, Datablock); - // can(Action.Delete, Datablock); - // can(Action.Delete, PublishedData); - // //-------------------------------- - // // instrument - // cannot(Action.InstrumentRead, Instrument); - // cannot(Action.InstrumentCreate, Instrument); - // cannot(Action.InstrumentUpdate, Instrument); - // can(Action.InstrumentDelete, Instrument); - // } - //if (user.currentGroups.includes(Role.GlobalAccess)) { - // can(Action.Read, "all"); - //} - // if (user.currentGroups.includes(Role.Ingestor)) { - // can(Action.Create, Attachment); - - // //cannot(Action.Delete, DatasetClass); - // //can(Action.Create, DatasetClass); - // //can(Action.Update, DatasetClass); - - // can(Action.Create, Instrument); - // can(Action.Update, Instrument); - // } - // if (user.currentGroups.includes(Role.ProposalIngestor)) { - // cannot(Action.Delete, ProposalClass); - // can(Action.Create, ProposalClass); - // can(Action.Update, ProposalClass); - // can(Action.Read, ProposalClass); - // can(Action.ListAll, ProposalClass); - // } - - //can(Action.Create, UserSettings, { userId: user._id }); - //can(Action.Read, UserSettings, { userId: user._id }); - //can(Action.Update, UserSettings, { userId: user._id }); + // can(Action.Read, Logbook); + + // can(Action.Read, PublishedData); + // can(Action.Update, PublishedData); + // can(Action.Create, PublishedData); + return build({ detectSubjectType: (item) => diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 6655d3b5f..c01b70ecc 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -160,7 +160,7 @@ export class DatasetsController { ): IFilters { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -205,7 +205,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); let canDoAction = false; @@ -290,7 +290,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -355,7 +355,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -691,7 +691,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -769,7 +769,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -850,7 +850,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1098,7 +1098,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1177,7 +1177,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1227,7 +1227,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createDatasetForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index ce68d9f22..12911cba7 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -90,7 +90,7 @@ export class OrigDatablocksController { // newDatasetClass.ownerGroup = dataset.ownerGroup; // if (user) { - // const ability = this.caslAbilityFactory.createForUser(user); + // const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); // const canUpdate = ability.can(Action.Update, newDatasetClass); // if (!canUpdate) { // throw new ForbiddenException("Unauthorized access"); @@ -128,7 +128,7 @@ export class OrigDatablocksController { const origDatablockInstance = await this.generateOrigDatablockInstanceInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); let canDoAction = false; @@ -363,7 +363,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { @@ -426,7 +426,7 @@ export class OrigDatablocksController { ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -467,7 +467,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -508,7 +508,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index ab707200d..1ae7d4a4b 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -41,7 +41,7 @@ const dataset3 = { accessGroups: ["group3"], }; -describe("0300: DatasetAuthorization: Test access to dataset", () => { +describe.only("0300: DatasetAuthorization: Test access to dataset", () => { before(() => { db.collection("Dataset").deleteMany({}); }); diff --git a/test/config/jobconfig.json b/test/config/jobconfig.json new file mode 100755 index 000000000..e69de29bb From 5367754347688cc72bade886167b8bc7324990c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:35:07 +0000 Subject: [PATCH 125/258] build(deps): bump @nestjs/core from 10.3.10 to 10.4.0 Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e71b8062e..44e7f2a09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,9 +2223,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.10.tgz", - "integrity": "sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.0.tgz", + "integrity": "sha512-vNVJ0H8n3FyIxrFibgV2tRbjKsVm90u//kinE0m7s6ygv+KhnGMrQvWGX0kk9wbsZwRMW5JMpnBWDUS4wu4yPg==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", From 279715027023e5e099a8731c4909c6d0d5037aea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:46:03 +0000 Subject: [PATCH 126/258] build(deps-dev): bump @nestjs/cli from 10.4.2 to 10.4.4 Bumps [@nestjs/cli](https://github.com/nestjs/nest-cli) from 10.4.2 to 10.4.4. - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/10.4.2...10.4.4) --- updated-dependencies: - dependency-name: "@nestjs/cli" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44e7f2a09..4c16d6a8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2099,9 +2099,9 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.2.tgz", - "integrity": "sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.4.tgz", + "integrity": "sha512-WKERbSZJGof0+9XeeMmWnb/9FpNxogcB5eTJTHjc9no0ymdTw3jTzT+KZL9iC/hGqBpuomDLaNFCYbAOt29nBw==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", @@ -2121,7 +2121,7 @@ "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.92.1", + "webpack": "5.93.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -13942,9 +13942,9 @@ } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", From 373ec6209de0a1dd76d4be71bc9ef66090e63afb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:56:40 +0000 Subject: [PATCH 127/258] build(deps-dev): bump @nestjs/testing from 10.3.10 to 10.4.0 Bumps [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c16d6a8f..141ccb8aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2476,9 +2476,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.10.tgz", - "integrity": "sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.0.tgz", + "integrity": "sha512-oAQe3Yb4/JlHtsBcKmueEvPZDoONp7LsNwGnMAeyhoBLuPBXDhZnNgMY2UtT4FfNmudBQBKR/vq/fOQRax/4Hg==", "dev": true, "dependencies": { "tslib": "2.6.3" From 86eaafdf05b72ec6af0a3ce20a40ebacfea6aed4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:07:17 +0000 Subject: [PATCH 128/258] build(deps): bump @nestjs/platform-express from 10.3.10 to 10.4.0 Bumps [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/platform-express) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 141ccb8aa..d901d8b99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2333,9 +2333,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.10.tgz", - "integrity": "sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.0.tgz", + "integrity": "sha512-DxrNsqywNVRs+4tmEXKNotumXEEGw+EvG2f9MyvDnHYU7tCZAT9ZsVnT6waM3lrjSmyjMaae8JuiMI8bnZj44g==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", From 7cbde9945916d10244cfb30c007aa55cd6757f65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:17:55 +0000 Subject: [PATCH 129/258] build(deps-dev): bump @types/node from 22.1.0 to 22.2.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.1.0 to 22.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d901d8b99..5092d9c9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3001,9 +3001,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", "dependencies": { "undici-types": "~6.13.0" } From 6e31bc0bda33dd543d6a41f70228372ad0399e0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:28:52 +0000 Subject: [PATCH 130/258] build(deps-dev): bump mocha from 10.7.0 to 10.7.3 Bumps [mocha](https://github.com/mochajs/mocha) from 10.7.0 to 10.7.3. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.7.0...v10.7.3) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5092d9c9c..46d5ce28f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10157,9 +10157,9 @@ } }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", From 178bc3dd263858968f66ed341b7d812bcc384845 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:39:21 +0000 Subject: [PATCH 131/258] build(deps): bump @nestjs/common from 10.3.10 to 10.4.0 Bumps [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/common) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46d5ce28f..b4b01810c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2181,9 +2181,9 @@ } }, "node_modules/@nestjs/common": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.10.tgz", - "integrity": "sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.0.tgz", + "integrity": "sha512-cGQJBMypG1qf0h31dvIYSffr/8+JhFd7qScJ4mqgF5HKT69WveW14zQcxavXzXI/LOE4vUvCu3QBeqcRBIs/9A==", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.3", From a037084b9b7e092638d400028d3a29c400a9823f Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Thu, 15 Aug 2024 17:47:52 +0200 Subject: [PATCH 132/258] wip: casl splitted, for users need to rewrite checkUserAuthorization --- src/casl/casl-ability.factory.ts | 1054 ++++++++++------- .../decorators/check-policies.decorator.ts | 2 +- src/casl/guards/policies.guard.ts | 26 +- src/datasets/datasets.controller.ts | 22 +- .../origdatablocks.controller.ts | 12 +- src/policies/policies.controller.ts | 3 +- src/proposals/proposals.controller.ts | 10 +- src/samples/samples.controller.ts | 10 +- src/users/user-identities.controller.ts | 2 +- src/users/users.controller.ts | 4 +- test/DatasetAuthorization.js | 2 +- test/UserAuthorization.js | 2 +- 12 files changed, 682 insertions(+), 467 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 0a410d24a..4e715d825 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -54,8 +54,121 @@ export type AppAbility = MongoAbility; @Injectable() export class CaslAbilityFactory { + accessEndpointForUser(user: JWTUser, subject: string) { + switch (subject) { + case 'elastic-search': + return this.accessElasticSearchEndpointForUser(user); + case 'logbooks': + return this.accessLogbookEndpointForUser(user); + case 'publisheddata': + return this.accessPublishedDataEndpointForUser(user); + case 'policies': + return this.accessPolicyEndpointForUser(user); + case 'users': + return this.accessUserEndpointForUser(user); + case 'datasets': + return this.accessDatasetEndpointForUser(user); + case 'origdatablocks': + return this.accessOrigDatablockEndpointForUser(user); + case 'jobs': + return this.accessJobsEnpointForUser(user); + case 'proposals': + return this.accessProposalsEndpointForUser(user); + case 'samples': + return this.accessSamplesEndpointForUser(user); + case 'instruments': + return this.accessInstrumentEndpointForUser(user); + default: + throw new Error(`No endpoint access policies defined for subject: ${subject}`); + } + } + + accessElasticSearchEndpointForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + can(Action.Manage, ElasticSearchActions); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessLogbookEndpointForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); - createForUser(user:JWTUser){ + if (user + ) { + /* + / authenticated user + */ + can(Action.Read, Logbook); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessPublishedDataEndpointForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (user){ + can(Action.Read, PublishedData); + can(Action.Update, PublishedData); + can(Action.Create, PublishedData); + } + + if (user && user.currentGroups.some((g) => configuration().deleteGroups.includes(g))){ + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + can(Action.Delete, PublishedData); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessPolicyEndpointForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (user && user.currentGroups.some((g) => configuration().deleteGroups.includes(g))){ + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + can(Action.Delete, Policy); + } else if (user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.Update, Policy); + can(Action.Read, Policy); + can(Action.Create, Policy); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessUserEndpointForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -74,16 +187,6 @@ export class CaslAbilityFactory { cannot(Action.UserUpdateAny, User); cannot(Action.UserDeleteAny, User); } else { - if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ - - can(Action.Delete, PublishedData); - can(Action.Delete, Policy); - } if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) ) { @@ -91,13 +194,7 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in ADMIN_GROUPS */ - can(Action.ReadAll, UserIdentity); - - // ------------------------------------- - // elasticsearch - // ------------------------------------- - // endpoint authorization - can(Action.Manage, ElasticSearchActions); + // can(Action.ReadAll, UserIdentity); NOT used? // ------------------------------------- // user endpoint, including useridentity @@ -109,11 +206,7 @@ export class CaslAbilityFactory { can(Action.UserCreateJwt, User); // ------------------------------------- - // policies - can(Action.Update, Policy); - can(Action.Read, Policy); - can(Action.Create, Policy); - } else { + } else if (user) { /** /* authenticated users **/ @@ -134,7 +227,7 @@ export class CaslAbilityFactory { }); } - createDatasetForUser(user:JWTUser){ + accessDatasetEndpointForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -144,8 +237,6 @@ export class CaslAbilityFactory { /* unauthenticated users **/ - // ------------------------------------- - // datasets endpoint authorization cannot(Action.DatasetCreate, DatasetClass); can(Action.DatasetRead, DatasetClass); cannot(Action.DatasetUpdate, DatasetClass); @@ -164,33 +255,8 @@ export class CaslAbilityFactory { cannot(Action.DatasetDatablockUpdate, DatasetClass); // - cannot(Action.DatasetLogbookRead, DatasetClass); - // ------------------------------------- - // datasets data instance authorization - can(Action.DatasetReadManyPublic, DatasetClass); - can(Action.DatasetReadOnePublic, DatasetClass, { - isPublished: true, - }); - // - - can(Action.DatasetAttachmentReadPublic, DatasetClass, { - isPublished: true, - }); - // - - can(Action.DatasetOrigdatablockReadPublic, DatasetClass, { - isPublished: true, - }); - // - - can(Action.DatasetDatablockReadPublic, DatasetClass, { - isPublished: true, - }); + - // cannot(Action.UserReadOwn, User); - // cannot(Action.UserCreateOwn, User); - // cannot(Action.UserUpdateOwn, User); - // cannot(Action.UserDeleteOwn, User); - // cannot(Action.UserReadAny, User); - // cannot(Action.UserCreateAny, User); - // cannot(Action.UserUpdateAny, User); - // cannot(Action.UserDeleteAny, User); } else { if ( user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) @@ -199,34 +265,19 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in DELETE_GROUPS */ - // ------------------------------------- - // datasets - // ------------------------------------- - // endpoint authorization + can(Action.DatasetDelete, DatasetClass); // - can(Action.DatasetOrigdatablockDelete, DatasetClass); // - can(Action.DatasetDatablockDelete, DatasetClass); - // ------------------------------------- - // data instance authorization - can(Action.DatasetDeleteAny, DatasetClass); - // - - can(Action.DatasetOrigdatablockDeleteAny, DatasetClass); - // - - can(Action.DatasetDatablockDeleteAny, DatasetClass); - // can(Action.Delete, PublishedData); - // can(Action.Delete, Policy); } else { /* / user that does not belong to any of the group listed in DELETE_GROUPS */ - // ------------------------------------- - // datasets - // ------------------------------------- - // endpoint authorization + cannot(Action.DatasetDelete, DatasetClass); // - cannot(Action.DatasetOrigdatablockDelete, DatasetClass); @@ -241,21 +292,36 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in ADMIN_GROUPS */ - // // this tests should be all removed, once we are done with authorization review - // //can(Action.ListAll, DatasetClass); - // // can(Action.ListAll, ProposalClass); - // can(Action.ReadAll, UserIdentity); + can(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + can(Action.DatasetUpdate, DatasetClass); + // - + can(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + can(Action.DatasetAttachmentUpdate, DatasetClass); + can(Action.DatasetAttachmentDelete, DatasetClass); + // - + can(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + can(Action.DatasetOrigdatablockUpdate, DatasetClass); + // - + can(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + can(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); + + - // // ------------------------------------- - // // elasticsearch - // // ------------------------------------- - // // endpoint authorization - // can(Action.Manage, ElasticSearchActions); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetPrivilegedGroups.includes(g), + ) + ) { + /** + /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + **/ - // ------------------------------------- - // datasets - // ------------------------------------- - // endpoint authorization can(Action.DatasetCreate, DatasetClass); can(Action.DatasetRead, DatasetClass); can(Action.DatasetUpdate, DatasetClass); @@ -274,54 +340,46 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - // ------------------------------------- - // data instance authorization - can(Action.DatasetCreateAny, DatasetClass); - can(Action.DatasetReadAny, DatasetClass); - can(Action.DatasetUpdateAny, DatasetClass); + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetWithPidGroups.includes(g), + ) || + configuration().createDatasetWithPidGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_WITH_PID_GROUPS + **/ + + can(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + can(Action.DatasetUpdate, DatasetClass); // - - can(Action.DatasetAttachmentCreateAny, DatasetClass); - can(Action.DatasetAttachmentReadAny, DatasetClass); - can(Action.DatasetAttachmentUpdateAny, DatasetClass); - can(Action.DatasetAttachmentDeleteAny, DatasetClass); + can(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + can(Action.DatasetAttachmentUpdate, DatasetClass); + can(Action.DatasetAttachmentDelete, DatasetClass); // - - can(Action.DatasetOrigdatablockCreateAny, DatasetClass); - can(Action.DatasetOrigdatablockReadAny, DatasetClass); - can(Action.DatasetOrigdatablockUpdateAny, DatasetClass); + can(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + can(Action.DatasetOrigdatablockUpdate, DatasetClass); // - - can(Action.DatasetDatablockCreateAny, DatasetClass); - can(Action.DatasetDatablockReadAny, DatasetClass); - can(Action.DatasetDatablockUpdateAny, DatasetClass); - // ------------------------------------- - can(Action.DatasetLogbookReadAny, DatasetClass); + can(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + can(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); - // // ------------------------------------- - // // user endpoint, including useridentity - // can(Action.UserReadAny, User); - // can(Action.UserReadOwn, User); - // can(Action.UserCreateAny, User); - // can(Action.UserUpdateAny, User); - // can(Action.UserDeleteAny, User); - // can(Action.UserCreateJwt, User); - - // // ------------------------------------- - // // policies - // can(Action.Update, Policy); - // can(Action.Read, Policy); - // can(Action.Create, Policy); } else if ( user.currentGroups.some((g) => - configuration().createDatasetPrivilegedGroups.includes(g), - ) + configuration().createDatasetGroups.includes(g), + ) || + configuration().createDatasetGroups.includes("#all") ) { /** - /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + /* users belonging to CREATE_DATASET_GROUPS **/ - // ------------------------------------- - // datasets - // ------------------------------------- - // endpoint authorization can(Action.DatasetCreate, DatasetClass); can(Action.DatasetRead, DatasetClass); can(Action.DatasetUpdate, DatasetClass); @@ -340,8 +398,121 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); + + } else if (user) { + /** + /* authenticated users + **/ + + cannot(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + cannot(Action.DatasetUpdate, DatasetClass); + // - + cannot(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + cannot(Action.DatasetAttachmentUpdate, DatasetClass); + cannot(Action.DatasetAttachmentDelete, DatasetClass); + // - + cannot(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + cannot(Action.DatasetOrigdatablockUpdate, DatasetClass); + // - + cannot(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + cannot(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); + + } + + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessDatasetDataInstanceForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + /** + /* unauthenticated users + **/ + + can(Action.DatasetReadManyPublic, DatasetClass); + can(Action.DatasetReadOnePublic, DatasetClass, { + isPublished: true, + }); + // - + can(Action.DatasetAttachmentReadPublic, DatasetClass, { + isPublished: true, + }); + // - + can(Action.DatasetOrigdatablockReadPublic, DatasetClass, { + isPublished: true, + }); + // - + can(Action.DatasetDatablockReadPublic, DatasetClass, { + isPublished: true, + }); + + + } else { + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.DatasetDeleteAny, DatasetClass); + // - + can(Action.DatasetOrigdatablockDeleteAny, DatasetClass); + // - + can(Action.DatasetDatablockDeleteAny, DatasetClass); + + + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.DatasetCreateAny, DatasetClass); + can(Action.DatasetReadAny, DatasetClass); + can(Action.DatasetUpdateAny, DatasetClass); + // - + can(Action.DatasetAttachmentCreateAny, DatasetClass); + can(Action.DatasetAttachmentReadAny, DatasetClass); + can(Action.DatasetAttachmentUpdateAny, DatasetClass); + can(Action.DatasetAttachmentDeleteAny, DatasetClass); + // - + can(Action.DatasetOrigdatablockCreateAny, DatasetClass); + can(Action.DatasetOrigdatablockReadAny, DatasetClass); + can(Action.DatasetOrigdatablockUpdateAny, DatasetClass); + // - + can(Action.DatasetDatablockCreateAny, DatasetClass); + can(Action.DatasetDatablockReadAny, DatasetClass); + can(Action.DatasetDatablockUpdateAny, DatasetClass); // ------------------------------------- - // data instance authorization + can(Action.DatasetLogbookReadAny, DatasetClass); + + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetPrivilegedGroups.includes(g), + ) + ) { + /** + /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + **/ + can(Action.DatasetCreateAny, DatasetClass); can(Action.DatasetReadManyAccess, DatasetClass); can(Action.DatasetReadOneAccess, DatasetClass, { @@ -416,28 +587,6 @@ export class CaslAbilityFactory { /* users belonging to CREATE_DATASET_WITH_PID_GROUPS **/ - // ------------------------------------- - // datasets endpoint authorization - can(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - can(Action.DatasetUpdate, DatasetClass); - // - - can(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - can(Action.DatasetAttachmentUpdate, DatasetClass); - can(Action.DatasetAttachmentDelete, DatasetClass); - // - - can(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - can(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - can(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - can(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); - // ------------------------------------- - // datasets data instance authorization can(Action.DatasetCreateOwnerWithPid, DatasetClass, { ownerGroup: { $in: user.currentGroups }, }); @@ -520,28 +669,6 @@ export class CaslAbilityFactory { /* users belonging to CREATE_DATASET_GROUPS **/ - // ------------------------------------- - // datasets endpoint authorization - can(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - can(Action.DatasetUpdate, DatasetClass); - // - - can(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - can(Action.DatasetAttachmentUpdate, DatasetClass); - can(Action.DatasetAttachmentDelete, DatasetClass); - // - - can(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - can(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - can(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - can(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); - // ------------------------------------- - // datasets data instance authorization can(Action.DatasetCreateOwnerNoPid, DatasetClass, { ownerGroup: { $in: user.currentGroups }, pid: { $eq: "" }, @@ -621,28 +748,6 @@ export class CaslAbilityFactory { /* authenticated users **/ - // ------------------------------------- - // datasets endpoint authorization - cannot(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - cannot(Action.DatasetUpdate, DatasetClass); - // - - cannot(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - cannot(Action.DatasetAttachmentUpdate, DatasetClass); - cannot(Action.DatasetAttachmentDelete, DatasetClass); - // - - cannot(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - cannot(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - cannot(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - cannot(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); - // ------------------------------------- - // datasets data instance authorization can(Action.DatasetReadManyAccess, DatasetClass); can(Action.DatasetReadOneAccess, DatasetClass, { ownerGroup: { $in: user.currentGroups }, @@ -688,16 +793,8 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); - // cannot(Action.UserReadAny, User); - // cannot(Action.UserCreateAny, User); - // cannot(Action.UserUpdateAny, User); - // cannot(Action.UserDeleteAny, User); - // cannot(Action.UserCreateJwt, User); } - // can(Action.UserReadOwn, User, { _id: user._id }); - // can(Action.UserCreateOwn, User, { _id: user._id }); - // can(Action.UserUpdateOwn, User, { _id: user._id }); - // can(Action.UserDeleteOwn, User, { _id: user._id }); + } return build({ detectSubjectType: (item) => @@ -705,8 +802,7 @@ export class CaslAbilityFactory { }); } - - createOrigDatablockForUser(user:JWTUser){ + accessOrigDatablockEndpointForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -717,17 +813,12 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in DELETE_GROUPS */ - // endpoint authorization can(Action.OrigdatablockDelete, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockDeleteAny, OrigDatablock); } else { /* / user that does not belong to any of the group listed in DELETE_GROUPS */ - // endpoint authorization cannot(Action.OrigdatablockDelete, OrigDatablock); } @@ -738,15 +829,9 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in ADMIN_GROUPS */ - // endpoint authorization can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization - can(Action.OrigdatablockReadAny, OrigDatablock); - can(Action.OrigdatablockCreateAny, OrigDatablock); - can(Action.OrigdatablockUpdateAny, OrigDatablock); } else if ( user.currentGroups.some((g) => @@ -756,12 +841,88 @@ export class CaslAbilityFactory { /** /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS **/ - // endpoint authorization + can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetWithPidGroups.includes(g), + ) || + configuration().createDatasetWithPidGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_WITH_PID_GROUPS + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetGroups.includes(g), + ) || + configuration().createDatasetGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_GROUPS + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + + } else if (user) { + /** + /* authenticated users + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + cannot(Action.OrigdatablockCreate, OrigDatablock); + cannot(Action.OrigdatablockUpdate, OrigDatablock); + + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + + } + + accessOrigDatablockDataInstanceForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.OrigdatablockDeleteAny, OrigDatablock); + } + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.OrigdatablockReadAny, OrigDatablock); + can(Action.OrigdatablockCreateAny, OrigDatablock); + can(Action.OrigdatablockUpdateAny, OrigDatablock); + + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetPrivilegedGroups.includes(g), + ) + ) { + /** + /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + **/ can(Action.OrigdatablockCreateAny, OrigDatablock); can(Action.OrigdatablockReadManyAccess, OrigDatablock); can(Action.OrigdatablockReadOneAccess, OrigDatablock, { @@ -786,12 +947,6 @@ export class CaslAbilityFactory { /* users belonging to CREATE_DATASET_WITH_PID_GROUPS **/ - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization can(Action.OrigdatablockCreateOwner, OrigDatablock, { ownerGroup: { $in: user.currentGroups }, }); @@ -818,12 +973,6 @@ export class CaslAbilityFactory { /* users belonging to CREATE_DATASET_GROUPS **/ - // endpoint authorization - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization can(Action.OrigdatablockCreateOwner, OrigDatablock, { ownerGroup: { $in: user.currentGroups }, }); @@ -845,11 +994,6 @@ export class CaslAbilityFactory { /* authenticated users **/ - can(Action.OrigdatablockRead, OrigDatablock); - cannot(Action.OrigdatablockCreate, OrigDatablock); - cannot(Action.OrigdatablockUpdate, OrigDatablock); - // ------------------------------------- - // data instance authorization can(Action.OrigdatablockReadManyAccess, OrigDatablock); can(Action.OrigdatablockReadOneAccess, OrigDatablock, { ownerGroup: { $in: user.currentGroups }, @@ -868,22 +1012,15 @@ export class CaslAbilityFactory { } - createJobsForUser(user:JWTUser){ + accessJobsEnpointForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); - // ************************************ - // JOBS AUTHORIZATION - // ************************************ if (!user) { /** * unauthenticated users */ - // ------------------------------------- - // jobs - // ------------------------------------- - // endpoint authorization cannot(Action.JobsRead, JobClass); cannot(Action.JobsCreate, JobClass); cannot(Action.JobsUpdate, JobClass); @@ -894,18 +1031,10 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in ADMIN_GROUPS */ - // ------------------------------------- - // jobs - // ------------------------------------- - // endpoint authorization can(Action.JobsRead, JobClass); can(Action.JobsCreate, JobClass); can(Action.JobsUpdate, JobClass); - // ------------------------------------- - // data instance authorization - can(Action.JobsReadAny, JobClass); - can(Action.JobsCreateAny, JobClass); - can(Action.JobsUpdateAny, JobClass); + } else if ( user.currentGroups.some((g) => configuration().createJobGroups.includes(g), @@ -915,15 +1044,58 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in CREATE_JOBS_GROUPS */ - // ------------------------------------- - // jobs - // ------------------------------------- - // endpoint authorization can(Action.JobsRead, JobClass); can(Action.JobsCreate, JobClass); can(Action.JobsUpdate, JobClass); - // ------------------------------------- - // data instance authorization + + } else if ( + user.currentGroups.some((g) => + configuration().updateJobGroups.includes(g), + ) + ) { + /** + * authenticated users belonging to any of the group listed in UPDATE_JOBS_GROUPS + */ + + cannot(Action.JobsRead, JobClass); + cannot(Action.JobsCreate, JobClass); + can(Action.JobsUpdate, JobClass); + + } else if (user) { + /** + * authenticated users + */ + + can(Action.JobsRead, JobClass); + cannot(Action.JobsCreate, JobClass); + cannot(Action.JobsUpdate, JobClass); + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessJobsDataInstanceForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + can(Action.JobsReadAny, JobClass); + can(Action.JobsCreateAny, JobClass); + can(Action.JobsUpdateAny, JobClass); + } else if ( + user.currentGroups.some((g) => + configuration().createJobGroups.includes(g), + ) + ) { + /** + * authenticated users belonging to any of the group listed in CREATE_JOBS_GROUPS + */ + can(Action.JobsCreateAny, JobClass, { ownerGroup: { $in: user.currentGroups }, }); @@ -942,57 +1114,92 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in UPDATE_JOBS_GROUPS */ - // ------------------------------------- - // jobs - // ------------------------------------- - // endpoint authorization - cannot(Action.JobsRead, JobClass); - cannot(Action.JobsCreate, JobClass); - can(Action.JobsUpdate, JobClass); - // ------------------------------------- - // data instance authorization can(Action.JobsUpdateAny, JobClass, { ownerGroup: { $in: user.currentGroups }, }); } else if (user) { /** - * authenticated users + * authenticated users + */ + + can(Action.JobsReadAccess, JobClass, { + ownerGroup: { $in: user.currentGroups }, + }); + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessProposalsEndpointForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (!user) { + /** + * unauthenticated users + */ + + can(Action.ProposalsRead, ProposalClass); + cannot(Action.ProposalsCreate, ProposalClass); + cannot(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + cannot(Action.ProposalsAttachmentCreate, ProposalClass); + cannot(Action.ProposalsAttachmentUpdate, ProposalClass); + cannot(Action.ProposalsAttachmentDelete, ProposalClass); + + } else if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.ProposalsDelete, ProposalClass); + + } else if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /** + * authenticated users belonging to any of the group listed in ADMIN_GROUPS + */ + + can(Action.ProposalsRead, ProposalClass); + can(Action.ProposalsCreate, ProposalClass); + can(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + can(Action.ProposalsAttachmentCreate, ProposalClass); + can(Action.ProposalsAttachmentUpdate, ProposalClass); + can(Action.ProposalsAttachmentDelete, ProposalClass); + + } else if ( + user.currentGroups.some((g) => { + return configuration().proposalGroups.includes(g); + }) + ) { + /** + * authenticated users belonging to any of the group listed in PROPOSAL_GROUPS */ - // ------------------------------------- - // jobs - // ------------------------------------- - // endpoint authorization - can(Action.JobsRead, JobClass); - cannot(Action.JobsCreate, JobClass); - cannot(Action.JobsUpdate, JobClass); - // ------------------------------------- - // data instance authorization - can(Action.JobsReadAccess, JobClass, { - ownerGroup: { $in: user.currentGroups }, - }); - } - - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - createProposalsForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - // ************************************ - // PROPOSALS AUTHORIZATION - // ************************************ + can(Action.ProposalsRead, ProposalClass); + can(Action.ProposalsCreate, ProposalClass); + can(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + can(Action.ProposalsAttachmentCreate, ProposalClass); + can(Action.ProposalsAttachmentUpdate, ProposalClass); + can(Action.ProposalsAttachmentDelete, ProposalClass); + cannot(Action.ProposalsDatasetRead, ProposalClass); - if (!user) { + } else if (user) { /** - * unauthenticated users + * authenticated users */ - // endpoint authorization can(Action.ProposalsRead, ProposalClass); cannot(Action.ProposalsCreate, ProposalClass); cannot(Action.ProposalsUpdate, ProposalClass); @@ -1001,9 +1208,24 @@ export class CaslAbilityFactory { cannot(Action.ProposalsAttachmentCreate, ProposalClass); cannot(Action.ProposalsAttachmentUpdate, ProposalClass); cannot(Action.ProposalsAttachmentDelete, ProposalClass); + can(Action.ProposalsDatasetRead, ProposalClass); + + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessProposalsDataInstanceForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (!user) { + /** + * unauthenticated users + */ - // ------------------------------------- - // data instance authorization can(Action.ProposalsReadManyPublic, ProposalClass); can(Action.ProposalsReadOnePublic, ProposalClass, { isPublished: true, @@ -1017,13 +1239,6 @@ export class CaslAbilityFactory { /* / user that belongs to any of the group listed in DELETE_GROUPS */ - - // endpoint authorization - can(Action.ProposalsDelete, ProposalClass); - - // ------------------------------------- - // data instance authorization - can(Action.ProposalsDeleteAny, ProposalClass); } else if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) @@ -1032,17 +1247,6 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in ADMIN_GROUPS */ - // endpoint authorization - can(Action.ProposalsRead, ProposalClass); - can(Action.ProposalsCreate, ProposalClass); - can(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - can(Action.ProposalsAttachmentCreate, ProposalClass); - can(Action.ProposalsAttachmentUpdate, ProposalClass); - can(Action.ProposalsAttachmentDelete, ProposalClass); - // ------------------------------------- - // data instance authorization can(Action.ProposalsReadAny, ProposalClass); can(Action.ProposalsCreateAny, ProposalClass); can(Action.ProposalsUpdateAny, ProposalClass); @@ -1060,19 +1264,6 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in PROPOSAL_GROUPS */ - // endpoint authorization - - can(Action.ProposalsRead, ProposalClass); - can(Action.ProposalsCreate, ProposalClass); - can(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - can(Action.ProposalsAttachmentCreate, ProposalClass); - can(Action.ProposalsAttachmentUpdate, ProposalClass); - can(Action.ProposalsAttachmentDelete, ProposalClass); - cannot(Action.ProposalsDatasetRead, ProposalClass); - // ------------------------------------- - // data instance authorization can(Action.ProposalsCreateAny, ProposalClass); can(Action.ProposalsReadManyAccess, ProposalClass); can(Action.ProposalsReadOneAccess, ProposalClass, { @@ -1106,18 +1297,6 @@ export class CaslAbilityFactory { * authenticated users */ - // endpoint authorization - can(Action.ProposalsRead, ProposalClass); - cannot(Action.ProposalsCreate, ProposalClass); - cannot(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - cannot(Action.ProposalsAttachmentCreate, ProposalClass); - cannot(Action.ProposalsAttachmentUpdate, ProposalClass); - cannot(Action.ProposalsAttachmentDelete, ProposalClass); - can(Action.ProposalsDatasetRead, ProposalClass); - // ------------------------------------- - // data instance authorization can(Action.ProposalsReadManyAccess, ProposalClass); can(Action.ProposalsReadOneAccess, ProposalClass, { ownerGroup: { $in: user.currentGroups }, @@ -1145,24 +1324,17 @@ export class CaslAbilityFactory { }); } - - - createSamplesForUser(user:JWTUser){ + accessSamplesEndpointForUser(user:JWTUser){ const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); - // ************************************ - // SAMPLES AUTHORIZATION - // ************************************ - if (!user) { // ------------------------------------- // unauthenticated users // ------------------------------------- - // ------------------------------------- - // endpoint authorization + can(Action.SampleRead, SampleClass); cannot(Action.SampleCreate, SampleClass); cannot(Action.SampleUpdate, SampleClass); @@ -1173,15 +1345,6 @@ export class CaslAbilityFactory { cannot(Action.SampleAttachmentDelete, SampleClass); cannot(Action.SampleDatasetRead, SampleClass); - // ------------------------------------- - // data instance authorization - can(Action.SampleReadManyPublic, SampleClass); - can(Action.SampleReadOnePublic, SampleClass, { - isPublished: true, - }); - can(Action.SampleAttachmentReadPublic, SampleClass, { - isPublished: true, - }); } else { // ------------------------------------- // authenticated users @@ -1194,28 +1357,16 @@ export class CaslAbilityFactory { // users that belong to any of the group listed in DELETE_GROUPS // ------------------------------------- - // ------------------------------------- - // endpoint authorization can(Action.SampleDelete, SampleClass); can(Action.SampleAttachmentDelete, SampleClass); - // ------------------------------------- - // data instance authorization - can(Action.SampleDeleteAny, SampleClass); - can(Action.SampleAttachmentDeleteAny, SampleClass); } else { // ------------------------------------- // users that do not belong to any of the group listed in DELETE_GROUPS // ------------------------------------- - // ------------------------------------- - // endpoint authorization cannot(Action.SampleDelete, SampleClass); - // ------------------------------------- - // data instance authorization - cannot(Action.SampleDeleteAny, SampleClass); - cannot(Action.SampleDeleteOwner, SampleClass); } if ( @@ -1225,8 +1376,6 @@ export class CaslAbilityFactory { // users belonging to any of the group listed in ADMIN_GROUPS // ------------------------------------- - // ------------------------------------- - // endpoint authorization can(Action.SampleRead, SampleClass); can(Action.SampleCreate, SampleClass); can(Action.SampleUpdate, SampleClass); @@ -1236,15 +1385,6 @@ export class CaslAbilityFactory { can(Action.SampleAttachmentDelete, SampleClass); can(Action.SampleDatasetRead, SampleClass); - // ------------------------------------- - // data instance authorization - can(Action.SampleReadAny, SampleClass); - can(Action.SampleCreateAny, SampleClass); - can(Action.SampleUpdateAny, SampleClass); - can(Action.SampleAttachmentReadAny, SampleClass); - can(Action.SampleAttachmentCreateAny, SampleClass); - can(Action.SampleAttachmentUpdateAny, SampleClass); - can(Action.SampleAttachmentDeleteAny, SampleClass); } else if ( user.currentGroups.some((g) => configuration().samplePrivilegedGroups.includes(g), @@ -1254,8 +1394,25 @@ export class CaslAbilityFactory { // users belonging to any of the group listed in SAMPLE_GROUPS // + can(Action.SampleRead, SampleClass); + can(Action.SampleCreate, SampleClass); + can(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + can(Action.SampleAttachmentCreate, SampleClass); + can(Action.SampleAttachmentUpdate, SampleClass); + can(Action.SampleAttachmentDelete, SampleClass); + can(Action.SampleDatasetRead, SampleClass); + + } else if ( + user.currentGroups.some((g) => + configuration().sampleGroups.includes(g), + ) || + configuration().sampleGroups.includes("#all") + ) { // ------------------------------------- - // endpoint authorization + // users belonging to any of the group listed in SAMPLE_GROUPS + // + can(Action.SampleRead, SampleClass); can(Action.SampleCreate, SampleClass); can(Action.SampleUpdate, SampleClass); @@ -1265,8 +1422,96 @@ export class CaslAbilityFactory { can(Action.SampleAttachmentDelete, SampleClass); can(Action.SampleDatasetRead, SampleClass); + } else { + // ------------------------------------- + // users with no elevated permissions + // ------------------------------------- + + can(Action.SampleRead, SampleClass); + cannot(Action.SampleCreate, SampleClass); + cannot(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + cannot(Action.SampleAttachmentCreate, SampleClass); + cannot(Action.SampleAttachmentUpdate, SampleClass); + if ( + !user.currentGroups.some((g) => + configuration().deleteGroups.includes(g), + ) + ) { + cannot(Action.SampleAttachmentDelete, SampleClass); + } + } + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + accessSamplesDataInstanceForUser(user:JWTUser){ + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + // ------------------------------------- + // unauthenticated users + // ------------------------------------- + + can(Action.SampleReadManyPublic, SampleClass); + can(Action.SampleReadOnePublic, SampleClass, { + isPublished: true, + }); + can(Action.SampleAttachmentReadPublic, SampleClass, { + isPublished: true, + }); + } else { + // ------------------------------------- + // authenticated users + // ------------------------------------- + + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + // ------------------------------------- + // users that belong to any of the group listed in DELETE_GROUPS + // ------------------------------------- + + can(Action.SampleDeleteAny, SampleClass); + can(Action.SampleAttachmentDeleteAny, SampleClass); + } else { + // ------------------------------------- + // users that do not belong to any of the group listed in DELETE_GROUPS + // ------------------------------------- + + cannot(Action.SampleDeleteAny, SampleClass); + cannot(Action.SampleDeleteOwner, SampleClass); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + // ------------------------------------- + // users belonging to any of the group listed in ADMIN_GROUPS + // ------------------------------------- + + can(Action.SampleReadAny, SampleClass); + can(Action.SampleCreateAny, SampleClass); + can(Action.SampleUpdateAny, SampleClass); + can(Action.SampleAttachmentReadAny, SampleClass); + can(Action.SampleAttachmentCreateAny, SampleClass); + can(Action.SampleAttachmentUpdateAny, SampleClass); + can(Action.SampleAttachmentDeleteAny, SampleClass); + } else if ( + user.currentGroups.some((g) => + configuration().samplePrivilegedGroups.includes(g), + ) + ) { // ------------------------------------- - // data instance authorization + // users belonging to any of the group listed in SAMPLE_GROUPS + // + can(Action.SampleCreateAny, SampleClass); can(Action.SampleUpdateOwner, SampleClass, { ownerGroup: { $in: user.currentGroups }, @@ -1307,19 +1552,6 @@ export class CaslAbilityFactory { // users belonging to any of the group listed in SAMPLE_GROUPS // - // ------------------------------------- - // endpoint authorization - can(Action.SampleRead, SampleClass); - can(Action.SampleCreate, SampleClass); - can(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - can(Action.SampleAttachmentCreate, SampleClass); - can(Action.SampleAttachmentUpdate, SampleClass); - can(Action.SampleAttachmentDelete, SampleClass); - can(Action.SampleDatasetRead, SampleClass); - - // ------------------------------------- - // data instance authorization can(Action.SampleCreateOwner, SampleClass, { ownerGroup: { $in: user.currentGroups }, }); @@ -1359,24 +1591,6 @@ export class CaslAbilityFactory { // users with no elevated permissions // ------------------------------------- - // ------------------------------------- - // endpoint authorization - can(Action.SampleRead, SampleClass); - cannot(Action.SampleCreate, SampleClass); - cannot(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - cannot(Action.SampleAttachmentCreate, SampleClass); - cannot(Action.SampleAttachmentUpdate, SampleClass); - if ( - !user.currentGroups.some((g) => - configuration().deleteGroups.includes(g), - ) - ) { - cannot(Action.SampleAttachmentDelete, SampleClass); - } - - // ------------------------------------- - // data instance authorization can(Action.SampleReadManyAccess, SampleClass); can(Action.SampleReadOneAccess, SampleClass, { ownerGroup: { $in: user.currentGroups }, @@ -1405,15 +1619,11 @@ export class CaslAbilityFactory { }); } - createInstrumentForUser(user: JWTUser) { + accessInstrumentEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); - // ************************************ - // INSTRUMENT AUTHORIZATION - // ************************************ - if (!user) { cannot(Action.InstrumentRead, Instrument); cannot(Action.InstrumentCreate, Instrument); @@ -1427,8 +1637,6 @@ export class CaslAbilityFactory { * user that belongs to any of the group listed in DELETE_GROUPS */ - // ------------------------------------- - // endpoint authorization can(Action.InstrumentDelete, Instrument); } else { cannot(Action.InstrumentDelete, Instrument); @@ -1441,8 +1649,6 @@ export class CaslAbilityFactory { * authenticated users belonging to any of the group listed in ADMIN_GROUPS */ - // ------------------------------------- - // endpoint authorization can(Action.InstrumentRead, Instrument); can(Action.InstrumentCreate, Instrument); can(Action.InstrumentUpdate, Instrument); @@ -1453,16 +1659,10 @@ export class CaslAbilityFactory { } } - // can(Action.Read, Logbook); - - // can(Action.Read, PublishedData); - // can(Action.Update, PublishedData); - // can(Action.Create, PublishedData); - - return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } } + diff --git a/src/casl/decorators/check-policies.decorator.ts b/src/casl/decorators/check-policies.decorator.ts index 6ac4f3550..dda83aa67 100644 --- a/src/casl/decorators/check-policies.decorator.ts +++ b/src/casl/decorators/check-policies.decorator.ts @@ -3,5 +3,5 @@ import { PolicyHandler } from "../interfaces/policy-handler.interface"; export const CHECK_POLICIES_KEY = "check_policy"; -export const CheckPolicies = (...handlers: PolicyHandler[]) => +export const CheckPolicies = ( ...handlers: PolicyHandler[]) => SetMetadata(CHECK_POLICIES_KEY, handlers); diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index 17ff148ce..c646ec418 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -3,6 +3,7 @@ import { Reflector } from "@nestjs/core"; import { AppAbility, CaslAbilityFactory } from "../casl-ability.factory"; import { CHECK_POLICIES_KEY } from "../decorators/check-policies.decorator"; import { PolicyHandler } from "../interfaces/policy-handler.interface"; +import { request } from "https"; @Injectable() export class PoliciesGuard implements CanActivate { @@ -12,22 +13,25 @@ export class PoliciesGuard implements CanActivate { ) {} async canActivate(context: ExecutionContext): Promise { + const policyHandlers = - this.reflector.get( - CHECK_POLICIES_KEY, - context.getHandler(), - ) || []; + this.reflector.get( + CHECK_POLICIES_KEY, + context.getHandler(), + ) || []; const req = context.switchToHttp().getRequest(); const user = req.user; - const ability = this.caslAbilityFactory.createForUser(user); + const endpoint = req.route.path.split("/")[3] + + const ability = this.caslAbilityFactory.accessEndpointForUser(user, endpoint); return policyHandlers.every((handler) => this.execPolicyHandler(handler, ability), ); } + private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) { - //console.log('PoliciesGuard:execPolicyHandler ', handler, ability) if (typeof handler === "function") { const res = handler(ability); //console.log("PoliciesGuard:execPolicyHandler ", res); @@ -36,3 +40,13 @@ export class PoliciesGuard implements CanActivate { return handler.handle(ability); } } + + + + + + // Assuming that there is only one policy handler, extract the subject + //const policyHandler = policyHandlers[0]; + //const subject = this.extractSubjectFromPolicyHandler(policyHandler); + + \ No newline at end of file diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index c01b70ecc..6180a9476 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -160,7 +160,7 @@ export class DatasetsController { ): IFilters { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -205,7 +205,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); let canDoAction = false; @@ -290,7 +290,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -355,7 +355,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -691,7 +691,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -769,7 +769,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -850,7 +850,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1098,7 +1098,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1177,7 +1177,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1227,7 +1227,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createDatasetForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || @@ -1278,7 +1278,7 @@ export class DatasetsController { @Query("data") data: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const datasetToUpdate = await this.datasetsService.findOne({ where: { pid: pid }, }); diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 12911cba7..0ecc13253 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -128,7 +128,7 @@ export class OrigDatablocksController { const origDatablockInstance = await this.generateOrigDatablockInstanceInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); let canDoAction = false; @@ -302,7 +302,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const parsedFilters: IFilters = JSON.parse(filter ?? "{}"); - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { parsedFilters.where = parsedFilters.where ?? {}; @@ -363,7 +363,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { @@ -426,7 +426,7 @@ export class OrigDatablocksController { ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -467,7 +467,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -508,7 +508,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.createOrigDatablockForUser(user); + const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( diff --git a/src/policies/policies.controller.ts b/src/policies/policies.controller.ts index 0ee2ea98f..442fe922e 100644 --- a/src/policies/policies.controller.ts +++ b/src/policies/policies.controller.ts @@ -84,7 +84,8 @@ export class PoliciesController { const user: JWTUser = request.user as JWTUser; if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessPolicyEndpointForUser(user); + // these actions are not defined in casl const canViewAll = ability.can(Action.ListAll, Policy); const canViewTheirOwn = ability.can(Action.ListOwn, Policy); if (!canViewAll && canViewTheirOwn) { diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 3fddfa348..3a5aae474 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -99,7 +99,7 @@ export class ProposalsController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); try { switch (group) { @@ -208,7 +208,7 @@ export class ProposalsController { mergedFilters.where = mergedFilters.where || {}; if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -407,7 +407,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -478,7 +478,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const facets = JSON.parse(filters.facets ?? "[]"); if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -869,7 +869,7 @@ export class ProposalsController { @Param("pid") proposalId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index a5077fcdf..87dcc4478 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -97,7 +97,7 @@ export class SamplesController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); try { switch (group) { @@ -198,7 +198,7 @@ export class SamplesController { /* eslint-disable @typescript-eslint/no-explicit-any */ const authorizationFilter: Record = { where: {} }; if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -356,7 +356,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -427,7 +427,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -870,7 +870,7 @@ export class SamplesController { @Param("id") sampleId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.createForUser(user); + const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index a20b421b3..a1d01a811 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -56,7 +56,7 @@ export class UserIdentitiesController { const authenticatedUser: JWTUser = request.user as JWTUser; const ability = - await this.caslAbilityFactory.createForUser(authenticatedUser); + await this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); if ( !ability.can(Action.UserReadAny, User) && diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index f5438de8b..433d8c9a6 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -65,7 +65,7 @@ export class UsersController { viewedUserSchema._id = viewedUserId; viewedUserSchema.id = viewedUserId; - const ability = this.caslAbilityFactory.createForUser(authenticatedUser); + const ability = this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); // const authorized = actions.map( action => // ability.can(action, viewedUserSchema) // ) as Array; @@ -328,7 +328,7 @@ export class UsersController { const viewedUser = (await this.usersService.findById2JWTUser( id, )) as JWTUser; - const ability = this.caslAbilityFactory.createForUser(viewedUser); + const ability = this.caslAbilityFactory.accessDatasetEndpointForUser(viewedUser); const canCreateDataset = ability.can(Action.DatasetCreate, DatasetClass); diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index 1ae7d4a4b..ab707200d 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -41,7 +41,7 @@ const dataset3 = { accessGroups: ["group3"], }; -describe.only("0300: DatasetAuthorization: Test access to dataset", () => { +describe("0300: DatasetAuthorization: Test access to dataset", () => { before(() => { db.collection("Dataset").deleteMany({}); }); diff --git a/test/UserAuthorization.js b/test/UserAuthorization.js index a8fb227f0..ea4f27ada 100644 --- a/test/UserAuthorization.js +++ b/test/UserAuthorization.js @@ -20,7 +20,7 @@ let accessTokenAdminIngestor = null, accessTokenArchiveManager = null, userIdArchiveManager = null; -describe("2300: User Authorization: test that user authorization are correct", () => { +describe.only("2300: User Authorization: test that user authorization are correct", () => { beforeEach(async() => { const loginResponseIngestor = await utils.getIdAndToken(appUrl, { username: "adminIngestor", From 652ecdea625c6b1291f5d1cf99bb55baf8048e0e Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Fri, 16 Aug 2024 09:41:43 +0200 Subject: [PATCH 133/258] fixed useridentities option in casl, fixed linting --- src/casl/casl-ability.factory.ts | 206 +++++++----------- .../decorators/check-policies.decorator.ts | 2 +- src/casl/guards/policies.guard.ts | 30 +-- src/datasets/datasets.controller.ts | 33 ++- .../origdatablocks.controller.ts | 18 +- src/proposals/proposals.controller.ts | 15 +- src/samples/samples.controller.ts | 15 +- src/users/user-identities.controller.ts | 4 +- src/users/users.controller.ts | 6 +- test/UserAuthorization.js | 2 +- 10 files changed, 157 insertions(+), 174 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 4e715d825..c98c9ba4b 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -56,119 +56,129 @@ export type AppAbility = MongoAbility; export class CaslAbilityFactory { accessEndpointForUser(user: JWTUser, subject: string) { switch (subject) { - case 'elastic-search': + case "datasets": + return this.accessDatasetEndpointForUser(user); + case "elastic-search": return this.accessElasticSearchEndpointForUser(user); - case 'logbooks': + case "jobs": + return this.accessJobsEnpointForUser(user); + case "instruments": + return this.accessInstrumentEndpointForUser(user); + case "logbooks": return this.accessLogbookEndpointForUser(user); - case 'publisheddata': - return this.accessPublishedDataEndpointForUser(user); - case 'policies': - return this.accessPolicyEndpointForUser(user); - case 'users': - return this.accessUserEndpointForUser(user); - case 'datasets': - return this.accessDatasetEndpointForUser(user); - case 'origdatablocks': + case "origdatablocks": return this.accessOrigDatablockEndpointForUser(user); - case 'jobs': - return this.accessJobsEnpointForUser(user); - case 'proposals': + case "policies": + return this.accessPolicyEndpointForUser(user); + case "proposals": return this.accessProposalsEndpointForUser(user); - case 'samples': + case "publisheddata": + return this.accessPublishedDataEndpointForUser(user); + case "samples": return this.accessSamplesEndpointForUser(user); - case 'instruments': - return this.accessInstrumentEndpointForUser(user); + case "users": + return this.accessUserEndpointForUser(user); + case "useridentities": + return this.accessUserEndpointForUser(user); default: - throw new Error(`No endpoint access policies defined for subject: ${subject}`); + throw new Error(` + No endpoint access policies defined for subject: ${subject}`); } } - accessElasticSearchEndpointForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessElasticSearchEndpointForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); - if (user && - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* + if ( + user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* / user that belongs to any of the group listed in ADMIN_GROUPS */ - can(Action.Manage, ElasticSearchActions); - } + can(Action.Manage, ElasticSearchActions); + } return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } - accessLogbookEndpointForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessLogbookEndpointForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); - if (user - ) { - /* + if (user) { + /* / authenticated user */ - can(Action.Read, Logbook); - } + can(Action.Read, Logbook); + } return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } - - accessPublishedDataEndpointForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + + accessPublishedDataEndpointForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); - if (user){ + if (user) { can(Action.Read, PublishedData); can(Action.Update, PublishedData); can(Action.Create, PublishedData); } - if (user && user.currentGroups.some((g) => configuration().deleteGroups.includes(g))){ - /* + if ( + user && + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* / user that belongs to any of the group listed in DELETE_GROUPS */ - can(Action.Delete, PublishedData); - } + can(Action.Delete, PublishedData); + } return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } - accessPolicyEndpointForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessPolicyEndpointForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); - if (user && user.currentGroups.some((g) => configuration().deleteGroups.includes(g))){ - /* + if ( + user && + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* / user that belongs to any of the group listed in DELETE_GROUPS */ - can(Action.Delete, Policy); - } else if (user && - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* + can(Action.Delete, Policy); + } else if ( + user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* / user that belongs to any of the group listed in ADMIN_GROUPS */ - can(Action.Update, Policy); - can(Action.Read, Policy); - can(Action.Create, Policy); - } + can(Action.Update, Policy); + can(Action.Read, Policy); + can(Action.Create, Policy); + } return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); - } + } - accessUserEndpointForUser(user:JWTUser){ + accessUserEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -206,7 +216,7 @@ export class CaslAbilityFactory { can(Action.UserCreateJwt, User); // ------------------------------------- - } else if (user) { + } else if (user) { /** /* authenticated users **/ @@ -227,7 +237,7 @@ export class CaslAbilityFactory { }); } - accessDatasetEndpointForUser(user:JWTUser){ + accessDatasetEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -255,8 +265,6 @@ export class CaslAbilityFactory { cannot(Action.DatasetDatablockUpdate, DatasetClass); // - cannot(Action.DatasetLogbookRead, DatasetClass); - - } else { if ( user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) @@ -265,19 +273,16 @@ export class CaslAbilityFactory { / user that belongs to any of the group listed in DELETE_GROUPS */ - can(Action.DatasetDelete, DatasetClass); // - can(Action.DatasetOrigdatablockDelete, DatasetClass); // - can(Action.DatasetDatablockDelete, DatasetClass); - } else { /* / user that does not belong to any of the group listed in DELETE_GROUPS */ - cannot(Action.DatasetDelete, DatasetClass); // - cannot(Action.DatasetOrigdatablockDelete, DatasetClass); @@ -310,9 +315,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - - - } else if ( user.currentGroups.some((g) => configuration().createDatasetPrivilegedGroups.includes(g), @@ -340,7 +342,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - } else if ( user.currentGroups.some((g) => configuration().createDatasetWithPidGroups.includes(g), @@ -369,7 +370,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - } else if ( user.currentGroups.some((g) => configuration().createDatasetGroups.includes(g), @@ -398,7 +398,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - } else if (user) { /** /* authenticated users @@ -422,9 +421,7 @@ export class CaslAbilityFactory { cannot(Action.DatasetDatablockUpdate, DatasetClass); // - can(Action.DatasetLogbookRead, DatasetClass); - } - } return build({ detectSubjectType: (item) => @@ -432,8 +429,8 @@ export class CaslAbilityFactory { }); } - accessDatasetDataInstanceForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessDatasetDataInstanceForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -458,8 +455,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockReadPublic, DatasetClass, { isPublished: true, }); - - } else { if ( user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) @@ -473,8 +468,6 @@ export class CaslAbilityFactory { can(Action.DatasetOrigdatablockDeleteAny, DatasetClass); // - can(Action.DatasetDatablockDeleteAny, DatasetClass); - - } if ( @@ -483,7 +476,7 @@ export class CaslAbilityFactory { /* / user that belongs to any of the group listed in ADMIN_GROUPS */ - + can(Action.DatasetCreateAny, DatasetClass); can(Action.DatasetReadAny, DatasetClass); can(Action.DatasetUpdateAny, DatasetClass); @@ -502,8 +495,6 @@ export class CaslAbilityFactory { can(Action.DatasetDatablockUpdateAny, DatasetClass); // ------------------------------------- can(Action.DatasetLogbookReadAny, DatasetClass); - - } else if ( user.currentGroups.some((g) => configuration().createDatasetPrivilegedGroups.includes(g), @@ -576,7 +567,6 @@ export class CaslAbilityFactory { can(Action.DatasetLogbookReadOwner, DatasetClass, { ownerGroup: { $in: user.currentGroups }, }); - } else if ( user.currentGroups.some((g) => configuration().createDatasetWithPidGroups.includes(g), @@ -658,7 +648,6 @@ export class CaslAbilityFactory { can(Action.DatasetLogbookReadOwner, DatasetClass, { ownerGroup: { $in: user.currentGroups }, }); - } else if ( user.currentGroups.some((g) => configuration().createDatasetGroups.includes(g), @@ -742,7 +731,6 @@ export class CaslAbilityFactory { can(Action.DatasetLogbookReadOwner, DatasetClass, { ownerGroup: { $in: user.currentGroups }, }); - } else if (user) { /** /* authenticated users @@ -792,9 +780,7 @@ export class CaslAbilityFactory { can(Action.DatasetLogbookReadOwner, DatasetClass, { ownerGroup: { $in: user.currentGroups }, }); - } - } return build({ detectSubjectType: (item) => @@ -802,7 +788,7 @@ export class CaslAbilityFactory { }); } - accessOrigDatablockEndpointForUser(user:JWTUser){ + accessOrigDatablockEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -832,7 +818,6 @@ export class CaslAbilityFactory { can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( user.currentGroups.some((g) => configuration().createDatasetPrivilegedGroups.includes(g), @@ -845,7 +830,6 @@ export class CaslAbilityFactory { can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( user.currentGroups.some((g) => configuration().createDatasetWithPidGroups.includes(g), @@ -859,7 +843,6 @@ export class CaslAbilityFactory { can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( user.currentGroups.some((g) => configuration().createDatasetGroups.includes(g), @@ -873,7 +856,6 @@ export class CaslAbilityFactory { can(Action.OrigdatablockRead, OrigDatablock); can(Action.OrigdatablockCreate, OrigDatablock); can(Action.OrigdatablockUpdate, OrigDatablock); - } else if (user) { /** /* authenticated users @@ -882,17 +864,15 @@ export class CaslAbilityFactory { can(Action.OrigdatablockRead, OrigDatablock); cannot(Action.OrigdatablockCreate, OrigDatablock); cannot(Action.OrigdatablockUpdate, OrigDatablock); - } return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); - } - accessOrigDatablockDataInstanceForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessOrigDatablockDataInstanceForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); if ( @@ -903,7 +883,7 @@ export class CaslAbilityFactory { */ can(Action.OrigdatablockDeleteAny, OrigDatablock); - } + } if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) ) { @@ -914,7 +894,6 @@ export class CaslAbilityFactory { can(Action.OrigdatablockReadAny, OrigDatablock); can(Action.OrigdatablockCreateAny, OrigDatablock); can(Action.OrigdatablockUpdateAny, OrigDatablock); - } else if ( user.currentGroups.some((g) => configuration().createDatasetPrivilegedGroups.includes(g), @@ -1009,10 +988,9 @@ export class CaslAbilityFactory { detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); - } - accessJobsEnpointForUser(user:JWTUser){ + accessJobsEnpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1034,7 +1012,6 @@ export class CaslAbilityFactory { can(Action.JobsRead, JobClass); can(Action.JobsCreate, JobClass); can(Action.JobsUpdate, JobClass); - } else if ( user.currentGroups.some((g) => configuration().createJobGroups.includes(g), @@ -1047,7 +1024,6 @@ export class CaslAbilityFactory { can(Action.JobsRead, JobClass); can(Action.JobsCreate, JobClass); can(Action.JobsUpdate, JobClass); - } else if ( user.currentGroups.some((g) => configuration().updateJobGroups.includes(g), @@ -1060,7 +1036,6 @@ export class CaslAbilityFactory { cannot(Action.JobsRead, JobClass); cannot(Action.JobsCreate, JobClass); can(Action.JobsUpdate, JobClass); - } else if (user) { /** * authenticated users @@ -1077,8 +1052,8 @@ export class CaslAbilityFactory { }); } - accessJobsDataInstanceForUser(user:JWTUser){ - const { can, cannot, build } = new AbilityBuilder( + accessJobsDataInstanceForUser(user: JWTUser) { + const { can, build } = new AbilityBuilder( createMongoAbility, ); if ( @@ -1133,7 +1108,7 @@ export class CaslAbilityFactory { }); } - accessProposalsEndpointForUser(user:JWTUser){ + accessProposalsEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1150,7 +1125,6 @@ export class CaslAbilityFactory { cannot(Action.ProposalsAttachmentCreate, ProposalClass); cannot(Action.ProposalsAttachmentUpdate, ProposalClass); cannot(Action.ProposalsAttachmentDelete, ProposalClass); - } else if ( user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) ) { @@ -1159,7 +1133,6 @@ export class CaslAbilityFactory { */ can(Action.ProposalsDelete, ProposalClass); - } else if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) ) { @@ -1175,7 +1148,6 @@ export class CaslAbilityFactory { can(Action.ProposalsAttachmentCreate, ProposalClass); can(Action.ProposalsAttachmentUpdate, ProposalClass); can(Action.ProposalsAttachmentDelete, ProposalClass); - } else if ( user.currentGroups.some((g) => { return configuration().proposalGroups.includes(g); @@ -1194,7 +1166,6 @@ export class CaslAbilityFactory { can(Action.ProposalsAttachmentUpdate, ProposalClass); can(Action.ProposalsAttachmentDelete, ProposalClass); cannot(Action.ProposalsDatasetRead, ProposalClass); - } else if (user) { /** * authenticated users @@ -1209,7 +1180,6 @@ export class CaslAbilityFactory { cannot(Action.ProposalsAttachmentUpdate, ProposalClass); cannot(Action.ProposalsAttachmentDelete, ProposalClass); can(Action.ProposalsDatasetRead, ProposalClass); - } return build({ detectSubjectType: (item) => @@ -1217,7 +1187,7 @@ export class CaslAbilityFactory { }); } - accessProposalsDataInstanceForUser(user:JWTUser){ + accessProposalsDataInstanceForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1324,7 +1294,7 @@ export class CaslAbilityFactory { }); } - accessSamplesEndpointForUser(user:JWTUser){ + accessSamplesEndpointForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1334,7 +1304,6 @@ export class CaslAbilityFactory { // unauthenticated users // ------------------------------------- - can(Action.SampleRead, SampleClass); cannot(Action.SampleCreate, SampleClass); cannot(Action.SampleUpdate, SampleClass); @@ -1344,7 +1313,6 @@ export class CaslAbilityFactory { cannot(Action.SampleAttachmentUpdate, SampleClass); cannot(Action.SampleAttachmentDelete, SampleClass); cannot(Action.SampleDatasetRead, SampleClass); - } else { // ------------------------------------- // authenticated users @@ -1359,14 +1327,12 @@ export class CaslAbilityFactory { can(Action.SampleDelete, SampleClass); can(Action.SampleAttachmentDelete, SampleClass); - } else { // ------------------------------------- // users that do not belong to any of the group listed in DELETE_GROUPS // ------------------------------------- cannot(Action.SampleDelete, SampleClass); - } if ( @@ -1384,7 +1350,6 @@ export class CaslAbilityFactory { can(Action.SampleAttachmentUpdate, SampleClass); can(Action.SampleAttachmentDelete, SampleClass); can(Action.SampleDatasetRead, SampleClass); - } else if ( user.currentGroups.some((g) => configuration().samplePrivilegedGroups.includes(g), @@ -1402,7 +1367,6 @@ export class CaslAbilityFactory { can(Action.SampleAttachmentUpdate, SampleClass); can(Action.SampleAttachmentDelete, SampleClass); can(Action.SampleDatasetRead, SampleClass); - } else if ( user.currentGroups.some((g) => configuration().sampleGroups.includes(g), @@ -1421,7 +1385,6 @@ export class CaslAbilityFactory { can(Action.SampleAttachmentUpdate, SampleClass); can(Action.SampleAttachmentDelete, SampleClass); can(Action.SampleDatasetRead, SampleClass); - } else { // ------------------------------------- // users with no elevated permissions @@ -1442,14 +1405,14 @@ export class CaslAbilityFactory { } } } - + return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } - accessSamplesDataInstanceForUser(user:JWTUser){ + accessSamplesDataInstanceForUser(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1612,7 +1575,7 @@ export class CaslAbilityFactory { }); } } - + return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, @@ -1665,4 +1628,3 @@ export class CaslAbilityFactory { }); } } - diff --git a/src/casl/decorators/check-policies.decorator.ts b/src/casl/decorators/check-policies.decorator.ts index dda83aa67..6ac4f3550 100644 --- a/src/casl/decorators/check-policies.decorator.ts +++ b/src/casl/decorators/check-policies.decorator.ts @@ -3,5 +3,5 @@ import { PolicyHandler } from "../interfaces/policy-handler.interface"; export const CHECK_POLICIES_KEY = "check_policy"; -export const CheckPolicies = ( ...handlers: PolicyHandler[]) => +export const CheckPolicies = (...handlers: PolicyHandler[]) => SetMetadata(CHECK_POLICIES_KEY, handlers); diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index c646ec418..08bfe8ba2 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -3,7 +3,6 @@ import { Reflector } from "@nestjs/core"; import { AppAbility, CaslAbilityFactory } from "../casl-ability.factory"; import { CHECK_POLICIES_KEY } from "../decorators/check-policies.decorator"; import { PolicyHandler } from "../interfaces/policy-handler.interface"; -import { request } from "https"; @Injectable() export class PoliciesGuard implements CanActivate { @@ -13,24 +12,25 @@ export class PoliciesGuard implements CanActivate { ) {} async canActivate(context: ExecutionContext): Promise { - const policyHandlers = - this.reflector.get( - CHECK_POLICIES_KEY, - context.getHandler(), - ) || []; + this.reflector.get( + CHECK_POLICIES_KEY, + context.getHandler(), + ) || []; const req = context.switchToHttp().getRequest(); const user = req.user; - const endpoint = req.route.path.split("/")[3] - - const ability = this.caslAbilityFactory.accessEndpointForUser(user, endpoint); + const endpoint = req.route.path.split("/")[3]; + + const ability = this.caslAbilityFactory.accessEndpointForUser( + user, + endpoint, + ); return policyHandlers.every((handler) => this.execPolicyHandler(handler, ability), ); } - private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) { if (typeof handler === "function") { const res = handler(ability); @@ -40,13 +40,3 @@ export class PoliciesGuard implements CanActivate { return handler.handle(ability); } } - - - - - - // Assuming that there is only one policy handler, extract the subject - //const policyHandler = policyHandlers[0]; - //const subject = this.extractSubjectFromPolicyHandler(policyHandler); - - \ No newline at end of file diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 6180a9476..1eb45083c 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -160,7 +160,8 @@ export class DatasetsController { ): IFilters { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -205,7 +206,8 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); let canDoAction = false; @@ -290,7 +292,8 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -355,7 +358,8 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -691,7 +695,8 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -769,7 +774,8 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -850,7 +856,8 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1098,7 +1105,8 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1177,7 +1185,8 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1227,7 +1236,8 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || @@ -1278,7 +1288,8 @@ export class DatasetsController { @Query("data") data: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); const datasetToUpdate = await this.datasetsService.findOne({ where: { pid: pid }, }); diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 0ecc13253..257ec925b 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -128,7 +128,8 @@ export class OrigDatablocksController { const origDatablockInstance = await this.generateOrigDatablockInstanceInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); let canDoAction = false; @@ -302,7 +303,8 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const parsedFilters: IFilters = JSON.parse(filter ?? "{}"); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { parsedFilters.where = parsedFilters.where ?? {}; @@ -363,7 +365,8 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { @@ -426,7 +429,8 @@ export class OrigDatablocksController { ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -467,7 +471,8 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -508,7 +513,8 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 3a5aae474..5e0ec3030 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -99,7 +99,8 @@ export class ProposalsController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); try { switch (group) { @@ -208,7 +209,8 @@ export class ProposalsController { mergedFilters.where = mergedFilters.where || {}; if (user) { - const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -407,7 +409,8 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -478,7 +481,8 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const facets = JSON.parse(filters.facets ?? "[]"); if (user) { - const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -869,7 +873,8 @@ export class ProposalsController { @Param("pid") proposalId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 87dcc4478..9abc40c1a 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -97,7 +97,8 @@ export class SamplesController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); try { switch (group) { @@ -198,7 +199,8 @@ export class SamplesController { /* eslint-disable @typescript-eslint/no-explicit-any */ const authorizationFilter: Record = { where: {} }; if (user) { - const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -356,7 +358,8 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -427,7 +430,8 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -870,7 +874,8 @@ export class SamplesController { @Param("id") sampleId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + const ability = + this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index a1d01a811..fdb6aea50 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -56,7 +56,9 @@ export class UserIdentitiesController { const authenticatedUser: JWTUser = request.user as JWTUser; const ability = - await this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); + await this.caslAbilityFactory.accessUserEndpointForUser( + authenticatedUser, + ); if ( !ability.can(Action.UserReadAny, User) && diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 433d8c9a6..a7c7c603d 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -65,7 +65,8 @@ export class UsersController { viewedUserSchema._id = viewedUserId; viewedUserSchema.id = viewedUserId; - const ability = this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); + const ability = + this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); // const authorized = actions.map( action => // ability.can(action, viewedUserSchema) // ) as Array; @@ -328,7 +329,8 @@ export class UsersController { const viewedUser = (await this.usersService.findById2JWTUser( id, )) as JWTUser; - const ability = this.caslAbilityFactory.accessDatasetEndpointForUser(viewedUser); + const ability = + this.caslAbilityFactory.accessDatasetEndpointForUser(viewedUser); const canCreateDataset = ability.can(Action.DatasetCreate, DatasetClass); diff --git a/test/UserAuthorization.js b/test/UserAuthorization.js index ea4f27ada..a8fb227f0 100644 --- a/test/UserAuthorization.js +++ b/test/UserAuthorization.js @@ -20,7 +20,7 @@ let accessTokenAdminIngestor = null, accessTokenArchiveManager = null, userIdArchiveManager = null; -describe.only("2300: User Authorization: test that user authorization are correct", () => { +describe("2300: User Authorization: test that user authorization are correct", () => { beforeEach(async() => { const loginResponseIngestor = await utils.getIdAndToken(appUrl, { username: "adminIngestor", From 5200b6a625698dde652c1e9b4e7cdbdf74813e76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:35:07 +0000 Subject: [PATCH 134/258] build(deps): bump @nestjs/core from 10.3.10 to 10.4.0 Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e71b8062e..44e7f2a09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,9 +2223,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.10.tgz", - "integrity": "sha512-ZbQ4jovQyzHtCGCrzK5NdtW1SYO2fHSsgSY1+/9WdruYCUra+JDkWEXgZ4M3Hv480Dl3OXehAmY1wCOojeMyMQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.0.tgz", + "integrity": "sha512-vNVJ0H8n3FyIxrFibgV2tRbjKsVm90u//kinE0m7s6ygv+KhnGMrQvWGX0kk9wbsZwRMW5JMpnBWDUS4wu4yPg==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", From 96122599d9ab0c9f7f26c3048431a71977774f91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:46:03 +0000 Subject: [PATCH 135/258] build(deps-dev): bump @nestjs/cli from 10.4.2 to 10.4.4 Bumps [@nestjs/cli](https://github.com/nestjs/nest-cli) from 10.4.2 to 10.4.4. - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/10.4.2...10.4.4) --- updated-dependencies: - dependency-name: "@nestjs/cli" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44e7f2a09..4c16d6a8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2099,9 +2099,9 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.2.tgz", - "integrity": "sha512-fQexIfLHfp6GUgX+CO4fOg+AEwV5ox/LHotQhyZi9wXUQDyIqS0NTTbumr//62EcX35qV4nU0359nYnuEdzG+A==", + "version": "10.4.4", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.4.tgz", + "integrity": "sha512-WKERbSZJGof0+9XeeMmWnb/9FpNxogcB5eTJTHjc9no0ymdTw3jTzT+KZL9iC/hGqBpuomDLaNFCYbAOt29nBw==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", @@ -2121,7 +2121,7 @@ "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.92.1", + "webpack": "5.93.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -13942,9 +13942,9 @@ } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", From b1933488bce0699b9349c8b05878597937a8378e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:56:40 +0000 Subject: [PATCH 136/258] build(deps-dev): bump @nestjs/testing from 10.3.10 to 10.4.0 Bumps [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c16d6a8f..141ccb8aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2476,9 +2476,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.10.tgz", - "integrity": "sha512-i3HAtVQJijxNxJq1k39aelyJlyEIBRONys7IipH/4r8W0J+M1V+y5EKDOyi4j1SdNSb/vmNyWpZ2/ewZjl3kRA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.0.tgz", + "integrity": "sha512-oAQe3Yb4/JlHtsBcKmueEvPZDoONp7LsNwGnMAeyhoBLuPBXDhZnNgMY2UtT4FfNmudBQBKR/vq/fOQRax/4Hg==", "dev": true, "dependencies": { "tslib": "2.6.3" From 80731dd1133881829daf1c8fe062cb5ef2c31cbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:07:17 +0000 Subject: [PATCH 137/258] build(deps): bump @nestjs/platform-express from 10.3.10 to 10.4.0 Bumps [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/platform-express) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 141ccb8aa..d901d8b99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2333,9 +2333,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.10.tgz", - "integrity": "sha512-wK2ow3CZI2KFqWeEpPmoR300OB6BcBLxARV1EiClJLCj4S1mZsoCmS0YWgpk3j1j6mo0SI8vNLi/cC2iZPEPQA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.0.tgz", + "integrity": "sha512-DxrNsqywNVRs+4tmEXKNotumXEEGw+EvG2f9MyvDnHYU7tCZAT9ZsVnT6waM3lrjSmyjMaae8JuiMI8bnZj44g==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", From e5bbe5899a69fdc66e1f8724e7c42741feb2f87b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:17:55 +0000 Subject: [PATCH 138/258] build(deps-dev): bump @types/node from 22.1.0 to 22.2.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.1.0 to 22.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d901d8b99..5092d9c9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3001,9 +3001,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", "dependencies": { "undici-types": "~6.13.0" } From ae5c5a3405c9f795633812a5d972dd529e4c019f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:28:52 +0000 Subject: [PATCH 139/258] build(deps-dev): bump mocha from 10.7.0 to 10.7.3 Bumps [mocha](https://github.com/mochajs/mocha) from 10.7.0 to 10.7.3. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v10.7.0...v10.7.3) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5092d9c9c..46d5ce28f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10157,9 +10157,9 @@ } }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", From fea164d6bd1e2c0750d3c8bf13ea6f5ea7cd5bab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:39:21 +0000 Subject: [PATCH 140/258] build(deps): bump @nestjs/common from 10.3.10 to 10.4.0 Bumps [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) from 10.3.10 to 10.4.0. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.0/packages/common) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46d5ce28f..b4b01810c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2181,9 +2181,9 @@ } }, "node_modules/@nestjs/common": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.10.tgz", - "integrity": "sha512-H8k0jZtxk1IdtErGDmxFRy0PfcOAUg41Prrqpx76DQusGGJjsaovs1zjXVD1rZWaVYchfT1uczJ6L4Kio10VNg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.0.tgz", + "integrity": "sha512-cGQJBMypG1qf0h31dvIYSffr/8+JhFd7qScJ4mqgF5HKT69WveW14zQcxavXzXI/LOE4vUvCu3QBeqcRBIs/9A==", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.3", From c07d5665f2b7d06fe6977d64eaa0ff92297a3bf0 Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Fri, 16 Aug 2024 10:37:28 +0200 Subject: [PATCH 141/258] remove empty file --- test/config/jobconfig.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 test/config/jobconfig.json diff --git a/test/config/jobconfig.json b/test/config/jobconfig.json deleted file mode 100755 index e69de29bb..000000000 From 9a1e643c0c3a096bc072bd023b8eb9f2b67edb47 Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:28:20 +0200 Subject: [PATCH 142/258] Rename constant as per Google TypeScript convention --- src/users/interceptors/create-user-settings.interceptor.ts | 4 ++-- .../interceptors/default-user-settings.interceptor.ts | 7 +++---- src/users/schemas/user-settings.schema.ts | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/users/interceptors/create-user-settings.interceptor.ts b/src/users/interceptors/create-user-settings.interceptor.ts index 2ecb7bbc0..e22d4f881 100644 --- a/src/users/interceptors/create-user-settings.interceptor.ts +++ b/src/users/interceptors/create-user-settings.interceptor.ts @@ -8,7 +8,7 @@ import { import { Observable, tap } from "rxjs"; import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; import { UsersService } from "../users.service"; -import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; @Injectable() export class CreateUserSettingsInterceptor implements NestInterceptor { @@ -35,7 +35,7 @@ export class CreateUserSettingsInterceptor implements NestInterceptor { const createUserSettingsDto: CreateUserSettingsDto = { userId, columns: [], - filters: kDefaultFilters, + filters: FILTER_CONFIGS, conditions: [], }; return this.usersService.createUserSettings( diff --git a/src/users/interceptors/default-user-settings.interceptor.ts b/src/users/interceptors/default-user-settings.interceptor.ts index f9eb647f1..61b8049e9 100644 --- a/src/users/interceptors/default-user-settings.interceptor.ts +++ b/src/users/interceptors/default-user-settings.interceptor.ts @@ -5,10 +5,9 @@ import { Logger, NestInterceptor, } from "@nestjs/common"; -import { map, Observable, tap } from "rxjs"; -import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; +import { map, Observable } from "rxjs"; import { UsersService } from "../users.service"; -import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; @Injectable() @@ -23,7 +22,7 @@ export class DefaultUserSettingsInterceptor implements NestInterceptor { Logger.log("DefaultUserSettingsInterceptor"); const defaultUserSettings: UpdateUserSettingsDto = { columns: [], - filters: kDefaultFilters, + filters: FILTER_CONFIGS, conditions: [], }; console.log(defaultUserSettings); diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index fc56df5af..edceaa30d 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -30,7 +30,7 @@ export interface ScientificCondition { operator: string; } -export const kDefaultFilters: FilterConfig[] = [ +export const FILTER_CONFIGS: FilterConfig[] = [ { type: "LocationFilterComponent", visible: true }, { type: "PidFilterComponent", visible: true }, { type: "PidFilterContainsComponent", visible: false }, @@ -83,12 +83,12 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: kDefaultFilters, + default: FILTER_CONFIGS, description: "Array of filters the user has set", }) @Prop({ type: [{ type: Object }], - default: kDefaultFilters, + default: FILTER_CONFIGS, }) filters: FilterConfig[]; From a0ea170f6442cc96d5c76232088a7d6c7b9c8bcc Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:42:12 +0200 Subject: [PATCH 143/258] Load default filters config from a json file --- src/config/default-filters.config.json | 11 +++++++++++ src/users/schemas/user-settings.schema.ts | 13 ++----------- 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 src/config/default-filters.config.json diff --git a/src/config/default-filters.config.json b/src/config/default-filters.config.json new file mode 100644 index 000000000..848bb1970 --- /dev/null +++ b/src/config/default-filters.config.json @@ -0,0 +1,11 @@ +[ + { "type": "LocationFilterComponent", "visible": true }, + { "type": "PidFilterComponent", "visible": true }, + { "type": "PidFilterContainsComponent", "visible": false }, + { "type": "PidFilterStartsWithComponent", "visible": false }, + { "type": "GroupFilterComponent", "visible": true }, + { "type": "TypeFilterComponent", "visible": true }, + { "type": "KeywordFilterComponent", "visible": true }, + { "type": "DateRangeFilterComponent", "visible": true }, + { "type": "TextFilterComponent", "visible": true } +] \ No newline at end of file diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index edceaa30d..9cfe2cae2 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -2,6 +2,7 @@ import * as mongoose from "mongoose"; import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; import { ApiProperty } from "@nestjs/swagger"; import { Document } from "mongoose"; +import filterConfigs from "../../config/default-filters.config.json"; export type UserSettingsDocument = UserSettings & Document; @@ -30,17 +31,7 @@ export interface ScientificCondition { operator: string; } -export const FILTER_CONFIGS: FilterConfig[] = [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, -]; +export const FILTER_CONFIGS: FilterConfig[] = filterConfigs as FilterConfig[]; @Schema({ collection: "UserSetting", From 5acacbe8f3b8a8b0dfbc7945c5bf517bd63a8615 Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:44:46 +0200 Subject: [PATCH 144/258] Remove default user settings POST entry point --- src/users/users.controller.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index b797ea2b4..56e415374 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -329,26 +329,6 @@ export class UsersController { return Promise.resolve(new UserSettings()); } - @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => - ability.can(Action.UserCreateAny, User), - ) - @Post("/settings/default") - async postDefaultSettings( - @Req() request: Request, - @Body() createUserSettingsDto: CreateUserSettingsDto, - ): Promise { - await this.checkUserAuthorization( - request, - [Action.UserCreateAny], - createUserSettingsDto.userId, - ); - return this.usersService.createUserSettings( - "default", - createUserSettingsDto, - ); - } - @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => { return ( From 8b0a54703229e154894283300d58f7a175ce24a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:20:32 +0000 Subject: [PATCH 145/258] build(deps): bump @nestjs/common from 10.4.0 to 10.4.1 Bumps [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) from 10.4.0 to 10.4.1. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.1/packages/common) --- updated-dependencies: - dependency-name: "@nestjs/common" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4b01810c..510a56c29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2181,9 +2181,9 @@ } }, "node_modules/@nestjs/common": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.0.tgz", - "integrity": "sha512-cGQJBMypG1qf0h31dvIYSffr/8+JhFd7qScJ4mqgF5HKT69WveW14zQcxavXzXI/LOE4vUvCu3QBeqcRBIs/9A==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.1.tgz", + "integrity": "sha512-4CkrDx0s4XuWqFjX8WvOFV7Y6RGJd0P2OBblkhZS7nwoctoSuW5pyEa8SWak6YHNGrHRpFb6ymm5Ai4LncwRVA==", "dependencies": { "iterare": "1.2.1", "tslib": "2.6.3", From 8145e6d7d04b35719c8d9e2eaf578efed9598dc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:31:31 +0000 Subject: [PATCH 146/258] build(deps): bump @nestjs/platform-express from 10.4.0 to 10.4.1 Bumps [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) from 10.4.0 to 10.4.1. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.1/packages/platform-express) --- updated-dependencies: - dependency-name: "@nestjs/platform-express" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 510a56c29..27141bf3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2333,9 +2333,9 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.0.tgz", - "integrity": "sha512-DxrNsqywNVRs+4tmEXKNotumXEEGw+EvG2f9MyvDnHYU7tCZAT9ZsVnT6waM3lrjSmyjMaae8JuiMI8bnZj44g==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.1.tgz", + "integrity": "sha512-ccfqIDAq/bg1ShLI5KGtaLaYGykuAdvCi57ohewH7eKJSIpWY1DQjbgKlFfXokALYUq1YOMGqjeZ244OWHfDQg==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", From d3e0f079b14e5c71328adf2104c12fbe11442cda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:42:13 +0000 Subject: [PATCH 147/258] build(deps): bump axios from 1.6.2 to 1.7.4 Bumps [axios](https://github.com/axios/axios) from 1.6.2 to 1.7.4. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.6.2...v1.7.4) --- updated-dependencies: - dependency-name: axios dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27141bf3b..d093d791e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4026,11 +4026,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } From 22469ebfbc65542c08a4c44d8ba713b89d03c9de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:53:03 +0000 Subject: [PATCH 148/258] build(deps): bump @nestjs/core from 10.4.0 to 10.4.1 Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 10.4.0 to 10.4.1. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.1/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d093d791e..e3db33700 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,9 +2223,9 @@ } }, "node_modules/@nestjs/core": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.0.tgz", - "integrity": "sha512-vNVJ0H8n3FyIxrFibgV2tRbjKsVm90u//kinE0m7s6ygv+KhnGMrQvWGX0kk9wbsZwRMW5JMpnBWDUS4wu4yPg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.1.tgz", + "integrity": "sha512-9I1WdfOBCCHdUm+ClBJupOuZQS6UxzIWHIq6Vp1brAA5ZKl/Wq6BVwSsbnUJGBy3J3PM2XHmR0EQ4fwX3nR7lA==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", From 5ad8a23cdb5ec7b52761d312ffad07eef1bc24dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:03:46 +0000 Subject: [PATCH 149/258] build(deps-dev): bump @nestjs/schematics from 10.1.3 to 10.1.4 Bumps [@nestjs/schematics](https://github.com/nestjs/schematics) from 10.1.3 to 10.1.4. - [Release notes](https://github.com/nestjs/schematics/releases) - [Changelog](https://github.com/nestjs/schematics/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/schematics/compare/10.1.3...10.1.4) --- updated-dependencies: - dependency-name: "@nestjs/schematics" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3db33700..856831d5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2353,9 +2353,9 @@ } }, "node_modules/@nestjs/schematics": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.3.tgz", - "integrity": "sha512-aLJ4Nl/K/u6ZlgLa0NjKw5CuBOIgc6vudF42QvmGueu5FaMGM6IJrAuEvB5T2kr0PAfVwYmDFBBHCWdYhTw4Tg==", + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.1.4.tgz", + "integrity": "sha512-QpY8ez9cTvXXPr3/KBrtSgXQHMSV6BkOUYy2c2TTe6cBqriEdGnCYqGl8cnfrQl3632q3lveQPaZ/c127dHsEw==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", From 3d9051de0f5b21775880dc1be261d81bc0a1af2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:14:44 +0000 Subject: [PATCH 150/258] build(deps-dev): bump @nestjs/testing from 10.4.0 to 10.4.1 Bumps [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) from 10.4.0 to 10.4.1. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v10.4.1/packages/testing) --- updated-dependencies: - dependency-name: "@nestjs/testing" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 856831d5d..07416b2f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2476,9 +2476,9 @@ } }, "node_modules/@nestjs/testing": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.0.tgz", - "integrity": "sha512-oAQe3Yb4/JlHtsBcKmueEvPZDoONp7LsNwGnMAeyhoBLuPBXDhZnNgMY2UtT4FfNmudBQBKR/vq/fOQRax/4Hg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.4.1.tgz", + "integrity": "sha512-pR+su5+YGqCLH0RhhVkPowQK7FCORU0/PWAywPK7LScAOtD67ZoviZ7hAU4vnGdwkg4HCB0D7W8Bkg19CGU8Xw==", "dev": true, "dependencies": { "tslib": "2.6.3" From df1c928d11de3fbc01bc3ca84d6c47a46a3493e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:25:35 +0000 Subject: [PATCH 151/258] build(deps-dev): bump @types/node from 22.2.0 to 22.4.1 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.2.0 to 22.4.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07416b2f7..f8e229ff5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3001,11 +3001,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", - "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "version": "22.4.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.1.tgz", + "integrity": "sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==", "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@types/node-fetch": { @@ -13484,9 +13484,9 @@ } }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.19.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", + "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==" }, "node_modules/universalify": { "version": "2.0.0", From ff0f5ab9f874db6e1d75ce12c2936ad71dc7997f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:36:25 +0000 Subject: [PATCH 152/258] build(deps): bump @nestjs/axios from 3.0.2 to 3.0.3 Bumps [@nestjs/axios](https://github.com/nestjs/axios) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/nestjs/axios/releases) - [Changelog](https://github.com/nestjs/axios/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/axios/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: "@nestjs/axios" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f8e229ff5..c82f56457 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2089,9 +2089,9 @@ } }, "node_modules/@nestjs/axios": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.2.tgz", - "integrity": "sha512-Z6GuOUdNQjP7FX+OuV2Ybyamse+/e0BFdTWBX5JxpBDKA+YkdLynDgG6HTF04zy6e9zPa19UX0WA2VDoehwhXQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.3.tgz", + "integrity": "sha512-h6TCn3yJwD6OKqqqfmtRS5Zo4E46Ip2n+gK1sqwzNBC+qxQ9xpCu+ODVRFur6V3alHSCSBxb3nNtt73VEdluyA==", "peerDependencies": { "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", "axios": "^1.3.1", From 56757450edd0b51116d336cfdf54e1c9e7279eb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:47:21 +0000 Subject: [PATCH 153/258] build(deps): bump mongoose from 8.5.2 to 8.5.3 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.2 to 8.5.3. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.5.2...8.5.3) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c82f56457..99371d1ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10393,9 +10393,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.2.tgz", - "integrity": "sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.3.tgz", + "integrity": "sha512-OubSDbsAclDFGHjV82MsKyIGQWFc42Ot1l+0dhRS6U9xODM7rm/ES/WpOQd8Ds9j0Mx8QzxZtrSCnBh6o9wUqw==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From dd8230269a6579b7251659d9ce3f0516bd448538 Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Tue, 20 Aug 2024 09:59:51 +0200 Subject: [PATCH 154/258] address changes requested in the PR --- src/casl/casl-ability.factory.ts | 1266 ++++++++--------- src/casl/guards/policies.guard.ts | 2 +- src/datasets/datasets.controller.ts | 22 +- .../origdatablocks.controller.ts | 12 +- src/policies/policies.controller.ts | 2 +- src/proposals/proposals.controller.ts | 10 +- src/samples/samples.controller.ts | 10 +- src/users/user-identities.controller.ts | 2 +- src/users/users.controller.ts | 4 +- 9 files changed, 665 insertions(+), 665 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index c98c9ba4b..d821225e3 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -54,190 +54,38 @@ export type AppAbility = MongoAbility; @Injectable() export class CaslAbilityFactory { - accessEndpointForUser(user: JWTUser, subject: string) { + endpointAccess(user: JWTUser, subject: string) { switch (subject) { case "datasets": - return this.accessDatasetEndpointForUser(user); + return this.datasetEndpointAccess(user); case "elastic-search": - return this.accessElasticSearchEndpointForUser(user); + return this.elasticSearchEndpointAccess(user); case "jobs": - return this.accessJobsEnpointForUser(user); + return this.jobsEndpointAccess(user); case "instruments": - return this.accessInstrumentEndpointForUser(user); + return this.instrumentEndpointAccess(user); case "logbooks": - return this.accessLogbookEndpointForUser(user); + return this.logbookEndpointAccess(user); case "origdatablocks": - return this.accessOrigDatablockEndpointForUser(user); + return this.origDatablockEndpointAccess(user); case "policies": - return this.accessPolicyEndpointForUser(user); + return this.policyEndpointAccess(user); case "proposals": - return this.accessProposalsEndpointForUser(user); + return this.proposalsEndpointAccess(user); case "publisheddata": - return this.accessPublishedDataEndpointForUser(user); + return this.publishedDataEndpointAccess(user); case "samples": - return this.accessSamplesEndpointForUser(user); + return this.samplesEndpointAccess(user); case "users": - return this.accessUserEndpointForUser(user); case "useridentities": - return this.accessUserEndpointForUser(user); + return this.userEndpointAccess(user); default: throw new Error(` No endpoint access policies defined for subject: ${subject}`); } } - accessElasticSearchEndpointForUser(user: JWTUser) { - const { can, build } = new AbilityBuilder( - createMongoAbility, - ); - - if ( - user && - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in ADMIN_GROUPS - */ - can(Action.Manage, ElasticSearchActions); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessLogbookEndpointForUser(user: JWTUser) { - const { can, build } = new AbilityBuilder( - createMongoAbility, - ); - - if (user) { - /* - / authenticated user - */ - can(Action.Read, Logbook); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessPublishedDataEndpointForUser(user: JWTUser) { - const { can, build } = new AbilityBuilder( - createMongoAbility, - ); - if (user) { - can(Action.Read, PublishedData); - can(Action.Update, PublishedData); - can(Action.Create, PublishedData); - } - - if ( - user && - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ - can(Action.Delete, PublishedData); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessPolicyEndpointForUser(user: JWTUser) { - const { can, build } = new AbilityBuilder( - createMongoAbility, - ); - if ( - user && - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ - can(Action.Delete, Policy); - } else if ( - user && - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in ADMIN_GROUPS - */ - - can(Action.Update, Policy); - can(Action.Read, Policy); - can(Action.Create, Policy); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessUserEndpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - - if (!user) { - /** - /* unauthenticated users - **/ - - cannot(Action.UserReadOwn, User); - cannot(Action.UserCreateOwn, User); - cannot(Action.UserUpdateOwn, User); - cannot(Action.UserDeleteOwn, User); - cannot(Action.UserReadAny, User); - cannot(Action.UserCreateAny, User); - cannot(Action.UserUpdateAny, User); - cannot(Action.UserDeleteAny, User); - } else { - if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in ADMIN_GROUPS - */ - - // can(Action.ReadAll, UserIdentity); NOT used? - - // ------------------------------------- - // user endpoint, including useridentity - can(Action.UserReadAny, User); - can(Action.UserReadOwn, User); - can(Action.UserCreateAny, User); - can(Action.UserUpdateAny, User); - can(Action.UserDeleteAny, User); - can(Action.UserCreateJwt, User); - - // ------------------------------------- - } else if (user) { - /** - /* authenticated users - **/ - cannot(Action.UserReadAny, User); - cannot(Action.UserCreateAny, User); - cannot(Action.UserUpdateAny, User); - cannot(Action.UserDeleteAny, User); - cannot(Action.UserCreateJwt, User); - } - can(Action.UserReadOwn, User, { _id: user._id }); - can(Action.UserCreateOwn, User, { _id: user._id }); - can(Action.UserUpdateOwn, User, { _id: user._id }); - can(Action.UserDeleteOwn, User, { _id: user._id }); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessDatasetEndpointForUser(user: JWTUser) { + datasetEndpointAccess(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -352,76 +200,615 @@ export class CaslAbilityFactory { /* users belonging to CREATE_DATASET_WITH_PID_GROUPS **/ - can(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - can(Action.DatasetUpdate, DatasetClass); - // - - can(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - can(Action.DatasetAttachmentUpdate, DatasetClass); - can(Action.DatasetAttachmentDelete, DatasetClass); - // - - can(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - can(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - can(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - can(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); - } else if ( - user.currentGroups.some((g) => - configuration().createDatasetGroups.includes(g), - ) || - configuration().createDatasetGroups.includes("#all") + can(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + can(Action.DatasetUpdate, DatasetClass); + // - + can(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + can(Action.DatasetAttachmentUpdate, DatasetClass); + can(Action.DatasetAttachmentDelete, DatasetClass); + // - + can(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + can(Action.DatasetOrigdatablockUpdate, DatasetClass); + // - + can(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + can(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetGroups.includes(g), + ) || + configuration().createDatasetGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_GROUPS + **/ + + can(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + can(Action.DatasetUpdate, DatasetClass); + // - + can(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + can(Action.DatasetAttachmentUpdate, DatasetClass); + can(Action.DatasetAttachmentDelete, DatasetClass); + // - + can(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + can(Action.DatasetOrigdatablockUpdate, DatasetClass); + // - + can(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + can(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); + } else if (user) { + /** + /* authenticated users + **/ + + cannot(Action.DatasetCreate, DatasetClass); + can(Action.DatasetRead, DatasetClass); + cannot(Action.DatasetUpdate, DatasetClass); + // - + cannot(Action.DatasetAttachmentCreate, DatasetClass); + can(Action.DatasetAttachmentRead, DatasetClass); + cannot(Action.DatasetAttachmentUpdate, DatasetClass); + cannot(Action.DatasetAttachmentDelete, DatasetClass); + // - + cannot(Action.DatasetOrigdatablockCreate, DatasetClass); + can(Action.DatasetOrigdatablockRead, DatasetClass); + cannot(Action.DatasetOrigdatablockUpdate, DatasetClass); + // - + cannot(Action.DatasetDatablockCreate, DatasetClass); + can(Action.DatasetDatablockRead, DatasetClass); + cannot(Action.DatasetDatablockUpdate, DatasetClass); + // - + can(Action.DatasetLogbookRead, DatasetClass); + } + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + elasticSearchEndpointAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + + if ( + user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + can(Action.Manage, ElasticSearchActions); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + instrumentEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + cannot(Action.InstrumentRead, Instrument); + cannot(Action.InstrumentCreate, Instrument); + cannot(Action.InstrumentUpdate, Instrument); + cannot(Action.InstrumentDelete, Instrument); + } else { + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + * user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.InstrumentDelete, Instrument); + } else { + cannot(Action.InstrumentDelete, Instrument); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /** + * authenticated users belonging to any of the group listed in ADMIN_GROUPS + */ + + can(Action.InstrumentRead, Instrument); + can(Action.InstrumentCreate, Instrument); + can(Action.InstrumentUpdate, Instrument); + } else { + can(Action.InstrumentRead, Instrument); + cannot(Action.InstrumentCreate, Instrument); + cannot(Action.InstrumentUpdate, Instrument); + } + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + jobsEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (!user) { + /** + * unauthenticated users + */ + + cannot(Action.JobsRead, JobClass); + cannot(Action.JobsCreate, JobClass); + cannot(Action.JobsUpdate, JobClass); + } else if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /** + * authenticated users belonging to any of the group listed in ADMIN_GROUPS + */ + + can(Action.JobsRead, JobClass); + can(Action.JobsCreate, JobClass); + can(Action.JobsUpdate, JobClass); + } else if ( + user.currentGroups.some((g) => + configuration().createJobGroups.includes(g), + ) + ) { + /** + * authenticated users belonging to any of the group listed in CREATE_JOBS_GROUPS + */ + + can(Action.JobsRead, JobClass); + can(Action.JobsCreate, JobClass); + can(Action.JobsUpdate, JobClass); + } else if ( + user.currentGroups.some((g) => + configuration().updateJobGroups.includes(g), + ) + ) { + /** + * authenticated users belonging to any of the group listed in UPDATE_JOBS_GROUPS + */ + + cannot(Action.JobsRead, JobClass); + cannot(Action.JobsCreate, JobClass); + can(Action.JobsUpdate, JobClass); + } else if (user) { + /** + * authenticated users + */ + + can(Action.JobsRead, JobClass); + cannot(Action.JobsCreate, JobClass); + cannot(Action.JobsUpdate, JobClass); + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + logbookEndpointAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (user) { + /* + / authenticated user + */ + can(Action.Read, Logbook); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + origDatablockEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.OrigdatablockDelete, OrigDatablock); + } else { + /* + / user that does not belong to any of the group listed in DELETE_GROUPS + */ + + cannot(Action.OrigdatablockDelete, OrigDatablock); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetPrivilegedGroups.includes(g), + ) + ) { + /** + /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetWithPidGroups.includes(g), + ) || + configuration().createDatasetWithPidGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_WITH_PID_GROUPS + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + } else if ( + user.currentGroups.some((g) => + configuration().createDatasetGroups.includes(g), + ) || + configuration().createDatasetGroups.includes("#all") + ) { + /** + /* users belonging to CREATE_DATASET_GROUPS + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + can(Action.OrigdatablockCreate, OrigDatablock); + can(Action.OrigdatablockUpdate, OrigDatablock); + } else if (user) { + /** + /* authenticated users + **/ + + can(Action.OrigdatablockRead, OrigDatablock); + cannot(Action.OrigdatablockCreate, OrigDatablock); + cannot(Action.OrigdatablockUpdate, OrigDatablock); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + policyEndpointAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + if ( + user && + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + can(Action.Delete, Policy); + } else if ( + user && + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ + + can(Action.Update, Policy); + can(Action.Read, Policy); + can(Action.Create, Policy); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + proposalsEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + if (!user) { + /** + * unauthenticated users + */ + + can(Action.ProposalsRead, ProposalClass); + cannot(Action.ProposalsCreate, ProposalClass); + cannot(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + cannot(Action.ProposalsAttachmentCreate, ProposalClass); + cannot(Action.ProposalsAttachmentUpdate, ProposalClass); + cannot(Action.ProposalsAttachmentDelete, ProposalClass); + } else if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + + can(Action.ProposalsDelete, ProposalClass); + } else if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + /** + * authenticated users belonging to any of the group listed in ADMIN_GROUPS + */ + + can(Action.ProposalsRead, ProposalClass); + can(Action.ProposalsCreate, ProposalClass); + can(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + can(Action.ProposalsAttachmentCreate, ProposalClass); + can(Action.ProposalsAttachmentUpdate, ProposalClass); + can(Action.ProposalsAttachmentDelete, ProposalClass); + } else if ( + user.currentGroups.some((g) => { + return configuration().proposalGroups.includes(g); + }) + ) { + /** + * authenticated users belonging to any of the group listed in PROPOSAL_GROUPS + */ + + can(Action.ProposalsRead, ProposalClass); + can(Action.ProposalsCreate, ProposalClass); + can(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + can(Action.ProposalsAttachmentCreate, ProposalClass); + can(Action.ProposalsAttachmentUpdate, ProposalClass); + can(Action.ProposalsAttachmentDelete, ProposalClass); + cannot(Action.ProposalsDatasetRead, ProposalClass); + } else if (user) { + /** + * authenticated users + */ + + can(Action.ProposalsRead, ProposalClass); + cannot(Action.ProposalsCreate, ProposalClass); + cannot(Action.ProposalsUpdate, ProposalClass); + cannot(Action.ProposalsDelete, ProposalClass); + can(Action.ProposalsAttachmentRead, ProposalClass); + cannot(Action.ProposalsAttachmentCreate, ProposalClass); + cannot(Action.ProposalsAttachmentUpdate, ProposalClass); + cannot(Action.ProposalsAttachmentDelete, ProposalClass); + can(Action.ProposalsDatasetRead, ProposalClass); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + publishedDataEndpointAccess(user: JWTUser) { + const { can, build } = new AbilityBuilder( + createMongoAbility, + ); + if (user) { + can(Action.Read, PublishedData); + can(Action.Update, PublishedData); + can(Action.Create, PublishedData); + } + + if ( + user && + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + /* + / user that belongs to any of the group listed in DELETE_GROUPS + */ + can(Action.Delete, PublishedData); + } + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + samplesEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + // ------------------------------------- + // unauthenticated users + // ------------------------------------- + + can(Action.SampleRead, SampleClass); + cannot(Action.SampleCreate, SampleClass); + cannot(Action.SampleUpdate, SampleClass); + cannot(Action.SampleDelete, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + cannot(Action.SampleAttachmentCreate, SampleClass); + cannot(Action.SampleAttachmentUpdate, SampleClass); + cannot(Action.SampleAttachmentDelete, SampleClass); + cannot(Action.SampleDatasetRead, SampleClass); + } else { + // ------------------------------------- + // authenticated users + // ------------------------------------- + + if ( + user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) + ) { + // ------------------------------------- + // users that belong to any of the group listed in DELETE_GROUPS + // ------------------------------------- + + can(Action.SampleDelete, SampleClass); + can(Action.SampleAttachmentDelete, SampleClass); + } else { + // ------------------------------------- + // users that do not belong to any of the group listed in DELETE_GROUPS + // ------------------------------------- + + cannot(Action.SampleDelete, SampleClass); + } + + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) + ) { + // ------------------------------------- + // users belonging to any of the group listed in ADMIN_GROUPS + // ------------------------------------- + + can(Action.SampleRead, SampleClass); + can(Action.SampleCreate, SampleClass); + can(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + can(Action.SampleAttachmentCreate, SampleClass); + can(Action.SampleAttachmentUpdate, SampleClass); + can(Action.SampleAttachmentDelete, SampleClass); + can(Action.SampleDatasetRead, SampleClass); + } else if ( + user.currentGroups.some((g) => + configuration().samplePrivilegedGroups.includes(g), + ) + ) { + // ------------------------------------- + // users belonging to any of the group listed in SAMPLE_GROUPS + // + + can(Action.SampleRead, SampleClass); + can(Action.SampleCreate, SampleClass); + can(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + can(Action.SampleAttachmentCreate, SampleClass); + can(Action.SampleAttachmentUpdate, SampleClass); + can(Action.SampleAttachmentDelete, SampleClass); + can(Action.SampleDatasetRead, SampleClass); + } else if ( + user.currentGroups.some((g) => + configuration().sampleGroups.includes(g), + ) || + configuration().sampleGroups.includes("#all") + ) { + // ------------------------------------- + // users belonging to any of the group listed in SAMPLE_GROUPS + // + + can(Action.SampleRead, SampleClass); + can(Action.SampleCreate, SampleClass); + can(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + can(Action.SampleAttachmentCreate, SampleClass); + can(Action.SampleAttachmentUpdate, SampleClass); + can(Action.SampleAttachmentDelete, SampleClass); + can(Action.SampleDatasetRead, SampleClass); + } else { + // ------------------------------------- + // users with no elevated permissions + // ------------------------------------- + + can(Action.SampleRead, SampleClass); + cannot(Action.SampleCreate, SampleClass); + cannot(Action.SampleUpdate, SampleClass); + can(Action.SampleAttachmentRead, SampleClass); + cannot(Action.SampleAttachmentCreate, SampleClass); + cannot(Action.SampleAttachmentUpdate, SampleClass); + if ( + !user.currentGroups.some((g) => + configuration().deleteGroups.includes(g), + ) + ) { + cannot(Action.SampleAttachmentDelete, SampleClass); + } + } + } + + return build({ + detectSubjectType: (item) => + item.constructor as ExtractSubjectType, + }); + } + + userEndpointAccess(user: JWTUser) { + const { can, cannot, build } = new AbilityBuilder( + createMongoAbility, + ); + + if (!user) { + /** + /* unauthenticated users + **/ + + cannot(Action.UserReadOwn, User); + cannot(Action.UserCreateOwn, User); + cannot(Action.UserUpdateOwn, User); + cannot(Action.UserDeleteOwn, User); + cannot(Action.UserReadAny, User); + cannot(Action.UserCreateAny, User); + cannot(Action.UserUpdateAny, User); + cannot(Action.UserDeleteAny, User); + } else { + if ( + user.currentGroups.some((g) => configuration().adminGroups.includes(g)) ) { - /** - /* users belonging to CREATE_DATASET_GROUPS - **/ + /* + / user that belongs to any of the group listed in ADMIN_GROUPS + */ - can(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - can(Action.DatasetUpdate, DatasetClass); - // - - can(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - can(Action.DatasetAttachmentUpdate, DatasetClass); - can(Action.DatasetAttachmentDelete, DatasetClass); - // - - can(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - can(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - can(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - can(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); + // can(Action.ReadAll, UserIdentity); NOT used? + + // ------------------------------------- + // user endpoint, including useridentity + can(Action.UserReadAny, User); + can(Action.UserReadOwn, User); + can(Action.UserCreateAny, User); + can(Action.UserUpdateAny, User); + can(Action.UserDeleteAny, User); + can(Action.UserCreateJwt, User); + + // ------------------------------------- } else if (user) { /** /* authenticated users **/ - - cannot(Action.DatasetCreate, DatasetClass); - can(Action.DatasetRead, DatasetClass); - cannot(Action.DatasetUpdate, DatasetClass); - // - - cannot(Action.DatasetAttachmentCreate, DatasetClass); - can(Action.DatasetAttachmentRead, DatasetClass); - cannot(Action.DatasetAttachmentUpdate, DatasetClass); - cannot(Action.DatasetAttachmentDelete, DatasetClass); - // - - cannot(Action.DatasetOrigdatablockCreate, DatasetClass); - can(Action.DatasetOrigdatablockRead, DatasetClass); - cannot(Action.DatasetOrigdatablockUpdate, DatasetClass); - // - - cannot(Action.DatasetDatablockCreate, DatasetClass); - can(Action.DatasetDatablockRead, DatasetClass); - cannot(Action.DatasetDatablockUpdate, DatasetClass); - // - - can(Action.DatasetLogbookRead, DatasetClass); + cannot(Action.UserReadAny, User); + cannot(Action.UserCreateAny, User); + cannot(Action.UserUpdateAny, User); + cannot(Action.UserDeleteAny, User); + cannot(Action.UserCreateJwt, User); } + can(Action.UserReadOwn, User, { _id: user._id }); + can(Action.UserCreateOwn, User, { _id: user._id }); + can(Action.UserUpdateOwn, User, { _id: user._id }); + can(Action.UserDeleteOwn, User, { _id: user._id }); } return build({ detectSubjectType: (item) => @@ -429,7 +816,7 @@ export class CaslAbilityFactory { }); } - accessDatasetDataInstanceForUser(user: JWTUser) { + datasetDataInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -788,90 +1175,7 @@ export class CaslAbilityFactory { }); } - accessOrigDatablockEndpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ - - can(Action.OrigdatablockDelete, OrigDatablock); - } else { - /* - / user that does not belong to any of the group listed in DELETE_GROUPS - */ - - cannot(Action.OrigdatablockDelete, OrigDatablock); - } - - if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in ADMIN_GROUPS - */ - - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( - user.currentGroups.some((g) => - configuration().createDatasetPrivilegedGroups.includes(g), - ) - ) { - /** - /* users belonging to CREATE_DATASET_PRIVILEGED_GROUPS - **/ - - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( - user.currentGroups.some((g) => - configuration().createDatasetWithPidGroups.includes(g), - ) || - configuration().createDatasetWithPidGroups.includes("#all") - ) { - /** - /* users belonging to CREATE_DATASET_WITH_PID_GROUPS - **/ - - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - } else if ( - user.currentGroups.some((g) => - configuration().createDatasetGroups.includes(g), - ) || - configuration().createDatasetGroups.includes("#all") - ) { - /** - /* users belonging to CREATE_DATASET_GROUPS - **/ - - can(Action.OrigdatablockRead, OrigDatablock); - can(Action.OrigdatablockCreate, OrigDatablock); - can(Action.OrigdatablockUpdate, OrigDatablock); - } else if (user) { - /** - /* authenticated users - **/ - - can(Action.OrigdatablockRead, OrigDatablock); - cannot(Action.OrigdatablockCreate, OrigDatablock); - cannot(Action.OrigdatablockUpdate, OrigDatablock); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessOrigDatablockDataInstanceForUser(user: JWTUser) { + origDatablockDataInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -969,90 +1273,28 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); } else if (user) { - /** - /* authenticated users - **/ - - can(Action.OrigdatablockReadManyAccess, OrigDatablock); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - ownerGroup: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - accessGroups: { $in: user.currentGroups }, - }); - can(Action.OrigdatablockReadOneAccess, OrigDatablock, { - isPublished: true, - }); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessJobsEnpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - if (!user) { - /** - * unauthenticated users - */ - - cannot(Action.JobsRead, JobClass); - cannot(Action.JobsCreate, JobClass); - cannot(Action.JobsUpdate, JobClass); - } else if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /** - * authenticated users belonging to any of the group listed in ADMIN_GROUPS - */ - - can(Action.JobsRead, JobClass); - can(Action.JobsCreate, JobClass); - can(Action.JobsUpdate, JobClass); - } else if ( - user.currentGroups.some((g) => - configuration().createJobGroups.includes(g), - ) - ) { - /** - * authenticated users belonging to any of the group listed in CREATE_JOBS_GROUPS - */ - - can(Action.JobsRead, JobClass); - can(Action.JobsCreate, JobClass); - can(Action.JobsUpdate, JobClass); - } else if ( - user.currentGroups.some((g) => - configuration().updateJobGroups.includes(g), - ) - ) { - /** - * authenticated users belonging to any of the group listed in UPDATE_JOBS_GROUPS - */ - - cannot(Action.JobsRead, JobClass); - cannot(Action.JobsCreate, JobClass); - can(Action.JobsUpdate, JobClass); - } else if (user) { - /** - * authenticated users - */ + /** + /* authenticated users + **/ - can(Action.JobsRead, JobClass); - cannot(Action.JobsCreate, JobClass); - cannot(Action.JobsUpdate, JobClass); + can(Action.OrigdatablockReadManyAccess, OrigDatablock); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + ownerGroup: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + accessGroups: { $in: user.currentGroups }, + }); + can(Action.OrigdatablockReadOneAccess, OrigDatablock, { + isPublished: true, + }); } - return build({ detectSubjectType: (item) => item.constructor as ExtractSubjectType, }); } - accessJobsDataInstanceForUser(user: JWTUser) { + jobsDataInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -1108,86 +1350,7 @@ export class CaslAbilityFactory { }); } - accessProposalsEndpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - if (!user) { - /** - * unauthenticated users - */ - - can(Action.ProposalsRead, ProposalClass); - cannot(Action.ProposalsCreate, ProposalClass); - cannot(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - cannot(Action.ProposalsAttachmentCreate, ProposalClass); - cannot(Action.ProposalsAttachmentUpdate, ProposalClass); - cannot(Action.ProposalsAttachmentDelete, ProposalClass); - } else if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - / user that belongs to any of the group listed in DELETE_GROUPS - */ - - can(Action.ProposalsDelete, ProposalClass); - } else if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /** - * authenticated users belonging to any of the group listed in ADMIN_GROUPS - */ - - can(Action.ProposalsRead, ProposalClass); - can(Action.ProposalsCreate, ProposalClass); - can(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - can(Action.ProposalsAttachmentCreate, ProposalClass); - can(Action.ProposalsAttachmentUpdate, ProposalClass); - can(Action.ProposalsAttachmentDelete, ProposalClass); - } else if ( - user.currentGroups.some((g) => { - return configuration().proposalGroups.includes(g); - }) - ) { - /** - * authenticated users belonging to any of the group listed in PROPOSAL_GROUPS - */ - - can(Action.ProposalsRead, ProposalClass); - can(Action.ProposalsCreate, ProposalClass); - can(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - can(Action.ProposalsAttachmentCreate, ProposalClass); - can(Action.ProposalsAttachmentUpdate, ProposalClass); - can(Action.ProposalsAttachmentDelete, ProposalClass); - cannot(Action.ProposalsDatasetRead, ProposalClass); - } else if (user) { - /** - * authenticated users - */ - - can(Action.ProposalsRead, ProposalClass); - cannot(Action.ProposalsCreate, ProposalClass); - cannot(Action.ProposalsUpdate, ProposalClass); - cannot(Action.ProposalsDelete, ProposalClass); - can(Action.ProposalsAttachmentRead, ProposalClass); - cannot(Action.ProposalsAttachmentCreate, ProposalClass); - cannot(Action.ProposalsAttachmentUpdate, ProposalClass); - cannot(Action.ProposalsAttachmentDelete, ProposalClass); - can(Action.ProposalsDatasetRead, ProposalClass); - } - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessProposalsDataInstanceForUser(user: JWTUser) { + proposalsDataInstanceAccess(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1294,125 +1457,7 @@ export class CaslAbilityFactory { }); } - accessSamplesEndpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - - if (!user) { - // ------------------------------------- - // unauthenticated users - // ------------------------------------- - - can(Action.SampleRead, SampleClass); - cannot(Action.SampleCreate, SampleClass); - cannot(Action.SampleUpdate, SampleClass); - cannot(Action.SampleDelete, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - cannot(Action.SampleAttachmentCreate, SampleClass); - cannot(Action.SampleAttachmentUpdate, SampleClass); - cannot(Action.SampleAttachmentDelete, SampleClass); - cannot(Action.SampleDatasetRead, SampleClass); - } else { - // ------------------------------------- - // authenticated users - // ------------------------------------- - - if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - // ------------------------------------- - // users that belong to any of the group listed in DELETE_GROUPS - // ------------------------------------- - - can(Action.SampleDelete, SampleClass); - can(Action.SampleAttachmentDelete, SampleClass); - } else { - // ------------------------------------- - // users that do not belong to any of the group listed in DELETE_GROUPS - // ------------------------------------- - - cannot(Action.SampleDelete, SampleClass); - } - - if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - // ------------------------------------- - // users belonging to any of the group listed in ADMIN_GROUPS - // ------------------------------------- - - can(Action.SampleRead, SampleClass); - can(Action.SampleCreate, SampleClass); - can(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - can(Action.SampleAttachmentCreate, SampleClass); - can(Action.SampleAttachmentUpdate, SampleClass); - can(Action.SampleAttachmentDelete, SampleClass); - can(Action.SampleDatasetRead, SampleClass); - } else if ( - user.currentGroups.some((g) => - configuration().samplePrivilegedGroups.includes(g), - ) - ) { - // ------------------------------------- - // users belonging to any of the group listed in SAMPLE_GROUPS - // - - can(Action.SampleRead, SampleClass); - can(Action.SampleCreate, SampleClass); - can(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - can(Action.SampleAttachmentCreate, SampleClass); - can(Action.SampleAttachmentUpdate, SampleClass); - can(Action.SampleAttachmentDelete, SampleClass); - can(Action.SampleDatasetRead, SampleClass); - } else if ( - user.currentGroups.some((g) => - configuration().sampleGroups.includes(g), - ) || - configuration().sampleGroups.includes("#all") - ) { - // ------------------------------------- - // users belonging to any of the group listed in SAMPLE_GROUPS - // - - can(Action.SampleRead, SampleClass); - can(Action.SampleCreate, SampleClass); - can(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - can(Action.SampleAttachmentCreate, SampleClass); - can(Action.SampleAttachmentUpdate, SampleClass); - can(Action.SampleAttachmentDelete, SampleClass); - can(Action.SampleDatasetRead, SampleClass); - } else { - // ------------------------------------- - // users with no elevated permissions - // ------------------------------------- - - can(Action.SampleRead, SampleClass); - cannot(Action.SampleCreate, SampleClass); - cannot(Action.SampleUpdate, SampleClass); - can(Action.SampleAttachmentRead, SampleClass); - cannot(Action.SampleAttachmentCreate, SampleClass); - cannot(Action.SampleAttachmentUpdate, SampleClass); - if ( - !user.currentGroups.some((g) => - configuration().deleteGroups.includes(g), - ) - ) { - cannot(Action.SampleAttachmentDelete, SampleClass); - } - } - } - - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } - - accessSamplesDataInstanceForUser(user: JWTUser) { + samplesDataInstanceAccess(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1582,49 +1627,4 @@ export class CaslAbilityFactory { }); } - accessInstrumentEndpointForUser(user: JWTUser) { - const { can, cannot, build } = new AbilityBuilder( - createMongoAbility, - ); - - if (!user) { - cannot(Action.InstrumentRead, Instrument); - cannot(Action.InstrumentCreate, Instrument); - cannot(Action.InstrumentUpdate, Instrument); - cannot(Action.InstrumentDelete, Instrument); - } else { - if ( - user.currentGroups.some((g) => configuration().deleteGroups.includes(g)) - ) { - /* - * user that belongs to any of the group listed in DELETE_GROUPS - */ - - can(Action.InstrumentDelete, Instrument); - } else { - cannot(Action.InstrumentDelete, Instrument); - } - - if ( - user.currentGroups.some((g) => configuration().adminGroups.includes(g)) - ) { - /** - * authenticated users belonging to any of the group listed in ADMIN_GROUPS - */ - - can(Action.InstrumentRead, Instrument); - can(Action.InstrumentCreate, Instrument); - can(Action.InstrumentUpdate, Instrument); - } else { - can(Action.InstrumentRead, Instrument); - cannot(Action.InstrumentCreate, Instrument); - cannot(Action.InstrumentUpdate, Instrument); - } - } - - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } } diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index 08bfe8ba2..5d0b088df 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -22,7 +22,7 @@ export class PoliciesGuard implements CanActivate { const user = req.user; const endpoint = req.route.path.split("/")[3]; - const ability = this.caslAbilityFactory.accessEndpointForUser( + const ability = this.caslAbilityFactory.endpointAccess( user, endpoint, ); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 1eb45083c..73cd1f98c 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -161,7 +161,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -207,7 +207,7 @@ export class DatasetsController { await this.generateDatasetInstanceForPermissions(dataset); const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); let canDoAction = false; @@ -293,7 +293,7 @@ export class DatasetsController { await this.generateDatasetInstanceForPermissions(dataset); const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -359,7 +359,7 @@ export class DatasetsController { await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -696,7 +696,7 @@ export class DatasetsController { const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -775,7 +775,7 @@ export class DatasetsController { const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -857,7 +857,7 @@ export class DatasetsController { const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1106,7 +1106,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1186,7 +1186,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1237,7 +1237,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || @@ -1289,7 +1289,7 @@ export class DatasetsController { ): Promise { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetDataInstanceForUser(user); + this.caslAbilityFactory.datasetDataInstanceAccess(user); const datasetToUpdate = await this.datasetsService.findOne({ where: { pid: pid }, }); diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 257ec925b..88ebfcb4c 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -129,7 +129,7 @@ export class OrigDatablocksController { await this.generateOrigDatablockInstanceInstanceForPermissions(dataset); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); let canDoAction = false; @@ -304,7 +304,7 @@ export class OrigDatablocksController { const parsedFilters: IFilters = JSON.parse(filter ?? "{}"); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { parsedFilters.where = parsedFilters.where ?? {}; @@ -366,7 +366,7 @@ export class OrigDatablocksController { const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { @@ -430,7 +430,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -472,7 +472,7 @@ export class OrigDatablocksController { const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -514,7 +514,7 @@ export class OrigDatablocksController { const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); const ability = - this.caslAbilityFactory.accessOrigDatablockDataInstanceForUser(user); + this.caslAbilityFactory.origDatablockDataInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( diff --git a/src/policies/policies.controller.ts b/src/policies/policies.controller.ts index 442fe922e..6cb073710 100644 --- a/src/policies/policies.controller.ts +++ b/src/policies/policies.controller.ts @@ -84,7 +84,7 @@ export class PoliciesController { const user: JWTUser = request.user as JWTUser; if (user) { - const ability = this.caslAbilityFactory.accessPolicyEndpointForUser(user); + const ability = this.caslAbilityFactory.policyEndpointAccess(user); // these actions are not defined in casl const canViewAll = ability.can(Action.ListAll, Policy); const canViewTheirOwn = ability.can(Action.ListOwn, Policy); diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 5e0ec3030..3bd6f2cfe 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -100,7 +100,7 @@ export class ProposalsController { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + this.caslAbilityFactory.proposalsDataInstanceAccess(user); try { switch (group) { @@ -210,7 +210,7 @@ export class ProposalsController { if (user) { const ability = - this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -410,7 +410,7 @@ export class ProposalsController { const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { const ability = - this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -482,7 +482,7 @@ export class ProposalsController { const facets = JSON.parse(filters.facets ?? "[]"); if (user) { const ability = - this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -874,7 +874,7 @@ export class ProposalsController { ): Promise { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessProposalsDataInstanceForUser(user); + this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 9abc40c1a..a31d1873c 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -98,7 +98,7 @@ export class SamplesController { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + this.caslAbilityFactory.samplesDataInstanceAccess(user); try { switch (group) { @@ -200,7 +200,7 @@ export class SamplesController { const authorizationFilter: Record = { where: {} }; if (user) { const ability = - this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -359,7 +359,7 @@ export class SamplesController { const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { const ability = - this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -431,7 +431,7 @@ export class SamplesController { const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { const ability = - this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -875,7 +875,7 @@ export class SamplesController { ): Promise { const user: JWTUser = request.user as JWTUser; const ability = - this.caslAbilityFactory.accessSamplesDataInstanceForUser(user); + this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index fdb6aea50..c8c7b757d 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -56,7 +56,7 @@ export class UserIdentitiesController { const authenticatedUser: JWTUser = request.user as JWTUser; const ability = - await this.caslAbilityFactory.accessUserEndpointForUser( + await this.caslAbilityFactory.userEndpointAccess( authenticatedUser, ); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index a7c7c603d..533a8104b 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -66,7 +66,7 @@ export class UsersController { viewedUserSchema.id = viewedUserId; const ability = - this.caslAbilityFactory.accessUserEndpointForUser(authenticatedUser); + this.caslAbilityFactory.userEndpointAccess(authenticatedUser); // const authorized = actions.map( action => // ability.can(action, viewedUserSchema) // ) as Array; @@ -330,7 +330,7 @@ export class UsersController { id, )) as JWTUser; const ability = - this.caslAbilityFactory.accessDatasetEndpointForUser(viewedUser); + this.caslAbilityFactory.datasetEndpointAccess(viewedUser); const canCreateDataset = ability.can(Action.DatasetCreate, DatasetClass); From 2e91873a820fa3292f1c5a782b90d41c180723b9 Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Tue, 20 Aug 2024 10:04:04 +0200 Subject: [PATCH 155/258] fix linting --- src/casl/casl-ability.factory.ts | 1 - src/casl/guards/policies.guard.ts | 5 +--- src/datasets/datasets.controller.ts | 33 +++++++++---------------- src/proposals/proposals.controller.ts | 15 ++++------- src/samples/samples.controller.ts | 15 ++++------- src/users/user-identities.controller.ts | 4 +-- src/users/users.controller.ts | 3 +-- 7 files changed, 24 insertions(+), 52 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index d821225e3..cde178460 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -1626,5 +1626,4 @@ export class CaslAbilityFactory { item.constructor as ExtractSubjectType, }); } - } diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index 5d0b088df..5d6576ff7 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -22,10 +22,7 @@ export class PoliciesGuard implements CanActivate { const user = req.user; const endpoint = req.route.path.split("/")[3]; - const ability = this.caslAbilityFactory.endpointAccess( - user, - endpoint, - ); + const ability = this.caslAbilityFactory.endpointAccess(user, endpoint); return policyHandlers.every((handler) => this.execPolicyHandler(handler, ability), ); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 73cd1f98c..52e52946b 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -160,8 +160,7 @@ export class DatasetsController { ): IFilters { const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -206,8 +205,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); let canDoAction = false; @@ -292,8 +290,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -358,8 +355,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -695,8 +691,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -774,8 +769,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -856,8 +850,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1105,8 +1098,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1185,8 +1177,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1236,8 +1227,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || @@ -1288,8 +1278,7 @@ export class DatasetsController { @Query("data") data: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); const datasetToUpdate = await this.datasetsService.findOne({ where: { pid: pid }, }); diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 3bd6f2cfe..ff62c9d48 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -99,8 +99,7 @@ export class ProposalsController { ); const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); try { switch (group) { @@ -209,8 +208,7 @@ export class ProposalsController { mergedFilters.where = mergedFilters.where || {}; if (user) { - const ability = - this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -409,8 +407,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = - this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -481,8 +478,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const facets = JSON.parse(filters.facets ?? "[]"); if (user) { - const ability = - this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -873,8 +869,7 @@ export class ProposalsController { @Param("pid") proposalId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index a31d1873c..989e26c9b 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -97,8 +97,7 @@ export class SamplesController { ); const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); try { switch (group) { @@ -199,8 +198,7 @@ export class SamplesController { /* eslint-disable @typescript-eslint/no-explicit-any */ const authorizationFilter: Record = { where: {} }; if (user) { - const ability = - this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -358,8 +356,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = - this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -430,8 +427,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = - this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -874,8 +870,7 @@ export class SamplesController { @Param("id") sampleId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = - this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index c8c7b757d..c95682c20 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -56,9 +56,7 @@ export class UserIdentitiesController { const authenticatedUser: JWTUser = request.user as JWTUser; const ability = - await this.caslAbilityFactory.userEndpointAccess( - authenticatedUser, - ); + await this.caslAbilityFactory.userEndpointAccess(authenticatedUser); if ( !ability.can(Action.UserReadAny, User) && diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 533a8104b..bfe3be6b3 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -329,8 +329,7 @@ export class UsersController { const viewedUser = (await this.usersService.findById2JWTUser( id, )) as JWTUser; - const ability = - this.caslAbilityFactory.datasetEndpointAccess(viewedUser); + const ability = this.caslAbilityFactory.datasetEndpointAccess(viewedUser); const canCreateDataset = ability.can(Action.DatasetCreate, DatasetClass); From 8f17bc7d1def7ff142615401728ead884cfc3834 Mon Sep 17 00:00:00 2001 From: fpotier Date: Tue, 20 Aug 2024 10:36:32 +0200 Subject: [PATCH 156/258] Upgrade to node 20 --- .github/workflows/github-tag-and-release.yml | 2 +- Dockerfile | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index 4d422b7dc..2e5e00c76 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -5,7 +5,7 @@ on: - release env: - NODE_VERSION: 18.x + NODE_VERSION: 20.x RELEASE_BRANCH: release jobs: diff --git a/Dockerfile b/Dockerfile index a426258ba..e56c0c88d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS dev +FROM node:20-alpine AS dev # Prepare app directory WORKDIR /home/node/app @@ -6,17 +6,15 @@ COPY . . # Set up local user RUN mkdir /home/node/app/dist -RUN npm install -g npm@9.8.1 # Install dependencies RUN npm install glob rimraf RUN npm install -FROM node:18-alpine AS builder +FROM node:20-alpine AS builder # Prepare app directory -RUN npm install -g npm@9.8.1 WORKDIR /usr/src/app # Set up local user @@ -29,7 +27,7 @@ RUN npm run build # Remove development dependencies RUN npm prune --production -FROM node:18-alpine +FROM node:20-alpine # Prepare app directory WORKDIR /home/node/app From 23b69066c0ae34a6de82c09edfc13ccc085dc4b8 Mon Sep 17 00:00:00 2001 From: fpotier Date: Tue, 20 Aug 2024 10:41:10 +0200 Subject: [PATCH 157/258] Upgrade in test workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba6213ed2..a757094f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ name: Test env: - NODE_VERSION: 18.x + NODE_VERSION: 20.x on: pull_request: From bb9c3351883c56119e24c5dfae3917139f318fa6 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Tue, 20 Aug 2024 16:30:45 +0200 Subject: [PATCH 158/258] Add test defaults --- src/users/users.service.spec.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index 24a65a86d..d69ca6012 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -29,6 +29,18 @@ const mockUser: User = { datasetCount: 25, jobCount: 25, userId: "testUserId", + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + conditions: [], }, }; @@ -58,6 +70,18 @@ const mockUserSettings: UserSettings = { datasetCount: 25, jobCount: 25, userId: "testUserId", + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + conditions: [], }; describe("UsersService", () => { From 7d3a298d38a7d3582dce20ac522cde2dc77989e8 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Tue, 20 Aug 2024 16:32:38 +0200 Subject: [PATCH 159/258] Revert "Fix cp non existing file" This reverts commit 680317c7939f437689588d57d9f94d16acf5a8e7. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 122c1b424..f81c13691 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start\"", "test:api:jest": "jest --config ./test/config/jest-e2e.json --maxWorkers=50%", "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js ", - "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.test.json functionalAccounts.json" + "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.json.test functionalAccounts.json" }, "dependencies": { "@casl/ability": "^6.3.2", From 43b0cf5e191bbd43c0ed6d6de1aa4aeb812c4b5a Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Wed, 21 Aug 2024 11:31:14 +0200 Subject: [PATCH 160/258] CheckPolices decorator accepts two arguments --- src/casl/casl-ability.factory.ts | 53 ++++++++---------- .../decorators/check-policies.decorator.ts | 4 +- src/casl/guards/policies.guard.ts | 18 +++--- src/datasets/datasets.controller.ts | 56 +++++++++---------- .../elastic-search.controller.ts | 12 ++-- src/instruments/instruments.controller.ts | 12 ++-- src/jobs/jobs.controller.ts | 24 ++++++-- src/logbooks/logbooks.controller.ts | 8 ++- .../origdatablocks.controller.ts | 20 +++---- src/policies/policies.controller.ts | 28 +++++++--- src/proposals/proposals.controller.ts | 28 +++++----- .../published-data.controller.ts | 12 ++-- src/samples/samples.controller.ts | 34 +++++------ src/users/user-identities.controller.ts | 1 + src/users/users.controller.ts | 23 ++++++-- test/config/jobconfig.json | 0 16 files changed, 188 insertions(+), 145 deletions(-) create mode 100755 test/config/jobconfig.json diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index cde178460..2524d0fac 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -6,7 +6,7 @@ import { MongoQuery, createMongoAbility, } from "@casl/ability"; -import { Injectable } from "@nestjs/common"; +import { Injectable, InternalServerErrorException } from "@nestjs/common"; import { Attachment } from "src/attachments/schemas/attachment.schema"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; // import { Role } from "src/auth/role.enum"; @@ -54,35 +54,30 @@ export type AppAbility = MongoAbility; @Injectable() export class CaslAbilityFactory { - endpointAccess(user: JWTUser, subject: string) { - switch (subject) { - case "datasets": - return this.datasetEndpointAccess(user); - case "elastic-search": - return this.elasticSearchEndpointAccess(user); - case "jobs": - return this.jobsEndpointAccess(user); - case "instruments": - return this.instrumentEndpointAccess(user); - case "logbooks": - return this.logbookEndpointAccess(user); - case "origdatablocks": - return this.origDatablockEndpointAccess(user); - case "policies": - return this.policyEndpointAccess(user); - case "proposals": - return this.proposalsEndpointAccess(user); - case "publisheddata": - return this.publishedDataEndpointAccess(user); - case "samples": - return this.samplesEndpointAccess(user); - case "users": - case "useridentities": - return this.userEndpointAccess(user); - default: - throw new Error(` - No endpoint access policies defined for subject: ${subject}`); + private endpointAccessors: { + [endpoint: string]: (user: JWTUser) => AppAbility; + } = { + datasets: this.datasetEndpointAccess, + elasticSearch: this.elasticSearchEndpointAccess, + jobs: this.jobsEndpointAccess, + instruments: this.instrumentEndpointAccess, + logbooks: this.logbookEndpointAccess, + origdatablocks: this.origDatablockEndpointAccess, + policies: this.policyEndpointAccess, + proposals: this.proposalsEndpointAccess, + publishedData: this.publishedDataEndpointAccess, + samples: this.samplesEndpointAccess, + users: this.userEndpointAccess, + }; + + endpointAccess(endpoint: string, user: JWTUser) { + const accessFunction = this.endpointAccessors[endpoint]; + if (!accessFunction) { + throw new InternalServerErrorException( + `No endpoint access policies defined for subject: ${endpoint}`, + ); } + return accessFunction.call(this, user); } datasetEndpointAccess(user: JWTUser) { diff --git a/src/casl/decorators/check-policies.decorator.ts b/src/casl/decorators/check-policies.decorator.ts index 6ac4f3550..ec4af992a 100644 --- a/src/casl/decorators/check-policies.decorator.ts +++ b/src/casl/decorators/check-policies.decorator.ts @@ -3,5 +3,5 @@ import { PolicyHandler } from "../interfaces/policy-handler.interface"; export const CHECK_POLICIES_KEY = "check_policy"; -export const CheckPolicies = (...handlers: PolicyHandler[]) => - SetMetadata(CHECK_POLICIES_KEY, handlers); +export const CheckPolicies = (endpoint: string, ...handlers: PolicyHandler[]) => + SetMetadata(CHECK_POLICIES_KEY, { endpoint, handlers }); diff --git a/src/casl/guards/policies.guard.ts b/src/casl/guards/policies.guard.ts index 5d6576ff7..0aa563ac0 100644 --- a/src/casl/guards/policies.guard.ts +++ b/src/casl/guards/policies.guard.ts @@ -12,17 +12,21 @@ export class PoliciesGuard implements CanActivate { ) {} async canActivate(context: ExecutionContext): Promise { - const policyHandlers = - this.reflector.get( - CHECK_POLICIES_KEY, - context.getHandler(), - ) || []; + const policyData = this.reflector.get<{ + endpoint: string; + handlers: PolicyHandler[]; + }>(CHECK_POLICIES_KEY, context.getHandler()); + if (!policyData) { + return false; + } + + const policyHandlers = policyData["handlers"]; + const endpoint = policyData["endpoint"]; const req = context.switchToHttp().getRequest(); const user = req.user; - const endpoint = req.route.path.split("/")[3]; - const ability = this.caslAbilityFactory.endpointAccess(user, endpoint); + const ability = this.caslAbilityFactory.endpointAccess(endpoint, user); return policyHandlers.every((handler) => this.execPolicyHandler(handler, ability), ); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 52e52946b..657a5a707 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -389,7 +389,7 @@ export class DatasetsController { // POST /datasets @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetCreate, DatasetClass), ) @UseInterceptors( @@ -510,7 +510,7 @@ export class DatasetsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetCreate, DatasetClass), ) @UseInterceptors( @@ -568,7 +568,7 @@ export class DatasetsController { // GET /datasets @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @UseInterceptors(MainDatasetsPublicInterceptor) @@ -650,7 +650,7 @@ export class DatasetsController { // GET /datasets/fullquery @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @UseInterceptors(SubDatasetsPublicInterceptor, FullQueryInterceptor) @@ -729,7 +729,7 @@ export class DatasetsController { // GET /fullfacets @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @UseInterceptors(SubDatasetsPublicInterceptor) @@ -811,7 +811,7 @@ export class DatasetsController { // GET /datasets/metadataKeys @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @UseInterceptors(SubDatasetsPublicInterceptor) @@ -890,7 +890,7 @@ export class DatasetsController { // GET /datasets/findOne @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @Get("/findOne") @@ -961,7 +961,7 @@ export class DatasetsController { // GET /datasets/count @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @Get("/count") @@ -1001,7 +1001,7 @@ export class DatasetsController { // GET /datasets/:id //@UseGuards(PoliciesGuard) @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) @Get("/:pid") @@ -1032,7 +1032,7 @@ export class DatasetsController { // PATCH /datasets/:id // body: modified fields @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetUpdate, DatasetClass), ) @UseInterceptors( @@ -1113,7 +1113,7 @@ export class DatasetsController { // PUT /datasets/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetUpdate, DatasetClass), ) @UseInterceptors( @@ -1195,7 +1195,7 @@ export class DatasetsController { // DELETE /datasets/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetDelete, DatasetClass), ) @Delete("/:pid") @@ -1241,7 +1241,7 @@ export class DatasetsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetUpdate, DatasetClass), ) @Post("/:pid/appendToArrayField") @@ -1312,7 +1312,7 @@ export class DatasetsController { // GET /datasets/:id/thumbnail @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetRead, DatasetClass), ) // @UseGuards(PoliciesGuard) @@ -1356,7 +1356,7 @@ export class DatasetsController { // POST /datasets/:id/attachments @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetAttachmentCreate, DatasetClass), ) @HttpCode(HttpStatus.CREATED) @@ -1406,7 +1406,7 @@ export class DatasetsController { // GET /datasets/:id/attachments @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetAttachmentRead, DatasetClass), ) @Get("/:pid/attachments") @@ -1443,7 +1443,7 @@ export class DatasetsController { // PATCH /datasets/:id/attachments/:fk @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetAttachmentUpdate, DatasetClass), ) @Put("/:pid/attachments/:aid") @@ -1490,7 +1490,7 @@ export class DatasetsController { // DELETE /datasets/:pid/attachments/:aid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetAttachmentDelete, DatasetClass), ) @Delete("/:pid/attachments/:aid") @@ -1534,7 +1534,7 @@ export class DatasetsController { // POST /datasets/:id/origdatablocks @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => { + @CheckPolicies("datasets", (ability: AppAbility) => { return ability.can(Action.DatasetOrigdatablockCreate, DatasetClass); }) @UseInterceptors( @@ -1600,7 +1600,7 @@ export class DatasetsController { // POST /datasets/:id/origdatablocks/isValid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => { + @CheckPolicies("datasets", (ability: AppAbility) => { return ability.can(Action.DatasetOrigdatablockCreate, DatasetClass); }) @HttpCode(HttpStatus.OK) @@ -1649,7 +1649,7 @@ export class DatasetsController { // GET /datasets/:id/origdatablocks @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => { + @CheckPolicies("datasets", (ability: AppAbility) => { return ability.can(Action.DatasetOrigdatablockRead, DatasetClass); }) @Get("/:pid/origdatablocks") @@ -1686,7 +1686,7 @@ export class DatasetsController { // PATCH /datasets/:id/origdatablocks/:fk @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => { + @CheckPolicies("datasets", (ability: AppAbility) => { return ability.can(Action.DatasetOrigdatablockUpdate, DatasetClass); }) @UseInterceptors( @@ -1757,7 +1757,7 @@ export class DatasetsController { // DELETE /datasets/:id/origdatablocks/:fk @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetOrigdatablockDelete, DatasetClass), ) @Delete("/:pid/origdatablocks/:oid") @@ -1819,7 +1819,7 @@ export class DatasetsController { // POST /datasets/:id/datablocks @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetDatablockCreate, DatasetClass), ) @UseInterceptors( @@ -1880,7 +1880,7 @@ export class DatasetsController { // GET /datasets/:id/datablocks @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetDatablockRead, DatasetClass), ) @Get("/:pid/datablocks") @@ -1917,7 +1917,7 @@ export class DatasetsController { // PATCH /datasets/:id/datablocks/:fk @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetDatablockUpdate, DatasetClass), ) @UseInterceptors( @@ -1987,7 +1987,7 @@ export class DatasetsController { // DELETE /datasets/:id/datablocks/:fk @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetDatablockDelete, DatasetClass), ) @Delete("/:pid/datablocks/:did") @@ -2056,7 +2056,7 @@ export class DatasetsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetLogbookRead, DatasetClass), ) @Get("/:pid/logbook") diff --git a/src/elastic-search/elastic-search.controller.ts b/src/elastic-search/elastic-search.controller.ts index ebc875cbd..de2498da6 100644 --- a/src/elastic-search/elastic-search.controller.ts +++ b/src/elastic-search/elastic-search.controller.ts @@ -37,7 +37,7 @@ export class ElasticSearchServiceController { ) {} @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.CREATED) @@ -53,7 +53,7 @@ export class ElasticSearchServiceController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.OK) @@ -70,7 +70,7 @@ export class ElasticSearchServiceController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.OK) @@ -88,7 +88,7 @@ export class ElasticSearchServiceController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.OK) @@ -104,7 +104,7 @@ export class ElasticSearchServiceController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.OK) @@ -120,7 +120,7 @@ export class ElasticSearchServiceController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("elastic-search", (ability: AppAbility) => ability.can(Action.Manage, ElasticSearchActions), ) @HttpCode(HttpStatus.OK) diff --git a/src/instruments/instruments.controller.ts b/src/instruments/instruments.controller.ts index b09fc7876..7ee9a6216 100644 --- a/src/instruments/instruments.controller.ts +++ b/src/instruments/instruments.controller.ts @@ -42,7 +42,7 @@ export class InstrumentsController { constructor(private readonly instrumentsService: InstrumentsService) {} @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentCreate, Instrument), ) @UseInterceptors( @@ -69,7 +69,7 @@ export class InstrumentsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentRead, Instrument), ) @Get() @@ -87,7 +87,7 @@ export class InstrumentsController { // GET /instrument/findOne @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentRead, Instrument), ) @Get("/findOne") @@ -117,7 +117,7 @@ export class InstrumentsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentRead, Instrument), ) @Get(":id") @@ -126,7 +126,7 @@ export class InstrumentsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentUpdate, Instrument), ) @UseInterceptors( @@ -152,7 +152,7 @@ export class InstrumentsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("instruments", (ability: AppAbility) => ability.can(Action.InstrumentDelete, Instrument), ) @Delete(":id") diff --git a/src/jobs/jobs.controller.ts b/src/jobs/jobs.controller.ts index 6430ca9ff..588f202f9 100644 --- a/src/jobs/jobs.controller.ts +++ b/src/jobs/jobs.controller.ts @@ -288,7 +288,9 @@ export class JobsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Read, JobClass), + ) @Get() @ApiQuery({ name: "filter", @@ -304,7 +306,9 @@ export class JobsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Read, JobClass), + ) @Get("/fullquery") async fullquery( @Query() filters: { fields?: string; limits?: string }, @@ -317,7 +321,9 @@ export class JobsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Read, JobClass), + ) @Get("/fullfacet") async fullfacet( @Query() filters: { fields?: string; facets?: string }, @@ -330,14 +336,18 @@ export class JobsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Read, JobClass), + ) @Get(":id") async findOne(@Param("id") id: string): Promise { return this.jobsService.findOne({ _id: id }); } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Update, JobClass), + ) @Patch(":id") async update( @Param("id") id: string, @@ -356,7 +366,9 @@ export class JobsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Delete, JobClass)) + @CheckPolicies("jobs", (ability: AppAbility) => + ability.can(Action.Delete, JobClass), + ) @Delete(":id") async remove(@Param("id") id: string): Promise { return this.jobsService.remove({ _id: id }); diff --git a/src/logbooks/logbooks.controller.ts b/src/logbooks/logbooks.controller.ts index 58df20cda..628997c7c 100644 --- a/src/logbooks/logbooks.controller.ts +++ b/src/logbooks/logbooks.controller.ts @@ -22,7 +22,9 @@ export class LogbooksController { constructor(private readonly logbooksService: LogbooksService) {} @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Logbook)) + @CheckPolicies("logbooks", (ability: AppAbility) => + ability.can(Action.Read, Logbook), + ) @UseInterceptors(UsersLogbooksInterceptor) @Get() findAll() { @@ -30,7 +32,9 @@ export class LogbooksController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Logbook)) + @CheckPolicies("logbooks", (ability: AppAbility) => + ability.can(Action.Read, Logbook), + ) @UseInterceptors(UsersLogbooksInterceptor) @Get("/:name") async findByName( diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 88ebfcb4c..9d83c63c2 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -158,7 +158,7 @@ export class OrigDatablocksController { // POST /origdatablocks @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockCreate, OrigDatablock), ) @HttpCode(HttpStatus.CREATED) @@ -227,7 +227,7 @@ export class OrigDatablocksController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockCreate, OrigDatablock), ) @HttpCode(HttpStatus.OK) @@ -272,7 +272,7 @@ export class OrigDatablocksController { // GET /origdatablock @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get() @@ -339,7 +339,7 @@ export class OrigDatablocksController { // GET /origdatablocks/fullquery @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get("/fullquery") @@ -404,7 +404,7 @@ export class OrigDatablocksController { // GET /origdatablocks/fullquery/files @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get("/fullquery/files") @@ -460,7 +460,7 @@ export class OrigDatablocksController { // GET /origdatablocks/fullfacet @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get("/fullfacet") @@ -502,7 +502,7 @@ export class OrigDatablocksController { // GET /origdatablocks/fullfacet/files @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get("/fullfacet/files") @@ -548,7 +548,7 @@ export class OrigDatablocksController { // GET /origdatablocks/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockRead, OrigDatablock), ) @Get("/:id") @@ -582,7 +582,7 @@ export class OrigDatablocksController { // PATCH /origdatablocks/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockUpdate, OrigDatablock), ) @Patch("/:id") @@ -629,7 +629,7 @@ export class OrigDatablocksController { // DELETE /origdatablocks/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("origdatablocks", (ability: AppAbility) => ability.can(Action.OrigdatablockDelete, OrigDatablock), ) @Delete("/:id") diff --git a/src/policies/policies.controller.ts b/src/policies/policies.controller.ts index 6cb073710..bbc9353dd 100644 --- a/src/policies/policies.controller.ts +++ b/src/policies/policies.controller.ts @@ -103,14 +103,18 @@ export class PoliciesController { return mergedFilters; } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Create, Policy), + ) @Post() async create(@Body() createPolicyDto: CreatePolicyDto): Promise { return this.policiesService.create(createPolicyDto); } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Read, Policy), + ) @Get() @ApiQuery({ name: "filter", @@ -134,7 +138,9 @@ export class PoliciesController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Read, Policy), + ) @Get("/count") async count(@Query("where") where?: string): Promise<{ count: number }> { const parsedWhere: FilterQuery = JSON.parse(where ?? "{}"); @@ -142,7 +148,9 @@ export class PoliciesController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Update, Policy), + ) @UseInterceptors(HistoryInterceptor) @HttpCode(HttpStatus.OK) @Post("/updateWhere") @@ -154,14 +162,18 @@ export class PoliciesController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Read, Policy), + ) @Get(":id") async findOne(@Param("id") id: string): Promise { return this.policiesService.findOne({ _id: id }); } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Update, Policy), + ) @Patch(":id") async update( @Param("id") id: string, @@ -171,7 +183,9 @@ export class PoliciesController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Delete, Policy)) + @CheckPolicies("policies", (ability: AppAbility) => + ability.can(Action.Delete, Policy), + ) @Delete(":id") async remove(@Param("id") id: string): Promise { return this.policiesService.remove({ _id: id }); diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index ff62c9d48..0deda52fe 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -243,7 +243,7 @@ export class ProposalsController { // POST /proposals @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsCreate, ProposalClass), ) @UseInterceptors( @@ -291,7 +291,7 @@ export class ProposalsController { } @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsCreate, ProposalClass), ) @HttpCode(HttpStatus.OK) @@ -330,7 +330,7 @@ export class ProposalsController { // GET /proposals @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @Get() @@ -366,7 +366,7 @@ export class ProposalsController { // GET /proposals/fullquery @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @Get("/fullquery") @@ -445,7 +445,7 @@ export class ProposalsController { // GET /proposals/fullfacet @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @Get("/fullfacet") @@ -517,7 +517,7 @@ export class ProposalsController { // GET /proposals/:pid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @Get("/:pid") @@ -551,7 +551,7 @@ export class ProposalsController { // GET /proposals/:pid/authorization @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsRead, ProposalClass), ) @Get("/:pid/authorization") @@ -590,7 +590,7 @@ export class ProposalsController { // PATCH /proposals/:pid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsUpdate, ProposalClass), ) @UseInterceptors( @@ -638,7 +638,7 @@ export class ProposalsController { // DELETE /proposals/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsDelete, ProposalClass), ) @Delete("/:pid") @@ -669,7 +669,7 @@ export class ProposalsController { // POST /proposals/:id/attachments @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsAttachmentCreate, ProposalClass), ) @Post("/:pid/attachments") @@ -714,7 +714,7 @@ export class ProposalsController { // GET /proposals/:pid/attachments @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsAttachmentRead, ProposalClass), ) @Get("/:pid/attachments") @@ -750,7 +750,7 @@ export class ProposalsController { // PATCH /proposals/:pid/attachments/:aid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsAttachmentUpdate, ProposalClass), ) @Patch("/:pid/attachments/:aid") @@ -797,7 +797,7 @@ export class ProposalsController { // DELETE /proposals/:pid/attachments/:aid @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsAttachmentDelete, ProposalClass), ) @Delete("/:pid/attachments/:aid") @@ -841,7 +841,7 @@ export class ProposalsController { // GET /proposals/:id/datasets @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("proposals", (ability: AppAbility) => ability.can(Action.ProposalsDatasetRead, ProposalClass), ) @Get("/:pid/datasets") diff --git a/src/published-data/published-data.controller.ts b/src/published-data/published-data.controller.ts index c8030b6ca..3bd9e9f2c 100644 --- a/src/published-data/published-data.controller.ts +++ b/src/published-data/published-data.controller.ts @@ -69,7 +69,7 @@ export class PublishedDataController { // POST /publisheddata @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Create, PublishedData), ) @Post() @@ -155,7 +155,7 @@ export class PublishedDataController { // GET /publisheddata/formpopulate @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Read, PublishedData), ) @Get("/formpopulate") @@ -221,7 +221,7 @@ export class PublishedDataController { // PATCH /publisheddata/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @Patch("/:id") @@ -237,7 +237,7 @@ export class PublishedDataController { // DELETE /publisheddata/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Delete, PublishedData), ) @Delete("/:id") @@ -247,7 +247,7 @@ export class PublishedDataController { // POST /publisheddata/:id/register @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @Post("/:id/register") @@ -428,7 +428,7 @@ export class PublishedDataController { // POST /publisheddata/:id/resync @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("publishedData", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @ApiOperation({ diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 989e26c9b..66c680a5e 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -243,7 +243,7 @@ export class SamplesController { } // POST /samples @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleCreate, SampleClass), ) @UseInterceptors( @@ -281,7 +281,7 @@ export class SamplesController { // GET /samples @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get() @@ -315,7 +315,7 @@ export class SamplesController { // GET /samples/fullquery @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get("/fullquery") @@ -392,7 +392,7 @@ export class SamplesController { // GET /samples/metadataKeys @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get("/metadataKeys") @@ -464,7 +464,7 @@ export class SamplesController { // GET /samples/findOne @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get("/findOne") @@ -523,7 +523,7 @@ export class SamplesController { // GET /samples/:id @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get("/:id") @@ -556,7 +556,7 @@ export class SamplesController { // GET /samples/:id/authorization @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleRead, SampleClass), ) @Get("/:id/authorization") @@ -594,7 +594,7 @@ export class SamplesController { // PATCH /samples/:id @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleUpdate, SampleClass), ) @UseInterceptors( @@ -634,7 +634,7 @@ export class SamplesController { // DELETE /samples/:id @UseGuards() - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleDelete, SampleClass), ) @Delete("/:id") @@ -661,7 +661,7 @@ export class SamplesController { // POST /samples/:id/attachments @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleAttachmentDelete, SampleClass), ) @Post("/:id/attachments") @@ -713,7 +713,7 @@ export class SamplesController { // GET /samples/:id/attachments @UseGuards(PoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleAttachmentRead, SampleClass), ) @Get("/:id/attachments") @@ -747,7 +747,7 @@ export class SamplesController { // GET /samples/:id/attachments/:fk @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleAttachmentRead, SampleClass), ) @Get("/:id/attachments/:fk") @@ -790,7 +790,7 @@ export class SamplesController { // DELETE /samples/:id/attachments/:fk @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleAttachmentDelete, SampleClass), ) @Delete("/:id/attachments/:fk") @@ -832,7 +832,7 @@ export class SamplesController { // POST /samples/:id/datasets /* @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Dataset)) + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.Create, Dataset)) @Post("/:id/datasets") async createDataset( @Param("id") id: string, @@ -845,7 +845,7 @@ export class SamplesController { // GET /samples/:id/datasets @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.SampleDatasetRead, SampleClass), ) @Get("/:id/datasets") @@ -908,7 +908,7 @@ export class SamplesController { // PATCH /samples/:id/datasets/:fk /* @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Update, Dataset)) + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.Update, Dataset)) @Patch("/:id/datasets/:fk") async findOneDatasetAndUpdate( @Param("id") sampleId: string, @@ -923,7 +923,7 @@ export class SamplesController { // DELETE /samples/:id/datasets/:fk /* @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.Delete, Dataset)) + @CheckPolicies("samples", (ability: AppAbility) => ability.can(Action.Delete, Dataset)) @Delete("/:id/datasets/:fk") async findOneDatasetAndRemove( @Param("id") sampleId: string, diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index c95682c20..99fa923f2 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -30,6 +30,7 @@ export class UserIdentitiesController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User), diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index bfe3be6b3..d123cf1db 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -113,7 +113,9 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.UserReadOwn, User)) + @CheckPolicies("users", (ability: AppAbility) => + ability.can(Action.UserReadOwn, User), + ) @UseInterceptors(CreateUserSettingsInterceptor) @Get("/my/self") @ApiOperation({ @@ -138,7 +140,9 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.UserReadOwn, User)) + @CheckPolicies("users", (ability: AppAbility) => + ability.can(Action.UserReadOwn, User), + ) @Get("/my/identity") async getMyUserIdentity( @Req() request: Request, @@ -153,7 +157,9 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => ability.can(Action.UserReadOwn, User)) + @CheckPolicies("users", (ability: AppAbility) => + ability.can(Action.UserReadOwn, User), + ) @Get("/my/settings") async getMySettings(@Req() request: Request): Promise { const authenticatedUserId: string = (request.user as JWTUser)._id; @@ -167,6 +173,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User), @@ -187,6 +194,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User), @@ -206,6 +214,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserCreateOwn, User) || ability.can(Action.UserCreateAny, User), @@ -226,6 +235,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User), @@ -245,6 +255,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserUpdateOwn, User) || ability.can(Action.UserUpdateAny, User), @@ -268,6 +279,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserUpdateOwn, User) || ability.can(Action.UserUpdateAny, User), @@ -291,6 +303,7 @@ export class UsersController { @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( + "users", (ability: AppAbility) => ability.can(Action.UserDeleteOwn, User) || ability.can(Action.UserDeleteAny, User), @@ -309,7 +322,7 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => { + @CheckPolicies("users", (ability: AppAbility) => { return ( ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User) @@ -354,7 +367,7 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => + @CheckPolicies("users", (ability: AppAbility) => ability.can(Action.UserCreateJwt, User), ) @Post("/:id/jwt") diff --git a/test/config/jobconfig.json b/test/config/jobconfig.json new file mode 100755 index 000000000..e69de29bb From b7f71a1eeb4b2e47fae4a844bae90562d5657862 Mon Sep 17 00:00:00 2001 From: sofyalaski Date: Wed, 21 Aug 2024 11:50:11 +0200 Subject: [PATCH 161/258] change name of instance functions --- src/casl/casl-ability.factory.ts | 14 ++++++------ src/datasets/datasets.controller.ts | 22 +++++++++---------- .../origdatablocks.controller.ts | 18 +++++---------- src/proposals/proposals.controller.ts | 10 ++++----- .../published-data.controller.ts | 12 +++++----- src/samples/samples.controller.ts | 10 ++++----- 6 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 2524d0fac..b2e3e1821 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -58,14 +58,14 @@ export class CaslAbilityFactory { [endpoint: string]: (user: JWTUser) => AppAbility; } = { datasets: this.datasetEndpointAccess, - elasticSearch: this.elasticSearchEndpointAccess, + "elastic-search": this.elasticSearchEndpointAccess, jobs: this.jobsEndpointAccess, instruments: this.instrumentEndpointAccess, logbooks: this.logbookEndpointAccess, origdatablocks: this.origDatablockEndpointAccess, policies: this.policyEndpointAccess, proposals: this.proposalsEndpointAccess, - publishedData: this.publishedDataEndpointAccess, + publisheddata: this.publishedDataEndpointAccess, samples: this.samplesEndpointAccess, users: this.userEndpointAccess, }; @@ -811,7 +811,7 @@ export class CaslAbilityFactory { }); } - datasetDataInstanceAccess(user: JWTUser) { + datasetInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -1170,7 +1170,7 @@ export class CaslAbilityFactory { }); } - origDatablockDataInstanceAccess(user: JWTUser) { + origDatablockInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -1289,7 +1289,7 @@ export class CaslAbilityFactory { }); } - jobsDataInstanceAccess(user: JWTUser) { + jobsInstanceAccess(user: JWTUser) { const { can, build } = new AbilityBuilder( createMongoAbility, ); @@ -1345,7 +1345,7 @@ export class CaslAbilityFactory { }); } - proposalsDataInstanceAccess(user: JWTUser) { + proposalsInstanceAccess(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); @@ -1452,7 +1452,7 @@ export class CaslAbilityFactory { }); } - samplesDataInstanceAccess(user: JWTUser) { + samplesInstanceAccess(user: JWTUser) { const { can, cannot, build } = new AbilityBuilder( createMongoAbility, ); diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 657a5a707..0d7706ee1 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -160,7 +160,7 @@ export class DatasetsController { ): IFilters { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass); const canViewAccess = ability.can( @@ -205,7 +205,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); let canDoAction = false; @@ -290,7 +290,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canView = ability.can(Action.DatasetReadAny, DatasetClass) || ability.can(Action.DatasetReadOneOwner, datasetInstance) || @@ -355,7 +355,7 @@ export class DatasetsController { const datasetInstance = await this.generateDatasetInstanceForPermissions(dataset); // instantiate the casl matrix for the user - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); // check if he/she can create this dataset const canCreate = ability.can(Action.DatasetCreateAny, DatasetClass) || @@ -691,7 +691,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -769,7 +769,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -850,7 +850,7 @@ export class DatasetsController { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); if (!canViewAny && !fields.isPublished) { @@ -1098,7 +1098,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1177,7 +1177,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetUpdateAny, DatasetClass) || @@ -1227,7 +1227,7 @@ export class DatasetsController { // instantiate the casl matrix for the user const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); // check if he/she can create this dataset const canUpdate = ability.can(Action.DatasetDeleteAny, DatasetClass) || @@ -1278,7 +1278,7 @@ export class DatasetsController { @Query("data") data: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.datasetDataInstanceAccess(user); + const ability = this.caslAbilityFactory.datasetInstanceAccess(user); const datasetToUpdate = await this.datasetsService.findOne({ where: { pid: pid }, }); diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 9d83c63c2..f1a0f13be 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -128,8 +128,7 @@ export class OrigDatablocksController { const origDatablockInstance = await this.generateOrigDatablockInstanceInstanceForPermissions(dataset); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); let canDoAction = false; @@ -303,8 +302,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const parsedFilters: IFilters = JSON.parse(filter ?? "{}"); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { parsedFilters.where = parsedFilters.where ?? {}; @@ -365,8 +363,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { @@ -429,8 +426,7 @@ export class OrigDatablocksController { ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -471,8 +467,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( @@ -513,8 +508,7 @@ export class OrigDatablocksController { const user: JWTUser = request.user as JWTUser; const fields: IOrigDatablockFields = JSON.parse(filters.fields ?? "{}"); - const ability = - this.caslAbilityFactory.origDatablockDataInstanceAccess(user); + const ability = this.caslAbilityFactory.origDatablockInstanceAccess(user); const canViewAny = ability.can(Action.OrigdatablockReadAny, OrigDatablock); if (!canViewAny) { const canViewAccess = ability.can( diff --git a/src/proposals/proposals.controller.ts b/src/proposals/proposals.controller.ts index 0deda52fe..ff509c0fc 100644 --- a/src/proposals/proposals.controller.ts +++ b/src/proposals/proposals.controller.ts @@ -99,7 +99,7 @@ export class ProposalsController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsInstanceAccess(user); try { switch (group) { @@ -208,7 +208,7 @@ export class ProposalsController { mergedFilters.where = mergedFilters.where || {}; if (user) { - const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -407,7 +407,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -478,7 +478,7 @@ export class ProposalsController { const fields: IProposalFields = JSON.parse(filters.fields ?? "{}"); const facets = JSON.parse(filters.facets ?? "[]"); if (user) { - const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsInstanceAccess(user); const canViewAll = ability.can(Action.ProposalsReadAny, ProposalClass); if (!canViewAll) { @@ -869,7 +869,7 @@ export class ProposalsController { @Param("pid") proposalId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.proposalsDataInstanceAccess(user); + const ability = this.caslAbilityFactory.proposalsInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); diff --git a/src/published-data/published-data.controller.ts b/src/published-data/published-data.controller.ts index 3bd9e9f2c..3d8199c7d 100644 --- a/src/published-data/published-data.controller.ts +++ b/src/published-data/published-data.controller.ts @@ -69,7 +69,7 @@ export class PublishedDataController { // POST /publisheddata @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Create, PublishedData), ) @Post() @@ -155,7 +155,7 @@ export class PublishedDataController { // GET /publisheddata/formpopulate @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Read, PublishedData), ) @Get("/formpopulate") @@ -221,7 +221,7 @@ export class PublishedDataController { // PATCH /publisheddata/:id @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @Patch("/:id") @@ -237,7 +237,7 @@ export class PublishedDataController { // DELETE /publisheddata/:id @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Delete, PublishedData), ) @Delete("/:id") @@ -247,7 +247,7 @@ export class PublishedDataController { // POST /publisheddata/:id/register @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @Post("/:id/register") @@ -428,7 +428,7 @@ export class PublishedDataController { // POST /publisheddata/:id/resync @UseGuards(PoliciesGuard) - @CheckPolicies("publishedData", (ability: AppAbility) => + @CheckPolicies("publisheddata", (ability: AppAbility) => ability.can(Action.Update, PublishedData), ) @ApiOperation({ diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 66c680a5e..030960896 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -97,7 +97,7 @@ export class SamplesController { ); const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesInstanceAccess(user); try { switch (group) { @@ -198,7 +198,7 @@ export class SamplesController { /* eslint-disable @typescript-eslint/no-explicit-any */ const authorizationFilter: Record = { where: {} }; if (user) { - const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { const canViewAccess = ability.can( @@ -356,7 +356,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -427,7 +427,7 @@ export class SamplesController { const fields: ISampleFields = JSON.parse(filters.fields ?? "{}"); const limits: ILimitsFilter = JSON.parse(filters.limits ?? "{}"); if (user) { - const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesInstanceAccess(user); const canViewAll = ability.can(Action.SampleReadAny, SampleClass); if (!canViewAll) { @@ -870,7 +870,7 @@ export class SamplesController { @Param("id") sampleId: string, ): Promise { const user: JWTUser = request.user as JWTUser; - const ability = this.caslAbilityFactory.samplesDataInstanceAccess(user); + const ability = this.caslAbilityFactory.samplesInstanceAccess(user); const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass); const fields: IDatasetFields = JSON.parse("{}"); From 27d06181cdfdb49c79a1dde8fa15386855ef4533 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 7 Aug 2024 17:21:29 +0200 Subject: [PATCH 162/258] build: added sdk generate & publish github workflow --- .github/workflows/publish-packages.yml | 105 +++++++++++++++++++++++++ scripts/generate-sdk-local.sh | 24 ++++++ scripts/python-sdk.json | 8 ++ scripts/typescript-sdk.json | 9 +++ 4 files changed, 146 insertions(+) create mode 100644 .github/workflows/publish-packages.yml create mode 100755 scripts/generate-sdk-local.sh create mode 100644 scripts/python-sdk.json create mode 100644 scripts/typescript-sdk.json diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml new file mode 100644 index 000000000..a37967a6e --- /dev/null +++ b/.github/workflows/publish-packages.yml @@ -0,0 +1,105 @@ +name: Generate and Publish SDK for multiple languages + +on: + push: + branches: + - release + +env: + NODE_VERSION: 18.x + +jobs: + generate-sdk: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{env.NODE_VERSION}} + + - name: Run docker-compose + run: | + cp CI/ESS/e2e/docker-compose.e2e.yaml docker-compose.yaml + docker compose pull + docker compose build --no-cache + docker compose up -d + + - name: Wait for Backend + run: | + npm install -g wait-on + wait-on http://localhost:3000/api/v3/health --timeout 200000 + + - name: Run SDK generation script + run: ./scripts/generate-sdk-local.sh + + - name: Fix permissions for SDK directory + run: sudo chown -R $USER:$USER ./sdk + + - name: Upload generated SDK JSON + uses: actions/upload-artifact@v3 + with: + name: sdk + path: ./sdk + + npm-publish: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: "https://registry.npmjs.org/" + + - name: Publish SDK to npm + run: | + npm install + npm run build + cd dist && npm publish --access public + working-directory: ./sdk/typescript + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + pypi-publish: + needs: generate-sdk + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/Scicat-Python-SDK + permissions: + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download generated SDK + uses: actions/download-artifact@v3 + with: + name: sdk + path: ./sdk/ + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel + working-directory: ./sdk/python + + - name: Build package + run: | + python setup.py sdist bdist_wheel + working-directory: ./sdk/python + + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: ./sdk/python/dist/ diff --git a/scripts/generate-sdk-local.sh b/scripts/generate-sdk-local.sh new file mode 100755 index 000000000..a67de7fdb --- /dev/null +++ b/scripts/generate-sdk-local.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +# Download the Swagger schema +curl -o ./swagger-schema.json http://localhost:3000/explorer-json + +# Remove the existing SDK directory if it exists +rm -rf ./sdk + +docker run \ + --rm \ + -v "${PWD}":/local \ + openapitools/openapi-generator-cli generate \ + -c /local/scripts/typescript-sdk.json \ + +docker run \ + --rm \ + -v "${PWD}":/local \ + openapitools/openapi-generator-cli generate \ + -c /local/scripts/python-sdk.json \ + +# Remove the Swagger schema file +rm ./swagger-schema.json \ No newline at end of file diff --git a/scripts/python-sdk.json b/scripts/python-sdk.json new file mode 100644 index 000000000..86b93db08 --- /dev/null +++ b/scripts/python-sdk.json @@ -0,0 +1,8 @@ +{ + "packageName": "Scicat-Python-SDK", + "projectName": "Scicat-Python-SDK", + "packageVerion": "0.0.1", + "inputSpec": "/local/swagger-schema.json", + "generatorName": "python", + "outputDir": "/local/sdk/python" +} diff --git a/scripts/typescript-sdk.json b/scripts/typescript-sdk.json new file mode 100644 index 000000000..f21039ee1 --- /dev/null +++ b/scripts/typescript-sdk.json @@ -0,0 +1,9 @@ +{ + "npmName": "@scicat-sdk/typescript-angular", + "npmVersion": "0.0.7", + "ngVersion": "16.2.12", + "withInterfaces": true, + "inputSpec": "/local/swagger-schema.json", + "generatorName": "typescript-angular", + "outputDir": "/local/sdk/typescript" +} From 2ee40a12dbd65c3e74cf8e8f6d79392d7159ed22 Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Fri, 9 Aug 2024 11:50:03 +0200 Subject: [PATCH 163/258] update MongoDB image and start backend server --- .github/workflows/publish-packages.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index a37967a6e..298fa136f 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -20,13 +20,17 @@ jobs: with: node-version: ${{env.NODE_VERSION}} - - name: Run docker-compose + - name: Pull MongoDB Image run: | - cp CI/ESS/e2e/docker-compose.e2e.yaml docker-compose.yaml - docker compose pull - docker compose build --no-cache - docker compose up -d - + docker pull mongo:latest + docker run -d --name mongo-container -p 27017:27017 mongo:latest + - name: Start Backend + env: + MONGODB_URI: "mongodb://localhost:27017/scicat" + JWT_SECRET: thisIsTheJwtSecret + run: | + npm install + npm run start - name: Wait for Backend run: | npm install -g wait-on @@ -39,9 +43,9 @@ jobs: run: sudo chown -R $USER:$USER ./sdk - name: Upload generated SDK JSON - uses: actions/upload-artifact@v3 + uses: actions/cache@v3 with: - name: sdk + key: sdk path: ./sdk npm-publish: From 9aed60f81cd81fdf9f9f5b027d109eb6e31b4ded Mon Sep 17 00:00:00 2001 From: Jay Quan Date: Mon, 12 Aug 2024 17:24:27 +0200 Subject: [PATCH 164/258] - added publish-sdk-packages workflow - added script to sync sdk version with package version from package.json --- .../openapi/python-config.json | 6 +- .github/openapi/typescript-config.json | 7 + .github/workflows/github-tag-and-release.yml | 3 +- .github/workflows/publish-packages.yml | 109 ------------ .github/workflows/publish-sdk-packages.yml | 155 ++++++++++++++++++ scripts/generate-sdk-local.sh | 24 --- scripts/typescript-sdk.json | 9 - scripts/update-sdk-versions.js | 41 +++++ 8 files changed, 207 insertions(+), 147 deletions(-) rename scripts/python-sdk.json => .github/openapi/python-config.json (50%) create mode 100644 .github/openapi/typescript-config.json delete mode 100644 .github/workflows/publish-packages.yml create mode 100644 .github/workflows/publish-sdk-packages.yml delete mode 100755 scripts/generate-sdk-local.sh delete mode 100644 scripts/typescript-sdk.json create mode 100644 scripts/update-sdk-versions.js diff --git a/scripts/python-sdk.json b/.github/openapi/python-config.json similarity index 50% rename from scripts/python-sdk.json rename to .github/openapi/python-config.json index 86b93db08..931f018fc 100644 --- a/scripts/python-sdk.json +++ b/.github/openapi/python-config.json @@ -1,8 +1,6 @@ { + "generatorName": "python", "packageName": "Scicat-Python-SDK", "projectName": "Scicat-Python-SDK", - "packageVerion": "0.0.1", - "inputSpec": "/local/swagger-schema.json", - "generatorName": "python", - "outputDir": "/local/sdk/python" + "packageVersion": "0.0.0" } diff --git a/.github/openapi/typescript-config.json b/.github/openapi/typescript-config.json new file mode 100644 index 000000000..42818108b --- /dev/null +++ b/.github/openapi/typescript-config.json @@ -0,0 +1,7 @@ +{ + "generatorName": "typescript-angular", + "npmName": "@scicat-sdk/typescript-angular", + "npmVersion": "0.0.0", + "ngVersion": "16.2.12", + "withInterfaces": true +} diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml index 2e5e00c76..6b3ddb5cc 100644 --- a/.github/workflows/github-tag-and-release.yml +++ b/.github/workflows/github-tag-and-release.yml @@ -1,4 +1,5 @@ -name: Bump version +name: Bump release version and build-push + on: push: branches: diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml deleted file mode 100644 index 298fa136f..000000000 --- a/.github/workflows/publish-packages.yml +++ /dev/null @@ -1,109 +0,0 @@ -name: Generate and Publish SDK for multiple languages - -on: - push: - branches: - - release - -env: - NODE_VERSION: 18.x - -jobs: - generate-sdk: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{env.NODE_VERSION}} - - - name: Pull MongoDB Image - run: | - docker pull mongo:latest - docker run -d --name mongo-container -p 27017:27017 mongo:latest - - name: Start Backend - env: - MONGODB_URI: "mongodb://localhost:27017/scicat" - JWT_SECRET: thisIsTheJwtSecret - run: | - npm install - npm run start - - name: Wait for Backend - run: | - npm install -g wait-on - wait-on http://localhost:3000/api/v3/health --timeout 200000 - - - name: Run SDK generation script - run: ./scripts/generate-sdk-local.sh - - - name: Fix permissions for SDK directory - run: sudo chown -R $USER:$USER ./sdk - - - name: Upload generated SDK JSON - uses: actions/cache@v3 - with: - key: sdk - path: ./sdk - - npm-publish: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - registry-url: "https://registry.npmjs.org/" - - - name: Publish SDK to npm - run: | - npm install - npm run build - cd dist && npm publish --access public - working-directory: ./sdk/typescript - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - pypi-publish: - needs: generate-sdk - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/Scicat-Python-SDK - permissions: - id-token: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Download generated SDK - uses: actions/download-artifact@v3 - with: - name: sdk - path: ./sdk/ - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.x" - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel - working-directory: ./sdk/python - - - name: Build package - run: | - python setup.py sdist bdist_wheel - working-directory: ./sdk/python - - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: ./sdk/python/dist/ diff --git a/.github/workflows/publish-sdk-packages.yml b/.github/workflows/publish-sdk-packages.yml new file mode 100644 index 000000000..8331a9951 --- /dev/null +++ b/.github/workflows/publish-sdk-packages.yml @@ -0,0 +1,155 @@ +name: Generate and Publish SDK for multiple languages + +on: + workflow_run: + workflows: ["Bump release version and build-push"] + types: + - completed + +env: + NODE_VERSION: 18.x + PYTHON_VERSION: 3.x + +jobs: + start-backend-and-upload-swagger-schema: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{env.NODE_VERSION}} + + - name: Pull MongoDB Image + run: | + docker pull mongo:latest + docker run -d --name mongo-container -p 27017:27017 mongo:latest + + - name: Install Backend and wait for it to be ready + env: + MONGODB_URI: "mongodb://localhost:27017/scicat" + JWT_SECRET: thisIsTheJwtSecret + run: | + npm install -g wait-on && npm install + npm run start & wait-on http://localhost:3000/api/v3/health --timeout 200000 + + - name: Download the Swagger schema + run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json + + - name: Update SDK Version for each language in Config Files + run: node scripts/update-sdk-versions.js + + - uses: actions/upload-artifact@v4 + with: + name: swagger-schema + path: ./swagger-schema.json + + - uses: actions/upload-artifact@v4 + with: + name: updated-configs + path: .github/openapi/ + + generate-and-upload-sdk: + runs-on: ubuntu-latest + needs: start-backend-and-upload-swagger-schema + strategy: + matrix: + generator: [python, typescript] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: swagger-schema + path: . + - uses: actions/download-artifact@v4 + with: + name: updated-configs + path: .github/openapi/ + + - name: Generate Client + uses: openapi-generators/openapitools-generator-action@v1 + with: + generator: ${{ matrix.generator }} + openapi-file: ./swagger-schema.json + config-file: .github/openapi/${{ matrix.generator }}-config.json + command-args: -o ./sdk/${{ matrix.generator }} + + - uses: actions/upload-artifact@v4 + with: + name: sdk-${{ matrix.generator }} + path: ./sdk + + npm-publish: + needs: generate-and-upload-sdk + runs-on: ubuntu-latest + environment: + name: npm-sdk-package + url: https://www.npmjs.com/package/@scicat-sdk/typescript-angular + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: "https://registry.npmjs.org/" + + - uses: actions/download-artifact@v4 + with: + name: sdk-typescript + path: ./sdk + + - name: Publish package + run: | + npm install + npm run build + npm publish --access public + working-directory: ./sdk/typescript/ + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + pypi-publish: + needs: generate-and-upload-sdk + runs-on: ubuntu-latest + environment: + name: pypi-sdk-package + url: https://pypi.org/p/Scicat-Python-SDK + permissions: + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - uses: actions/download-artifact@v4 + with: + name: sdk-python + path: ./sdk + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel + working-directory: ./sdk/python/ + + - name: Build package + run: | + python setup.py sdist bdist_wheel + working-directory: ./sdk/python/ + + - name: Publish package + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: ./sdk/python/dist/ diff --git a/scripts/generate-sdk-local.sh b/scripts/generate-sdk-local.sh deleted file mode 100755 index a67de7fdb..000000000 --- a/scripts/generate-sdk-local.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -set -e - -# Download the Swagger schema -curl -o ./swagger-schema.json http://localhost:3000/explorer-json - -# Remove the existing SDK directory if it exists -rm -rf ./sdk - -docker run \ - --rm \ - -v "${PWD}":/local \ - openapitools/openapi-generator-cli generate \ - -c /local/scripts/typescript-sdk.json \ - -docker run \ - --rm \ - -v "${PWD}":/local \ - openapitools/openapi-generator-cli generate \ - -c /local/scripts/python-sdk.json \ - -# Remove the Swagger schema file -rm ./swagger-schema.json \ No newline at end of file diff --git a/scripts/typescript-sdk.json b/scripts/typescript-sdk.json deleted file mode 100644 index f21039ee1..000000000 --- a/scripts/typescript-sdk.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "npmName": "@scicat-sdk/typescript-angular", - "npmVersion": "0.0.7", - "ngVersion": "16.2.12", - "withInterfaces": true, - "inputSpec": "/local/swagger-schema.json", - "generatorName": "typescript-angular", - "outputDir": "/local/sdk/typescript" -} diff --git a/scripts/update-sdk-versions.js b/scripts/update-sdk-versions.js new file mode 100644 index 000000000..a52302070 --- /dev/null +++ b/scripts/update-sdk-versions.js @@ -0,0 +1,41 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const fs = require("fs"); + +// Paths to the OpenAPI Generator config files +const configPaths = { + typescript: ".github/openapi/typescript-config.json", + python: ".github/openapi/python-config.json", +}; + +// Function to read and parse JSON files +const readJsonFile = (filePath) => { + return JSON.parse(fs.readFileSync(filePath, "utf8")); +}; + +// Function to write JSON objects to files +const writeJsonFile = (filePath, jsonObject) => { + fs.writeFileSync(filePath, JSON.stringify(jsonObject, null, 2), "utf8"); +}; + +// Get the version from the root package.json +const packageJson = readJsonFile("package.json"); +const packageVersion = packageJson.version; + +for (const [key, configFilePath] of Object.entries(configPaths)) { + const configJson = readJsonFile(configFilePath); + + // Update the relevant version field + switch (key) { + case "typescript": + configJson.npmVersion = packageVersion; + break; + case "python": + configJson.packageVersion = packageVersion; + break; + } + + // Write the updated config back to the file + writeJsonFile(configFilePath, configJson); +} + +console.log(`Updated configs with version: ${packageVersion}`); From 3a2f860d6478f5ce6c0591bbe39d8119ed572eb5 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 13 Aug 2024 12:05:17 +0200 Subject: [PATCH 165/258] added steps to sync packages version with project version --- .github/openapi/python-config.json | 3 +- .github/openapi/typescript-config.json | 1 - .github/workflows/publish-sdk-packages.yml | 25 ++++++++++++- scripts/update-sdk-versions.js | 41 ---------------------- 4 files changed, 25 insertions(+), 45 deletions(-) delete mode 100644 scripts/update-sdk-versions.js diff --git a/.github/openapi/python-config.json b/.github/openapi/python-config.json index 931f018fc..1323b5f58 100644 --- a/.github/openapi/python-config.json +++ b/.github/openapi/python-config.json @@ -1,6 +1,5 @@ { "generatorName": "python", "packageName": "Scicat-Python-SDK", - "projectName": "Scicat-Python-SDK", - "packageVersion": "0.0.0" + "projectName": "Scicat-Python-SDK" } diff --git a/.github/openapi/typescript-config.json b/.github/openapi/typescript-config.json index 42818108b..4248aecec 100644 --- a/.github/openapi/typescript-config.json +++ b/.github/openapi/typescript-config.json @@ -1,7 +1,6 @@ { "generatorName": "typescript-angular", "npmName": "@scicat-sdk/typescript-angular", - "npmVersion": "0.0.0", "ngVersion": "16.2.12", "withInterfaces": true } diff --git a/.github/workflows/publish-sdk-packages.yml b/.github/workflows/publish-sdk-packages.yml index 8331a9951..620bb6f7e 100644 --- a/.github/workflows/publish-sdk-packages.yml +++ b/.github/workflows/publish-sdk-packages.yml @@ -13,6 +13,8 @@ env: jobs: start-backend-and-upload-swagger-schema: runs-on: ubuntu-latest + outputs: + current-version: ${{ steps.package-version.outputs.current-version }} steps: - name: Checkout repository uses: actions/checkout@v4 @@ -22,6 +24,10 @@ jobs: with: node-version: ${{env.NODE_VERSION}} + - name: get-npm-version + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + - name: Pull MongoDB Image run: | docker pull mongo:latest @@ -62,6 +68,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Set packageVersion variable + run: echo "packageVersion=${{ needs.start-backend-and-upload-swagger-schema.outputs.current-version }}" >> $GITHUB_ENV + - uses: actions/download-artifact@v4 with: name: swagger-schema @@ -71,13 +80,27 @@ jobs: name: updated-configs path: .github/openapi/ + - name: Check packageVersion + run: | + if [ -z "$packageVersion" ]; then + echo "packageVersion is not set, exiting..." + exit 1 + fi + - name: Generate Client uses: openapi-generators/openapitools-generator-action@v1 with: generator: ${{ matrix.generator }} openapi-file: ./swagger-schema.json config-file: .github/openapi/${{ matrix.generator }}-config.json - command-args: -o ./sdk/${{ matrix.generator }} + command-args: | + -o ./sdk/${{ matrix.generator }} $( + if [ "${{ matrix.generator }}" == "typescript" ]; then + echo "--additional-properties=npmVersion=$packageVersion"; + elif [ "${{ matrix.generator }}" == "python" ]; then + echo "--additional-properties=packageVersion=$packageVersion"; + fi + ) - uses: actions/upload-artifact@v4 with: diff --git a/scripts/update-sdk-versions.js b/scripts/update-sdk-versions.js deleted file mode 100644 index a52302070..000000000 --- a/scripts/update-sdk-versions.js +++ /dev/null @@ -1,41 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const fs = require("fs"); - -// Paths to the OpenAPI Generator config files -const configPaths = { - typescript: ".github/openapi/typescript-config.json", - python: ".github/openapi/python-config.json", -}; - -// Function to read and parse JSON files -const readJsonFile = (filePath) => { - return JSON.parse(fs.readFileSync(filePath, "utf8")); -}; - -// Function to write JSON objects to files -const writeJsonFile = (filePath, jsonObject) => { - fs.writeFileSync(filePath, JSON.stringify(jsonObject, null, 2), "utf8"); -}; - -// Get the version from the root package.json -const packageJson = readJsonFile("package.json"); -const packageVersion = packageJson.version; - -for (const [key, configFilePath] of Object.entries(configPaths)) { - const configJson = readJsonFile(configFilePath); - - // Update the relevant version field - switch (key) { - case "typescript": - configJson.npmVersion = packageVersion; - break; - case "python": - configJson.packageVersion = packageVersion; - break; - } - - // Write the updated config back to the file - writeJsonFile(configFilePath, configJson); -} - -console.log(`Updated configs with version: ${packageVersion}`); From b916e3a23c53327a8cc1481df550901b4392f1c1 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 13 Aug 2024 13:51:22 +0200 Subject: [PATCH 166/258] remove unused steps --- .github/workflows/publish-sdk-packages.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/publish-sdk-packages.yml b/.github/workflows/publish-sdk-packages.yml index 620bb6f7e..fc0bc77ad 100644 --- a/.github/workflows/publish-sdk-packages.yml +++ b/.github/workflows/publish-sdk-packages.yml @@ -44,19 +44,11 @@ jobs: - name: Download the Swagger schema run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json - - name: Update SDK Version for each language in Config Files - run: node scripts/update-sdk-versions.js - - uses: actions/upload-artifact@v4 with: name: swagger-schema path: ./swagger-schema.json - - uses: actions/upload-artifact@v4 - with: - name: updated-configs - path: .github/openapi/ - generate-and-upload-sdk: runs-on: ubuntu-latest needs: start-backend-and-upload-swagger-schema @@ -75,10 +67,6 @@ jobs: with: name: swagger-schema path: . - - uses: actions/download-artifact@v4 - with: - name: updated-configs - path: .github/openapi/ - name: Check packageVersion run: | From c07a9e08d02ac0dce34ab66547933bf336a201a8 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 9 Aug 2024 13:39:19 +0200 Subject: [PATCH 167/258] Added start time to dataset dto and fixed description of timestamps --- src/datasets/dto/update-dataset.dto.ts | 2 +- src/datasets/dto/update-raw-dataset.dto.ts | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index aa681784b..aab14a7e5 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -137,7 +137,7 @@ export class UpdateDatasetDto extends OwnableDto { type: Date, required: true, description: - "Time when dataset became fully available on disk, i.e. all containing files have been written. Format according to chapter 5.6 internet date/time format in RFC 3339. Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + "Time when dataset became fully available on disk, i.e. all containing files have been written, or the dataset was created in SciCat.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", }) @IsDateString() readonly creationTime: Date; diff --git a/src/datasets/dto/update-raw-dataset.dto.ts b/src/datasets/dto/update-raw-dataset.dto.ts index 241e124b8..a03fa14ad 100644 --- a/src/datasets/dto/update-raw-dataset.dto.ts +++ b/src/datasets/dto/update-raw-dataset.dto.ts @@ -17,7 +17,17 @@ export class UpdateRawDatasetDto extends UpdateDatasetDto { type: Date, required: false, description: - "End time of data acquisition for this dataset, format according to chapter 5.6 internet date/time format in RFC 3339. Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly startTime?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", }) @IsOptional() @IsDateString() From e643e3d97e55320ec17b3d3ef1382aa05687ea27 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 9 Aug 2024 13:43:32 +0200 Subject: [PATCH 168/258] added startTime to dataset schema --- src/datasets/schemas/dataset.schema.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 239987347..d1d613d3e 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -418,7 +418,16 @@ export class DatasetClass extends OwnableClass { type: Date, required: false, description: - "End time of data acquisition for this dataset, format according to chapter 5.6 internet date/time format in RFC 3339. Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @Prop({ type: Date, required: false }) + startTime?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", }) @Prop({ type: Date, required: false }) endTime?: Date; From 159b8542de8eeea9207a2315160fa053aaf99b88 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 9 Aug 2024 13:44:35 +0200 Subject: [PATCH 169/258] fixed description of timestamp fields --- src/datasets/schemas/dataset.schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index d1d613d3e..74c29aaa7 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -196,7 +196,7 @@ export class DatasetClass extends OwnableClass { type: Date, required: true, description: - "Time when dataset became fully available on disk, i.e. all containing files have been written. Format according to chapter 5.6 internet date/time format in RFC 3339. Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + "Time when dataset became fully available on disk, i.e. all containing files have been written, or the dataset was created in SciCat.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", }) @Prop({ type: Date, required: true, index: true }) creationTime: Date; From f0cb8e5c7ca606989067ba0700baab4f0de7fc65 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 9 Aug 2024 14:14:24 +0200 Subject: [PATCH 170/258] Added startTime to test data --- test/TestData.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/TestData.js b/test/TestData.js index 91fd1bb28..9b8e0f5fb 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -6,6 +6,12 @@ const TestAccounts = Object.fromEntries( RawTestAccounts.map((account) => [account.username, account]), ); +const DatasetDates = faker.date.betweens({ + from: faker.date.recent({ days: 15 }).toISOString(), + to: faker.date.recent({ days: 10 }).toISOString(), + count: 2, +}); + const TestData = { EntryCreatedStatusCode: 201, EntryValidStatusCode: 200, @@ -117,6 +123,7 @@ const TestData = { RawCorrect: { principalInvestigator: "scicatingestor@your.site", + startTime: "2011-09-14T05:29:11.000Z", endTime: "2011-09-14T06:31:25.000Z", creationLocation: "/SU/XQX/RAMJET", dataFormat: "Upchuck pre 2017", @@ -199,7 +206,8 @@ const TestData = { RawCorrectRandom: { principalInvestigator: faker.internet.email(), - endTime: faker.date.past().toISOString(), + startTime: DatasetDates[0], + endTime: DatasetDates[1], creationLocation: faker.system.directoryPath(), dataFormat: faker.lorem.words(3), scientificMetadata: { @@ -299,6 +307,7 @@ const TestData = { RawWrong_2: { principalInvestigator: "bertram.astor@grumble.com", + startTime: "2011-09-15T02:13:52.000Z", endTime: "2011-09-14T06:31:25.000Z", creationLocation: "/SU/XQX/RAMJET", dataFormat: "Upchuck pre 2017", From 8ca1eae3f9b5ce116a01dee412b59a092152e2fb Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 22 Aug 2024 13:06:37 +0200 Subject: [PATCH 171/258] fix fluffy fake data for testing --- test/TestData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestData.js b/test/TestData.js index 9b8e0f5fb..538f657bf 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -8,7 +8,7 @@ const TestAccounts = Object.fromEntries( const DatasetDates = faker.date.betweens({ from: faker.date.recent({ days: 15 }).toISOString(), - to: faker.date.recent({ days: 10 }).toISOString(), + to: faker.date.soon({ days: 10 }).toISOString(), count: 2, }); From e873fbeffbc5874f58b4323e16c102c65f666de1 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 22 Aug 2024 19:22:00 +0200 Subject: [PATCH 172/258] Updated frontend config with fake url --- src/config/frontend.config.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 9ae4a1688..39ec77d8b 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -143,7 +143,7 @@ "label": "Download All", "files": "all", "mat_icon": "download", - "url": "", + "url": "https://www.scicat.info/download/all", "target": "_blank", "enabled": "#SizeLimit", "authorization": ["#datasetAccess", "#datasetPublic"] @@ -154,7 +154,7 @@ "label": "Download Selected", "files": "selected", "mat_icon": "download", - "url": "", + "url": "https://www.scicat.info/download/selected", "target": "_blank", "enabled": "#Selected && #SizeLimit", "authorization": ["#datasetAccess", "#datasetPublic"] @@ -165,7 +165,7 @@ "label": "Notebook All", "files": "all", "icon": "/assets/icons/jupyter_logo.png", - "url": "", + "url": "https://www.scicat.info/notebook/all", "target": "_blank", "authorization": ["#datasetAccess", "#datasetPublic"] }, @@ -175,7 +175,7 @@ "label": "Notebook Selected", "files": "selected", "icon": "/assets/icons/jupyter_logo.png", - "url": "", + "url": "https://www.scicat.info/notebook/all", "target": "_blank", "enabled": "#Selected", "authorization": ["#datasetAccess", "#datasetPublic"] From 90ac4357d3cb5952173aef384f719c818c3b5771 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 23 Aug 2024 18:01:29 +0200 Subject: [PATCH 173/258] fixed permissions on user identities and improved swagger documentation --- src/common/utils.ts | 15 +++++ src/users/user-identities.controller.ts | 76 ++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index 3a872ff3f..9480ab61c 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -925,6 +925,21 @@ export const samplesFullQueryDescriptionFields = }\n \ '; +export const filterUserIdentityExample = '{ "where": { "field": "value" }}'; + +export const filterUserIdentityDescription = + '
\n \
+{\n \
+  "field": "value"\n \
+}\n \
+  or \n \
+{\n \
+  "where?": {\n \
+    "field": "value"\n \
+  }\n \
+}\
+
'; + export const parseBoolean = (v: unknown): boolean => { switch (v) { case true: diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index 99fa923f2..e2827fec7 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -8,7 +8,13 @@ import { Req, UseGuards, } from "@nestjs/common"; -import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; +import { + ApiBearerAuth, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, +} from "@nestjs/swagger"; import { Action } from "src/casl/action.enum"; import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; @@ -18,6 +24,11 @@ import { Request } from "express"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { User } from "./schemas/user.schema"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; +import { boolean } from "mathjs"; +import { + filterUserIdentityDescription, + filterUserIdentityExample, +} from "src/common/utils"; @ApiBearerAuth() @ApiTags("user identities") @@ -36,6 +47,27 @@ export class UserIdentitiesController { ability.can(Action.UserReadAny, User), ) @Get("/findOne") + @ApiOperation({ + summary: + "It returns the user identity profile of the first user matching the query", + description: + "This endpoint returns the user identity profile of the first user matching teh condition", + }) + @ApiQuery({ + name: "filter", + description: + "Full database filters to apply when checking for the email. The filter can be just the where clause or the full filter syntax\n" + + filterUserIdentityDescription, + required: false, + type: String, + example: filterUserIdentityExample, + }) + @ApiResponse({ + status: 201, + type: boolean, + description: + "Results is true if a registered user exists that have the emailed provided listed as main email", + }) async findOne( // NOTE: This now supports both headers filter and query filter. // There is a loopback config file where we have this as a setting on the frontend. @@ -89,7 +121,31 @@ export class UserIdentitiesController { } @UseGuards(AuthenticatedPoliciesGuard) + @CheckPolicies("users", (ability: AppAbility) => + ability.can(Action.UserReadAny, User), + ) @Get("/isValidEmail") + @ApiOperation({ + summary: + "It returns true if the emailed passed in is linked to any registered users", + description: + "This endpoint check if the email passed in as parameter is a valid email tight to a known user that have a record in this instance of SciCat", + }) + @ApiQuery({ + name: "filter", + description: + "Email to be checked or or full database filters to apply when checking for the email\n" + + filterUserIdentityDescription, + required: false, + type: String, + example: filterUserIdentityExample, + }) + @ApiResponse({ + status: 201, + type: boolean, + description: + "Results is true if a registered user exists that have the emailed provided listed as main email", + }) async isValidEmail( // NOTE: This now supports both headers filter and query filter. // There is a loopback config file where we have this as a setting on the frontend. @@ -97,7 +153,17 @@ export class UserIdentitiesController { @Headers() headers: Record, @Query("filter") queryFilters?: string, ): Promise { - const parsedQueryFilters = JSON.parse(queryFilters ?? "{}"); + let parsedQueryFilters; + try { + parsedQueryFilters = JSON.parse(queryFilters ?? "{}"); + } catch { + parsedQueryFilters = { + where: { + "profile.email": queryFilters, + }, + }; + } + let filter = {}; if (headers.filter) { const parsedFilter = JSON.parse(headers.filter); @@ -112,10 +178,6 @@ export class UserIdentitiesController { filter, )) as UserIdentity; - if (!identity) { - return false; - } - - return true; + return identity ? true : false; } } From 213d0dfa92b67ed20ee2ee2f03f09ca35b64e8c4 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 26 Aug 2024 11:25:09 +0200 Subject: [PATCH 174/258] fix(casl-ability): correct instrument endpoint access for unauthenticated users (#1393) --- src/casl/casl-ability.factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index b2e3e1821..628beabf4 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -298,7 +298,7 @@ export class CaslAbilityFactory { ); if (!user) { - cannot(Action.InstrumentRead, Instrument); + can(Action.InstrumentRead, Instrument); cannot(Action.InstrumentCreate, Instrument); cannot(Action.InstrumentUpdate, Instrument); cannot(Action.InstrumentDelete, Instrument); From fac6db39435f5e9978cf15f9ece3aa7cef0d50c5 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Mon, 26 Aug 2024 13:23:16 +0200 Subject: [PATCH 175/258] Fixed user identities endpoints descriptions and examples --- src/common/utils.ts | 27 ++++++++++++++++--------- src/users/user-identities.controller.ts | 4 ++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index 9480ab61c..f30ec2734 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -925,19 +925,28 @@ export const samplesFullQueryDescriptionFields = }\n \ '; -export const filterUserIdentityExample = '{ "where": { "field": "value" }}'; +export const filterUserIdentityExample = + '{ "profile.email": "this_email@your.site" }'; export const filterUserIdentityDescription = '
\n \
-{\n \
-  "field": "value"\n \
-}\n \
-  or \n \
-{\n \
-  "where?": {\n \
-    "field": "value"\n \
+  this_email@some.site\n \
+or \n \
+  {\n \
+    "email": "this_email@some.site"\n \
+  }\n \
+or \n \
+  {\n \
+    "profile.email": "this_email@some.site"\n \
+  }\n \
+or \n \
+  {\n \
+    "where?": {\n \
+      "profile.email": "this_email@some.site"\n \
+    }\n \
   }\n \
-}\
+This last version is deprecated and will be discontinued as soon as the FE is updated.\n \
+It has been maintanined for backward compatibility.\n \
 
'; export const parseBoolean = (v: unknown): boolean => { diff --git a/src/users/user-identities.controller.ts b/src/users/user-identities.controller.ts index e2827fec7..9a4105710 100644 --- a/src/users/user-identities.controller.ts +++ b/src/users/user-identities.controller.ts @@ -129,12 +129,12 @@ export class UserIdentitiesController { summary: "It returns true if the emailed passed in is linked to any registered users", description: - "This endpoint check if the email passed in as parameter is a valid email tight to a known user that have a record in this instance of SciCat", + "This endpoint check if the email passed in as parameter is a valid email connected to a known user that has a record in this instance of SciCat", }) @ApiQuery({ name: "filter", description: - "Email to be checked or or full database filters to apply when checking for the email\n" + + "Email to be checked or full filter format query to apply when checking for the email\n" + filterUserIdentityDescription, required: false, type: String, From 6f0c373a6a41e3ead51768bdf5d7af42e86182eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:54:40 +0000 Subject: [PATCH 176/258] build(deps): bump mathjs from 13.0.3 to 13.1.0 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.0.3 to 13.1.0. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.0.3...v13.1.0) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99371d1ac..e60e1cfc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -842,9 +842,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -9478,11 +9478,11 @@ } }, "node_modules/mathjs": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.0.3.tgz", - "integrity": "sha512-GpP9OW6swA5POZXvgpc/1FYkAr8lKgV04QHS1tIU60klFfplVCYaNzn6qy0vSp0hAQQN7shcx9CeB507dlLujA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.1.0.tgz", + "integrity": "sha512-5BI//cQdcKtDgstJ3QbKYyrWLyUEEHY9ZQgA3laaPyTis+ca8Y7GCxbLFFLYv8nkpOFTIF55FLKoiqQaufj1dQ==", "dependencies": { - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.4", "complex.js": "^2.1.1", "decimal.js": "^10.4.3", "escape-latex": "^1.2.0", From 4a32a666c120fa1a7c981022e2c69c9867098b2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:05:25 +0000 Subject: [PATCH 177/258] build(deps): bump mongoose from 8.5.3 to 8.5.4 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.3 to 8.5.4. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.5.3...8.5.4) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e60e1cfc3..72f6b53ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10393,9 +10393,9 @@ } }, "node_modules/mongoose": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.3.tgz", - "integrity": "sha512-OubSDbsAclDFGHjV82MsKyIGQWFc42Ot1l+0dhRS6U9xODM7rm/ES/WpOQd8Ds9j0Mx8QzxZtrSCnBh6o9wUqw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.4.tgz", + "integrity": "sha512-nG3eehhWf9l1q80WuHvp5DV+4xDNFpDWLE5ZgcFD5tslUV2USJ56ogun8gaZ62MKAocJnoStjAdno08b8U57hg==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", From c87de81ab41d0f9311fb1724e85b8f23242f64e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:16:01 +0000 Subject: [PATCH 178/258] build(deps-dev): bump @types/chai from 4.3.17 to 4.3.18 Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.3.17 to 4.3.18. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai) --- updated-dependencies: - dependency-name: "@types/chai" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72f6b53ed..4a3d9cd21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2799,9 +2799,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.17", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz", - "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", + "version": "4.3.18", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.18.tgz", + "integrity": "sha512-2UfJzigyNa8kYTKn7o4hNMPphkxtu4WTJyobK3m4FBpyj7EK5xgtPcOtxLm7Dznk/Qxr0QXn+gQbkg7mCZKdfg==", "dev": true }, "node_modules/@types/connect": { From 2f6dfba31e7d90586adea3214d6df333e2725a40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:27:04 +0000 Subject: [PATCH 179/258] build(deps-dev): bump @types/node from 22.4.1 to 22.5.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.4.1 to 22.5.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a3d9cd21..c3825d14a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3001,9 +3001,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.1.tgz", - "integrity": "sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==", + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", "dependencies": { "undici-types": "~6.19.2" } From bd1f3ff75b47d22cbf8ae163e860eb1dfe6a8c44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:43:26 +0000 Subject: [PATCH 180/258] build(deps-dev): bump wait-on from 7.2.0 to 8.0.0 Bumps [wait-on](https://github.com/jeffbski/wait-on) from 7.2.0 to 8.0.0. - [Release notes](https://github.com/jeffbski/wait-on/releases) - [Commits](https://github.com/jeffbski/wait-on/compare/v7.2.0...v8.0.0) --- updated-dependencies: - dependency-name: wait-on dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3825d14a..9b6d811d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.8.3", - "wait-on": "^7.0.1" + "wait-on": "^8.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2633,9 +2633,9 @@ } }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -8728,14 +8728,14 @@ } }, "node_modules/joi": { - "version": "17.11.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz", - "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==", + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "dev": true, "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -13707,13 +13707,13 @@ } }, "node_modules/wait-on": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", - "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.0.tgz", + "integrity": "sha512-fNE5SXinLr2Bt7cJvjvLg2PcXfqznlqRvtE3f8AqYdRZ9BhE+XpsCp1mwQbRoO7s1q7uhAuCw0Ro3mG/KdZjEw==", "dev": true, "dependencies": { - "axios": "^1.6.1", - "joi": "^17.11.0", + "axios": "^1.7.4", + "joi": "^17.13.3", "lodash": "^4.17.21", "minimist": "^1.2.8", "rxjs": "^7.8.1" diff --git a/package.json b/package.json index f81c13691..8bbe9c638 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.8.3", - "wait-on": "^7.0.1" + "wait-on": "^8.0.0" }, "jest": { "moduleFileExtensions": [ From 2a1272ec67f17cd3f46e8c1adeaa0c4804ed294d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:58:08 +0000 Subject: [PATCH 181/258] build(deps): bump @elastic/elasticsearch from 8.13.1 to 8.15.0 Bumps [@elastic/elasticsearch](https://github.com/elastic/elasticsearch-js) from 8.13.1 to 8.15.0. - [Release notes](https://github.com/elastic/elasticsearch-js/releases) - [Changelog](https://github.com/elastic/elasticsearch-js/blob/main/docs/changelog.asciidoc) - [Commits](https://github.com/elastic/elasticsearch-js/compare/v8.13.1...v8.15.0) --- updated-dependencies: - dependency-name: "@elastic/elasticsearch" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b6d811d4..c4fc23023 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1129,11 +1129,11 @@ } }, "node_modules/@elastic/elasticsearch": { - "version": "8.13.1", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.13.1.tgz", - "integrity": "sha512-2G4Vu6OHw4+XTrp7AGIcOEezpPEoVrWg2JTK1v/exEKSLYquZkUdd+m4yOL3/UZ6bTj7hmXwrmYzW76BnLCkJQ==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.15.0.tgz", + "integrity": "sha512-mG90EMdTDoT6GFSdqpUAhWK9LGuiJo6tOWqs0Usd/t15mPQDj7ZqHXfCBqNkASZpwPZpbAYVjd57S6nbUBINCg==", "dependencies": { - "@elastic/transport": "~8.4.1", + "@elastic/transport": "^8.7.0", "tslib": "^2.4.0" }, "engines": { @@ -1141,19 +1141,20 @@ } }, "node_modules/@elastic/transport": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.4.1.tgz", - "integrity": "sha512-/SXVuVnuU5b4dq8OFY4izG+dmGla185PcoqgK6+AJMpmOeY1QYVNbWtCwvSvoAANN5D/wV+EBU8+x7Vf9EphbA==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.7.0.tgz", + "integrity": "sha512-IqXT7a8DZPJtqP2qmX1I2QKmxYyN27kvSW4g6pInESE1SuGwZDp2FxHJ6W2kwmYOJwQdAt+2aWwzXO5jHo9l4A==", "dependencies": { + "@opentelemetry/api": "1.x", "debug": "^4.3.4", "hpagent": "^1.0.0", "ms": "^2.1.3", "secure-json-parse": "^2.4.0", "tslib": "^2.4.0", - "undici": "^5.22.1" + "undici": "^6.12.0" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@elastic/transport/node_modules/ms": { @@ -1255,14 +1256,6 @@ "npm": ">=6.14.13" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", - "engines": { - "node": ">=14" - } - }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2598,6 +2591,14 @@ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", "optional": true }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -13473,14 +13474,11 @@ } }, "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", + "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==", "engines": { - "node": ">=14.0" + "node": ">=18.17" } }, "node_modules/undici-types": { From 9000ad176dbc51b010aead294c4e381cbcd722c3 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 27 Aug 2024 15:58:21 +0200 Subject: [PATCH 182/258] chore: Update @elastic/elasticsearch dependency to version 8.15.0 --- package-lock.json | 2 +- package.json | 2 +- src/elastic-search/elastic-search.service.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4fc23023..6105a1db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "BSD-3-Clause", "dependencies": { "@casl/ability": "^6.3.2", - "@elastic/elasticsearch": "^8.9.0", + "@elastic/elasticsearch": "^8.15.0", "@nestjs-modules/mailer": "^2.0.2", "@nestjs/axios": "^3.0.0", "@nestjs/common": "^10.3.8", diff --git a/package.json b/package.json index 8bbe9c638..2ca16fd70 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@casl/ability": "^6.3.2", - "@elastic/elasticsearch": "^8.9.0", + "@elastic/elasticsearch": "^8.15.0", "@nestjs-modules/mailer": "^2.0.2", "@nestjs/axios": "^3.0.0", "@nestjs/common": "^10.3.8", diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 12a02353f..36d6bb44b 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -262,7 +262,7 @@ export class ElasticSearchService implements OnModuleInit { limit = 20, skip = 0, sort?: Record, - ): Promise<{ totalCount: number; data: string[] }> { + ): Promise<{ totalCount: number; data: (string | undefined)[] }> { const defaultMinScore = searchParam.text ? 1 : 0; try { From cb48b70179fa0058b6587c34f69f4102460022e0 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:22:30 +0200 Subject: [PATCH 183/258] fix for readableStream error --- package.json | 3 +++ test/config/jest.setup.js | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 test/config/jest.setup.js diff --git a/package.json b/package.json index 2ca16fd70..9793fb573 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,9 @@ "wait-on": "^8.0.0" }, "jest": { + "setupFilesAfterEnv": [ + "./test/config/jest.setup.js" + ], "moduleFileExtensions": [ "js", "json", diff --git a/test/config/jest.setup.js b/test/config/jest.setup.js new file mode 100644 index 000000000..009d18510 --- /dev/null +++ b/test/config/jest.setup.js @@ -0,0 +1,2 @@ +import { ReadableStream } from "node:stream/web"; +this.global.ReadableStream = ReadableStream; From 9e126ee84e58e4d8488518e56e1abe4b53df6c68 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:24:26 +0200 Subject: [PATCH 184/258] update jest setup file path in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9793fb573..748681b4c 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ }, "jest": { "setupFilesAfterEnv": [ - "./test/config/jest.setup.js" + "../test/config/jest.setup.js" ], "moduleFileExtensions": [ "js", From 1e90192307d6ca04daf62c75f8842c417a1c0ad8 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:26:06 +0200 Subject: [PATCH 185/258] Fix global assignment of ReadableStream in jest setup file --- test/config/jest.setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/jest.setup.js b/test/config/jest.setup.js index 009d18510..bcaae7d16 100644 --- a/test/config/jest.setup.js +++ b/test/config/jest.setup.js @@ -1,2 +1,2 @@ import { ReadableStream } from "node:stream/web"; -this.global.ReadableStream = ReadableStream; +global.ReadableStream = ReadableStream; From 4b7e34b82df3c8b087a761a960c7a8b07ecd1c3b Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:30:23 +0200 Subject: [PATCH 186/258] update jest-e2e.json configuration --- test/config/jest-e2e.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/jest-e2e.json b/test/config/jest-e2e.json index cf83246b2..45a2bf8e0 100644 --- a/test/config/jest-e2e.json +++ b/test/config/jest-e2e.json @@ -1,4 +1,5 @@ { + "setupFilesAfterEnv": ["jest.setup.js"], "moduleFileExtensions": ["js", "json", "ts"], "rootDir": "../../", "testTimeout": 30000, @@ -16,5 +17,4 @@ "isolatedModules": true } } - } From 717b3ce46deee1224d9d9f15ccb61d5dce5c386c Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:33:01 +0200 Subject: [PATCH 187/258] update jest-e2e.json configuration --- test/config/jest-e2e.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/jest-e2e.json b/test/config/jest-e2e.json index 45a2bf8e0..f4b781d49 100644 --- a/test/config/jest-e2e.json +++ b/test/config/jest-e2e.json @@ -1,5 +1,5 @@ { - "setupFilesAfterEnv": ["jest.setup.js"], + "setupFilesAfterEnv": ["test/config/jest.setup.js"], "moduleFileExtensions": ["js", "json", "ts"], "rootDir": "../../", "testTimeout": 30000, From 5c3bcd80ad38583441b053814770da553efeaeb6 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:34:50 +0200 Subject: [PATCH 188/258] update jest-e2e.json setupFilesAfterEnv path --- test/config/jest-e2e.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/jest-e2e.json b/test/config/jest-e2e.json index f4b781d49..0fb0cd924 100644 --- a/test/config/jest-e2e.json +++ b/test/config/jest-e2e.json @@ -1,5 +1,5 @@ { - "setupFilesAfterEnv": ["test/config/jest.setup.js"], + "setupFilesAfterEnv": ["./test/config/jest.setup.js"], "moduleFileExtensions": ["js", "json", "ts"], "rootDir": "../../", "testTimeout": 30000, From a7558f4955d07a170c4e1af4aca48ab58f3c742b Mon Sep 17 00:00:00 2001 From: junjiequan Date: Fri, 30 Aug 2024 12:39:36 +0200 Subject: [PATCH 189/258] Fix global assignment of ReadableStream in jest setup file --- test/config/jest.setup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/config/jest.setup.js b/test/config/jest.setup.js index bcaae7d16..a861b3a8c 100644 --- a/test/config/jest.setup.js +++ b/test/config/jest.setup.js @@ -1,2 +1,2 @@ -import { ReadableStream } from "node:stream/web"; -global.ReadableStream = ReadableStream; +/* eslint-disable @typescript-eslint/no-var-requires */ +global.ReadableStream = require("node:stream/web").ReadableStream; From 33b4337578b3288c0708626906e7b179ac9cf731 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:49:54 +0000 Subject: [PATCH 190/258] build(deps): bump webpack and @nestjs/cli Bumps [webpack](https://github.com/webpack/webpack) to 5.94.0 and updates ancestor dependency [@nestjs/cli](https://github.com/nestjs/nest-cli). These dependencies need to be updated together. Updates `webpack` from 5.93.0 to 5.94.0 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.93.0...v5.94.0) Updates `@nestjs/cli` from 10.4.4 to 10.4.5 - [Release notes](https://github.com/nestjs/nest-cli/releases) - [Changelog](https://github.com/nestjs/nest-cli/blob/master/.release-it.json) - [Commits](https://github.com/nestjs/nest-cli/compare/10.4.4...10.4.5) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect - dependency-name: "@nestjs/cli" dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package-lock.json | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6105a1db3..ef1240cc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2092,9 +2092,9 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.4.4", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.4.tgz", - "integrity": "sha512-WKERbSZJGof0+9XeeMmWnb/9FpNxogcB5eTJTHjc9no0ymdTw3jTzT+KZL9iC/hGqBpuomDLaNFCYbAOt29nBw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.5.tgz", + "integrity": "sha512-FP7Rh13u8aJbHe+zZ7hM0CC4785g9Pw4lz4r2TTgRtf0zTxSWMkJaPEwyjX8SK9oWK2GsYxl+fKpwVZNbmnj9A==", "dev": true, "dependencies": { "@angular-devkit/core": "17.3.8", @@ -2114,7 +2114,7 @@ "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.3.3", - "webpack": "5.93.0", + "webpack": "5.94.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -2831,21 +2831,13 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -5813,9 +5805,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -13940,12 +13932,11 @@ } }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -13954,7 +13945,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", From f5a64f0faaf6381803bea4c061cd95ec01a8704b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 15:33:21 +0000 Subject: [PATCH 191/258] build(deps-dev): bump @types/node from 22.5.0 to 22.5.2 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.0 to 22.5.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef1240cc0..cfb48fbea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2994,9 +2994,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", - "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "version": "22.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz", + "integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==", "dependencies": { "undici-types": "~6.19.2" } From 2c0115b94f8acc808a6bf7ead34959b9b40f2afe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 15:43:51 +0000 Subject: [PATCH 192/258] build(deps-dev): bump @types/chai from 4.3.18 to 4.3.19 Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.3.18 to 4.3.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai) --- updated-dependencies: - dependency-name: "@types/chai" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cfb48fbea..bd965684e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2800,9 +2800,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.18", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.18.tgz", - "integrity": "sha512-2UfJzigyNa8kYTKn7o4hNMPphkxtu4WTJyobK3m4FBpyj7EK5xgtPcOtxLm7Dznk/Qxr0QXn+gQbkg7mCZKdfg==", + "version": "4.3.19", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz", + "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==", "dev": true }, "node_modules/@types/connect": { From 48d46ecaf7024edf254a7314e415beac8532d951 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 15:54:09 +0000 Subject: [PATCH 193/258] build(deps): bump mathjs from 13.1.0 to 13.1.1 Bumps [mathjs](https://github.com/josdejong/mathjs) from 13.1.0 to 13.1.1. - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v13.1.0...v13.1.1) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd965684e..35dc1140e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9471,9 +9471,9 @@ } }, "node_modules/mathjs": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.1.0.tgz", - "integrity": "sha512-5BI//cQdcKtDgstJ3QbKYyrWLyUEEHY9ZQgA3laaPyTis+ca8Y7GCxbLFFLYv8nkpOFTIF55FLKoiqQaufj1dQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.1.1.tgz", + "integrity": "sha512-duaSAy7m4F+QtP1Dyv8MX2XuxcqpNDDlGly0SdVTCqpAmwdOFWilDdQKbLdo9RfD6IDNMOdo9tIsEaTXkconlQ==", "dependencies": { "@babel/runtime": "^7.25.4", "complex.js": "^2.1.1", From 1798c0cc13386955f5d0245951a30b98d06cb5bc Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 4 Sep 2024 17:28:26 +0200 Subject: [PATCH 194/258] refactor naming of current dataset schema and dto. Added new unified dataset schema and dto --- src/datasets/datasets.controller.ts | 19 +- src/datasets/datasets.service.ts | 36 ++- .../dto/create-dataset-obsolete.dto.ts | 34 ++ src/datasets/dto/create-dataset.dto.ts | 9 - .../dto/output-dataset-obsolete.dto.ts | 237 ++++++++++++++ src/datasets/dto/output-dataset.dto.ts | 41 +++ .../dto/update-dataset-obsolete.dto.ts | 298 ++++++++++++++++++ src/datasets/dto/update-dataset.dto.ts | 141 ++++++++- .../dto/update-derived-dataset.dto.ts | 4 +- src/datasets/dto/update-raw-dataset.dto.ts | 4 +- src/datasets/schemas/dataset.schema.ts | 149 ++++----- 11 files changed, 852 insertions(+), 120 deletions(-) create mode 100644 src/datasets/dto/create-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/output-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/output-dataset.dto.ts create mode 100644 src/datasets/dto/update-dataset-obsolete.dto.ts diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 0d7706ee1..42233e22a 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -36,7 +36,7 @@ import { } from "@nestjs/swagger"; import { Request } from "express"; import { DatasetsService } from "./datasets.service"; -import { PartialUpdateDatasetDto } from "./dto/update-dataset.dto"; +import { PartialUpdateDatasetObsoleteDto } from "./dto/update-dataset-obsolete.dto"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; import { CreateRawDatasetDto } from "./dto/create-raw-dataset.dto"; import { CreateDerivedDatasetDto } from "./dto/create-derived-dataset.dto"; @@ -98,6 +98,7 @@ import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { LogbooksService } from "src/logbooks/logbooks.service"; import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; +import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; @ApiBearerAuth() @ApiExtraModels( @@ -597,7 +598,7 @@ export class DatasetsController { @Req() request: Request, @Headers() headers: Record, @Query(new FilterPipe()) queryFilter: { filter?: string }, - ): Promise { + ): Promise { const mergedFilters = replaceLikeOperator( this.updateMergedFiltersForList( request, @@ -606,7 +607,9 @@ export class DatasetsController { ) as IFilters; // this should be implemented at database level - const datasets = await this.datasetsService.findAll(mergedFilters); + const datasets = (await this.datasetsService.findAll( + mergedFilters, + )) as OutputDatasetObsoleteDto[]; if (datasets && datasets.length > 0) { const includeFilters = mergedFilters.include ?? []; await Promise.all( @@ -917,7 +920,7 @@ export class DatasetsController { @Req() request: Request, @Headers() headers: Record, @Query(new FilterPipe()) queryFilter: { filter?: string }, - ): Promise { + ): Promise { const mergedFilters = replaceLikeOperator( this.updateMergedFiltersForList( request, @@ -927,7 +930,7 @@ export class DatasetsController { const dataset = (await this.datasetsService.findOne( mergedFilters, - )) as DatasetClass; + )) as OutputDatasetObsoleteDto; if (dataset) { const includeFilters = mergedFilters.include ?? []; @@ -1585,7 +1588,7 @@ export class DatasetsController { const datablock = await this.origDatablocksService.create(createOrigDatablock); - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { size: dataset.size + datablock.size, numberOfFiles: dataset.numberOfFiles + datablock.dataFileList.length, }; @@ -1804,7 +1807,7 @@ export class DatasetsController { where: { datasetId: pid }, }); // update dataset size and files number - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { size: odb.reduce((a, b) => a + b.size, 0), numberOfFiles: odb.reduce((a, b) => a + b.dataFileList.length, 0), }; @@ -2034,7 +2037,7 @@ export class DatasetsController { datasetId: pid, }); // update dataset size and files number - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { packedSize: remainingDatablocks.reduce((a, b) => a + b.packedSize, 0), numberOfFilesArchived: remainingDatablocks.reduce( (a, b) => a + b.dataFileList.length, diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index c78974c1e..680222e8e 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -24,11 +24,11 @@ import { ElasticSearchService } from "src/elastic-search/elastic-search.service" import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; -import { CreateDatasetDto } from "./dto/create-dataset.dto"; +import { CreateDatasetObsoleteDto } from "./dto/create-dataset-obsolete.dto"; import { - PartialUpdateDatasetDto, - UpdateDatasetDto, -} from "./dto/update-dataset.dto"; + PartialUpdateDatasetObsoleteDto, + UpdateDatasetObsoleteDto, +} from "./dto/update-dataset-obsolete.dto"; import { PartialUpdateDerivedDatasetDto, UpdateDerivedDatasetDto, @@ -58,7 +58,9 @@ export class DatasetsService { } } - async create(createDatasetDto: CreateDatasetDto): Promise { + async create( + createDatasetDto: CreateDatasetObsoleteDto, + ): Promise { const username = (this.request.user as JWTUser).username; const createdDataset = new this.datasetModel( // insert created and updated fields @@ -206,7 +208,7 @@ export class DatasetsService { async findByIdAndReplace( id: string, updateDatasetDto: - | UpdateDatasetDto + | UpdateDatasetObsoleteDto | UpdateRawDatasetDto | UpdateDerivedDatasetDto, ): Promise { @@ -252,7 +254,7 @@ export class DatasetsService { async findByIdAndUpdate( id: string, updateDatasetDto: - | PartialUpdateDatasetDto + | PartialUpdateDatasetObsoleteDto | PartialUpdateRawDatasetDto | PartialUpdateDerivedDatasetDto | UpdateQuery, @@ -434,20 +436,28 @@ export class DatasetsService { async updateHistory( req: Request, dataset: DatasetClass, - data: UpdateDatasetDto, + data: UpdateDatasetObsoleteDto, ) { if (req.body.history) { delete req.body.history; } if (!req.body.size && !req.body.packedSize) { - const updatedFields: Omit = - data; + const updatedFields: Omit< + UpdateDatasetObsoleteDto, + "updatedAt" | "updatedBy" + > = data; const historyItem: Record = {}; Object.keys(updatedFields).forEach((updatedField) => { - historyItem[updatedField as keyof UpdateDatasetDto] = { - currentValue: data[updatedField as keyof UpdateDatasetDto], - previousValue: dataset[updatedField as keyof UpdateDatasetDto], + historyItem[updatedField as keyof UpdateDatasetObsoleteDto] = { + currentValue: data[updatedField as keyof UpdateDatasetObsoleteDto], + previousValue: + dataset[ + updatedField as keyof Omit< + UpdateDatasetObsoleteDto, + "attachments" | "origdatablocks" | "datablocks" + > + ], }; }); dataset.history = dataset.history ?? []; diff --git a/src/datasets/dto/create-dataset-obsolete.dto.ts b/src/datasets/dto/create-dataset-obsolete.dto.ts new file mode 100644 index 000000000..a75fe5dfe --- /dev/null +++ b/src/datasets/dto/create-dataset-obsolete.dto.ts @@ -0,0 +1,34 @@ +import { IsEnum, IsOptional, IsString } from "class-validator"; +import { ApiProperty } from "@nestjs/swagger"; +import { DatasetType } from "../dataset-type.enum"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; + +export class CreateDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsOptional() + @IsString() + pid?: string; + + @ApiProperty({ + type: String, + required: true, + enum: [DatasetType.Raw, DatasetType.Derived], + description: + "Characterize type of dataset, either 'raw' or 'derived'. Autofilled when choosing the proper inherited models.", + }) + @IsEnum(DatasetType) + readonly type: string; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; +} diff --git a/src/datasets/dto/create-dataset.dto.ts b/src/datasets/dto/create-dataset.dto.ts index c9b5b7ad5..8ee18d733 100644 --- a/src/datasets/dto/create-dataset.dto.ts +++ b/src/datasets/dto/create-dataset.dto.ts @@ -22,13 +22,4 @@ export class CreateDatasetDto extends UpdateDatasetDto { }) @IsEnum(DatasetType) readonly type: string; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; } diff --git a/src/datasets/dto/output-dataset-obsolete.dto.ts b/src/datasets/dto/output-dataset-obsolete.dto.ts new file mode 100644 index 000000000..dced6bc31 --- /dev/null +++ b/src/datasets/dto/output-dataset-obsolete.dto.ts @@ -0,0 +1,237 @@ +import { + IsArray, + IsDateString, + IsEnum, + IsObject, + IsOptional, + IsString, +} from "class-validator"; +import { ApiProperty, getSchemaPath } from "@nestjs/swagger"; +import { DatasetType } from "../dataset-type.enum"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; +import { Attachment } from "src/attachments/schemas/attachment.schema"; +import { Type } from "class-transformer"; +import { OrigDatablock } from "src/origdatablocks/schemas/origdatablock.schema"; +import { Datablock } from "src/datablocks/schemas/datablock.schema"; + +export class OutputDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsString() + readonly pid: string; + + @ApiProperty({ + type: String, + required: true, + enum: [DatasetType.Raw, DatasetType.Derived], + description: + "Characterize type of dataset, either 'raw' or 'derived'. Autofilled when choosing the proper inherited models.", + }) + @IsEnum(DatasetType) + readonly type: string; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + @IsOptional() + readonly principalInvestigator?: string; + + @ApiProperty({ + type: Date, + required: false, + description: + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly startTime?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly endTime?: Date; + + @ApiProperty({ + type: String, + required: true, + description: + "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + @IsOptional() + readonly creationLocation?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", + }) + @IsOptional() + @IsString() + readonly dataFormat?: string; + + @ApiProperty({ + type: String, + required: false, + description: "The ID of the proposal to which the dataset belongs.", + }) + @IsOptional() + @IsString() + readonly proposalId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the sample used when collecting the data.", + }) + @IsOptional() + @IsString() + readonly sampleId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the instrument where the data was created.", + }) + @IsOptional() + @IsString() + readonly instrumentId?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", + }) + @IsString() + @IsOptional() + readonly investigator?: string; + + @ApiProperty({ + type: [String], + required: true, + description: + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", + }) + @IsString({ + each: true, + }) + @IsOptional() + readonly inputDatasets?: string[]; + + @ApiProperty({ + type: [String], + required: true, + description: + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", + }) + @IsString({ + each: true, + }) + @IsOptional() + readonly usedSoftware?: string[]; + + @ApiProperty({ + type: Object, + required: false, + description: + "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", + }) + @IsOptional() + @IsObject() + readonly jobParameters?: Record; + + @ApiProperty({ + type: String, + required: false, + description: + "The output job logfile. Keep the size of this log data well below 15 MB.", + }) + @IsOptional() + @IsString() + readonly jobLogData?: string; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(Attachment) }, + required: false, + description: + "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", + }) + @IsOptional() + @IsArray() + @Type(() => Attachment) + attachments?: Attachment[]; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(OrigDatablock) }, + required: false, + description: + "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", + }) + origdatablocks?: OrigDatablock[]; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(Datablock) }, + required: false, + description: + "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", + }) + datablocks?: Datablock[]; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who created this record. This property is added and maintained by the system.", + }) + createdBy: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who updated this record last. This property is added and maintained by the system.", + }) + updatedBy: string; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was created. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + createdAt: Date; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was updated last. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + updatedAt: Date; +} diff --git a/src/datasets/dto/output-dataset.dto.ts b/src/datasets/dto/output-dataset.dto.ts new file mode 100644 index 000000000..8809e3756 --- /dev/null +++ b/src/datasets/dto/output-dataset.dto.ts @@ -0,0 +1,41 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { CreateDatasetDto } from "./create-dataset.dto"; +import { IsString } from "class-validator"; + +export class OutputDatasetDto extends CreateDatasetDto { + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who created this record. This property is added and maintained by the system.", + }) + @IsString() + createdBy: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who updated this record last. This property is added and maintained by the system.", + }) + @IsString() + updatedBy: string; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was created. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + @IsString() + createdAt: Date; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was updated last. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + @IsString() + updatedAt: Date; +} diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts new file mode 100644 index 000000000..f2be1c2d2 --- /dev/null +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -0,0 +1,298 @@ +import { + ApiProperty, + ApiTags, + getSchemaPath, + PartialType, +} from "@nestjs/swagger"; +import { OwnableDto } from "../../common/dto/ownable.dto"; +import { + IsArray, + IsBoolean, + IsDateString, + IsEmail, + IsFQDN, + IsInt, + IsNumber, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from "class-validator"; +import { TechniqueClass } from "../schemas/technique.schema"; +import { Type } from "class-transformer"; +import { CreateTechniqueDto } from "./create-technique.dto"; +import { RelationshipClass } from "../schemas/relationship.schema"; +import { CreateRelationshipDto } from "./create-relationship.dto"; +import { LifecycleClass } from "../schemas/lifecycle.schema"; +import { Attachment } from "../../attachments/schemas/attachment.schema"; +import { OrigDatablock } from "../../origdatablocks/schemas/origdatablock.schema"; +import { Datablock } from "../../datablocks/schemas/datablock.schema"; + +@ApiTags("datasets") +export class UpdateDatasetObsoleteDto extends OwnableDto { + @ApiProperty({ + type: String, + required: true, + description: + "Owner or custodian of the dataset, usually first name + last name. The string may contain a list of persons, which should then be separated by semicolons.", + }) + @IsString() + readonly owner: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Email of the owner or custodian of the dataset. The string may contain a list of emails, which should then be separated by semicolons.", + }) + @IsOptional() + @IsEmail() + readonly ownerEmail?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "ORCID of the owner or custodian. The string may contain a list of ORCIDs, which should then be separated by semicolons.", + }) + @IsOptional() + @IsString() + readonly orcidOfOwner?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Email of the contact person for this dataset. The string may contain a list of emails, which should then be separated by semicolons.", + }) + @IsEmail() + readonly contactEmail: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Absolute file path on file server containing the files of this dataset, e.g. /some/path/to/sourcefolder. In case of a single file dataset, e.g. HDF5 data, it contains the path up to, but excluding the filename. Trailing slashes are removed.", + }) + @IsString() + readonly sourceFolder: string; + + @ApiProperty({ + type: String, + required: false, + description: + "DNS host name of file server hosting sourceFolder, optionally including a protocol e.g. [protocol://]fileserver1.example.com", + }) + @IsOptional() + @IsFQDN() + readonly sourceFolderHost?: string; + + /* + * size and number of files fields should be managed by the system + */ + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total size of all source files contained in source folder on disk when unpacked.", + }) + @IsOptional() + @IsInt() + readonly size?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total size of all datablock package files created for this dataset.", + }) + @IsOptional() + @IsInt() + readonly packedSize?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total number of files in all OrigDatablocks for this dataset.", + }) + @IsOptional() + @IsInt() + readonly numberOfFiles?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: true, + description: "Total number of files in all Datablocks for this dataset.", + }) + @IsOptional() + @IsInt() + readonly numberOfFilesArchived?: number; + + @ApiProperty({ + type: Date, + required: true, + description: + "Time when dataset became fully available on disk, i.e. all containing files have been written, or the dataset was created in SciCat.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsDateString() + readonly creationTime: Date; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines a level of trust, e.g. a measure of how much data was verified or used by other persons.", + }) + @IsOptional() + @IsString() + readonly validationStatus?: string; + + @ApiProperty({ + type: [String], + required: false, + description: + "Array of tags associated with the meaning or contents of this dataset. Values should ideally come from defined vocabularies, taxonomies, ontologies or knowledge graphs.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly keywords?: string[]; + + @ApiProperty({ + type: String, + required: false, + description: "Free text explanation of contents of dataset.", + }) + @IsOptional() + @IsString() + readonly description?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", + }) + @IsOptional() + @IsString() + readonly datasetName?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'", + }) + @IsOptional() + @IsString() + readonly classification?: string; + + @ApiProperty({ + type: String, + required: false, + description: "Name of the license under which the data can be used.", + }) + @IsOptional() + @IsString() + readonly license?: string; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: Boolean, + required: false, + default: false, + description: "Flag is true when data are made publicly available.", + }) + @IsOptional() + @IsBoolean() + readonly isPublished?: boolean; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(TechniqueClass) }, + required: false, + default: [], + description: "Stores the metadata information for techniques.", + }) + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => CreateTechniqueDto) + readonly techniques?: TechniqueClass[]; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: [String], + required: false, + default: [], + description: "List of users that the dataset has been shared with.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly sharedWith?: string[]; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(RelationshipClass) }, + required: false, + default: [], + description: "Stores the relationships with other datasets.", + }) + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => CreateRelationshipDto) + readonly relationships?: RelationshipClass[]; + + @ApiProperty({ + type: LifecycleClass, + required: false, + default: {}, + description: + "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", + }) + @IsOptional() + readonly datasetlifecycle: LifecycleClass; + + @ApiProperty({ + type: Object, + required: false, + default: {}, + description: "JSON object containing the scientific metadata.", + }) + @IsOptional() + @IsObject() + readonly scientificMetadata?: Record; + + @ApiProperty({ + type: String, + required: false, + description: "Comment the user has about a given dataset.", + }) + @IsOptional() + @IsString() + readonly comment?: string; + + @ApiProperty({ + type: Number, + required: false, + description: + "Data Quality Metrics is a number given by the user to rate the dataset.", + }) + @IsOptional() + @IsNumber() + readonly dataQualityMetrics?: number; +} + +export class PartialUpdateDatasetObsoleteDto extends PartialType( + UpdateDatasetObsoleteDto, +) {} diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index aab14a7e5..c4ea63c4b 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -24,9 +24,6 @@ import { CreateTechniqueDto } from "./create-technique.dto"; import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; -import { Attachment } from "../../attachments/schemas/attachment.schema"; -import { OrigDatablock } from "../../origdatablocks/schemas/origdatablock.schema"; -import { Datablock } from "../../datablocks/schemas/datablock.schema"; @ApiTags("datasets") export class UpdateDatasetDto extends OwnableDto { @@ -37,7 +34,8 @@ export class UpdateDatasetDto extends OwnableDto { "Owner or custodian of the dataset, usually first name + last name. The string may contain a list of persons, which should then be separated by semicolons.", }) @IsString() - readonly owner: string; + @IsOptional() + readonly owner?: string; @ApiProperty({ type: String, @@ -175,13 +173,12 @@ export class UpdateDatasetDto extends OwnableDto { @ApiProperty({ type: String, - required: false, + required: true, description: "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", }) - @IsOptional() @IsString() - readonly datasetName?: string; + readonly datasetName: string; @ApiProperty({ type: String, @@ -211,7 +208,7 @@ export class UpdateDatasetDto extends OwnableDto { }) @IsOptional() @IsBoolean() - readonly isPublished?: boolean; + readonly isPublished?: boolean = false; @ApiProperty({ type: "array", @@ -261,7 +258,7 @@ export class UpdateDatasetDto extends OwnableDto { "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", }) @IsOptional() - readonly datasetlifecycle: LifecycleClass; + readonly datasetlifecycle?: LifecycleClass; @ApiProperty({ type: Object, @@ -292,14 +289,134 @@ export class UpdateDatasetDto extends OwnableDto { @IsNumber() readonly dataQualityMetrics?: number; + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + readonly principalInvestigator: string; + + @ApiProperty({ + type: Date, + required: false, + description: + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) @IsOptional() - attachments?: Attachment[]; + @IsDateString() + readonly startTime?: Date; + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) @IsOptional() - origdatablocks?: OrigDatablock[]; + @IsDateString() + readonly endTime?: Date; + @ApiProperty({ + type: String, + required: false, + description: + "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + }) @IsOptional() - datablocks?: Datablock[]; + @IsString() + readonly creationLocation?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", + }) + @IsOptional() + @IsString() + readonly dataFormat?: string; + + @ApiProperty({ + type: [String], + required: false, + description: + "ID of the proposal or proposals which the dataset belongs to.
This dataset might have been acquired under the listed proposals or is derived from datasets acquired from datasets belonging to the listed datasets.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly proposalId?: string[]; + + @ApiProperty({ + type: [String], + required: false, + description: + "ID of the sample or samples used when collecting the data included or used in this dataset.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly sampleId?: string[]; + + @ApiProperty({ + type: String, + required: false, + description: + "ID of the instrument or instruments where the data included or used in this datasets was collected on.", + }) + @IsOptional() + @IsString({ + each: false, + }) + readonly instrumentId?: string[]; + + @ApiProperty({ + type: [String], + required: true, + description: + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", + }) + @IsOptional() + @IsString({ + each: false, + }) + readonly inputDatasets?: string[]; + + @ApiProperty({ + type: [String], + required: false, + description: + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly usedSoftware?: string[]; + + @ApiProperty({ + type: Object, + required: false, + description: + "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", + }) + @IsOptional() + @IsObject() + readonly jobParameters?: Record; + + @ApiProperty({ + type: String, + required: false, + description: + "The output job logfile. Keep the size of this log data well below 15 MB.", + }) + @IsOptional() + @IsString() + readonly jobLogData?: string; } export class PartialUpdateDatasetDto extends PartialType(UpdateDatasetDto) {} diff --git a/src/datasets/dto/update-derived-dataset.dto.ts b/src/datasets/dto/update-derived-dataset.dto.ts index 5f4d83a1d..a654c5bca 100644 --- a/src/datasets/dto/update-derived-dataset.dto.ts +++ b/src/datasets/dto/update-derived-dataset.dto.ts @@ -1,8 +1,8 @@ -import { UpdateDatasetDto } from "./update-dataset.dto"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; import { ApiProperty, PartialType } from "@nestjs/swagger"; import { IsObject, IsOptional, IsString } from "class-validator"; -export class UpdateDerivedDatasetDto extends UpdateDatasetDto { +export class UpdateDerivedDatasetDto extends UpdateDatasetObsoleteDto { @ApiProperty({ type: String, required: true, diff --git a/src/datasets/dto/update-raw-dataset.dto.ts b/src/datasets/dto/update-raw-dataset.dto.ts index a03fa14ad..5926b854f 100644 --- a/src/datasets/dto/update-raw-dataset.dto.ts +++ b/src/datasets/dto/update-raw-dataset.dto.ts @@ -1,8 +1,8 @@ import { IsDateString, IsOptional, IsString } from "class-validator"; -import { UpdateDatasetDto } from "./update-dataset.dto"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; import { ApiProperty, PartialType } from "@nestjs/swagger"; -export class UpdateRawDatasetDto extends UpdateDatasetDto { +export class UpdateRawDatasetDto extends UpdateDatasetObsoleteDto { /* we need to discuss if the naming is adequate. */ @ApiProperty({ type: String, diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 74c29aaa7..a50055b98 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -244,28 +244,21 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, - required: false, + required: true, description: - "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", + "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid.", }) @Prop({ type: String, - required: false, - default: function datasetName() { - const sourceFolder = (this as DatasetDocument).sourceFolder; - if (!sourceFolder) return ""; - const arr = sourceFolder.split("/"); - if (arr.length == 1) return arr[0]; - else return arr[arr.length - 2] + "/" + arr[arr.length - 1]; - }, + required: true, }) - datasetName?: string; + datasetName: string; @ApiProperty({ type: String, required: false, description: - "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'", + "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'. Please check the following post for more info: https://en.wikipedia.org/wiki/Parkerian_Hexad", }) @Prop({ type: String, required: false }) classification?: string; @@ -280,11 +273,12 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, - required: false, - description: "Version of the API used in creation of the dataset.", + required: true, + description: + "Version of the API used when the dataset was created or last updated. API version is defined in code for each release. Managed by the system.", }) - @Prop({ type: String, required: false }) - version?: string; + @Prop({ type: String, required: true }) + version: string; @ApiProperty({ type: "array", @@ -298,12 +292,12 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: LifecycleClass, - required: false, + required: true, default: {}, description: "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", }) - @Prop({ type: LifecycleSchema, default: {}, required: false }) + @Prop({ type: LifecycleSchema, default: {}, required: true }) datasetlifecycle?: LifecycleClass; @ApiProperty({ @@ -311,7 +305,8 @@ export class DatasetClass extends OwnableClass { items: { $ref: getSchemaPath(TechniqueClass) }, required: false, default: [], - description: "Stores the metadata information for techniques.", + description: + "Array of techniques information, with technique name and pid.", }) @Prop({ type: [TechniqueSchema], required: false, default: [] }) techniques?: TechniqueClass[]; @@ -321,7 +316,8 @@ export class DatasetClass extends OwnableClass { items: { $ref: getSchemaPath(RelationshipClass) }, required: false, default: [], - description: "Stores the relationships with other datasets.", + description: + "Array of relationships with other datasets. It contains relationship type and destination dataset", }) @Prop({ type: [RelationshipSchema], required: false, default: [] }) relationships?: RelationshipClass[]; @@ -330,7 +326,8 @@ export class DatasetClass extends OwnableClass { type: [String], required: false, default: [], - description: "List of users that the dataset has been shared with.", + description: + "List of additional users that the dataset has been shared with.", }) @Prop({ type: [String], @@ -339,37 +336,37 @@ export class DatasetClass extends OwnableClass { }) sharedWith?: string[]; - @ApiProperty({ - type: "array", - items: { $ref: getSchemaPath(Attachment) }, - required: false, - description: - "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", - }) - @Prop({ type: [AttachmentSchema], default: [] }) - attachments?: Attachment[]; - - @ApiProperty({ - isArray: true, - type: OrigDatablock, - items: { $ref: getSchemaPath(OrigDatablock) }, - required: false, - description: - "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", - }) - @Prop({ type: [OrigDatablockSchema], default: [] }) - origdatablocks: OrigDatablock[]; - - @ApiProperty({ - isArray: true, - type: Datablock, - items: { $ref: getSchemaPath(Datablock) }, - required: false, - description: - "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", - }) - @Prop({ type: [DatablockSchema], default: [] }) - datablocks: Datablock[]; + // @ApiProperty({ + // type: "array", + // items: { $ref: getSchemaPath(Attachment) }, + // required: false, + // description: + // "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", + // }) + // @Prop({ type: [AttachmentSchema], default: [] }) + // attachments?: Attachment[]; + + // @ApiProperty({ + // isArray: true, + // type: OrigDatablock, + // items: { $ref: getSchemaPath(OrigDatablock) }, + // required: false, + // description: + // "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", + // }) + // @Prop({ type: [OrigDatablockSchema], default: [] }) + // origdatablocks: OrigDatablock[]; + + // @ApiProperty({ + // isArray: true, + // type: Datablock, + // items: { $ref: getSchemaPath(Datablock) }, + // required: false, + // description: + // "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", + // }) + // @Prop({ type: [DatablockSchema], default: [] }) + // datablocks: Datablock[]; @ApiProperty({ type: Object, @@ -383,7 +380,8 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, required: false, - description: "Comment the user has about a given dataset.", + description: + "Short comment provided by the user about a given dataset. This is additional to the description field.", }) @Prop({ type: String, @@ -400,7 +398,7 @@ export class DatasetClass extends OwnableClass { type: Number, required: false, }) - dataQualityMetrics: number; + dataQualityMetrics?: number; /* * fields related to Raw Datasets @@ -436,7 +434,7 @@ export class DatasetClass extends OwnableClass { type: String, required: true, description: - "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + "Unique location identifier where data was acquired. Usually in the form /Site-name/facility-name/instrumentOrBeamline-name.", }) @Prop({ type: String, required: false, index: true }) creationLocation?: string; @@ -453,44 +451,47 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, required: false, - description: "The ID of the proposal to which the dataset belongs.", + description: + "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) @Prop({ type: String, ref: "Proposal", required: false }) proposalId?: string; @ApiProperty({ - type: String, + type: [String], required: false, - description: "ID of the sample used when collecting the data.", + description: + "Single ID or array of IDS of the samples used when collecting the data.", }) - @Prop({ type: String, ref: "Sample", required: false }) - sampleId?: string; + @Prop({ type: [String], ref: "Sample", required: false }) + sampleId?: string[]; @ApiProperty({ - type: String, + type: [String], required: false, - description: "ID of the instrument where the data was created.", + description: + "Id of the instrument or array of IDS of the instruments where the data contained in this dataset was created/acquired.", }) - @Prop({ type: String, ref: "Instrument", required: false }) - instrumentId?: string; + @Prop({ type: [String], ref: "Instrument", required: false }) + instrumentId?: string[]; /* * Derived Dataset */ - @ApiProperty({ - type: String, - required: false, - description: - "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", - }) - @Prop({ type: String, required: false, index: true }) - investigator?: string; + // @ApiProperty({ + // type: String, + // required: false, + // description: + // "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", + // }) + // @Prop({ type: String, required: false, index: true }) + // investigator?: string; @ApiProperty({ type: [String], required: false, description: - "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs. This field is required if the dataset is a Derived dataset.", + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", }) @Prop({ type: [String], required: false }) inputDatasets?: string[]; @@ -499,7 +500,7 @@ export class DatasetClass extends OwnableClass { type: [String], required: false, description: - "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data. This field is required if the dataset is a Derived dataset.", + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", }) @Prop({ type: [String], required: false }) usedSoftware?: string[]; From 6ff6c6a7db7a8ee9abc4162c860eca38322bd773 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 5 Sep 2024 13:58:25 +0200 Subject: [PATCH 195/258] solved weird dependency in jobs --- src/jobs/jobs.controller.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/jobs/jobs.controller.ts b/src/jobs/jobs.controller.ts index 588f202f9..838fc724c 100644 --- a/src/jobs/jobs.controller.ts +++ b/src/jobs/jobs.controller.ts @@ -179,25 +179,26 @@ export class JobsController { // Indexing originDataBlock with pid and create set of files for each dataset const datasets = await this.datasetsService.findAll(filter); // Include origdatablocks - await Promise.all( + const aggregatedData = await Promise.all( datasets.map(async (dataset) => { - dataset.origdatablocks = await this.origDatablocksService.findAll( - { + return { + dataset: dataset, + origdatablocks: await this.origDatablocksService.findAll({ datasetId: dataset.pid, - }, - ); + }), + }; }), ); - const result: Record> = datasets.reduce( - (acc: Record>, dataset) => { + const result: Record> = aggregatedData.reduce( + (acc: Record>, data) => { // Using Set make searching more efficient - const files = dataset.origdatablocks.reduce((acc, block) => { + const files = data.origdatablocks.reduce((acc, block) => { block.dataFileList.forEach((file) => { acc.add(file.path); }); return acc; }, new Set()); - acc[dataset.pid] = files; + acc[data.dataset.pid] = files; return acc; }, {}, From 74b6edd5360a6dd7b2afdc8d0062859c37478f5c Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 6 Sep 2024 16:57:59 +0200 Subject: [PATCH 196/258] still refactoring names, started working on tests --- src/datasets/datasets.controller.ts | 180 +- src/datasets/datasets.service.ts | 10 +- .../dto/create-derived-dataset.dto.ts | 27 - src/datasets/dto/create-raw-dataset.dto.ts | 27 - src/datasets/dto/update-dataset.dto.ts | 6 +- .../dto/update-derived-dataset.dto.ts | 60 - src/datasets/dto/update-raw-dataset.dto.ts | 100 - src/datasets/schemas/dataset.schema.ts | 6 +- .../origdatablocks.controller.ts | 4 +- test/DatasetAuthorization.js | 2879 +++++++++-------- 10 files changed, 1584 insertions(+), 1715 deletions(-) delete mode 100644 src/datasets/dto/create-derived-dataset.dto.ts delete mode 100644 src/datasets/dto/create-raw-dataset.dto.ts delete mode 100644 src/datasets/dto/update-derived-dataset.dto.ts delete mode 100644 src/datasets/dto/update-raw-dataset.dto.ts diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 42233e22a..89e6f7536 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -38,8 +38,8 @@ import { Request } from "express"; import { DatasetsService } from "./datasets.service"; import { PartialUpdateDatasetObsoleteDto } from "./dto/update-dataset-obsolete.dto"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; -import { CreateRawDatasetDto } from "./dto/create-raw-dataset.dto"; -import { CreateDerivedDatasetDto } from "./dto/create-derived-dataset.dto"; +import { CreateRawDatasetObsoleteDto } from "./dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetObsoleteDto } from "./dto/create-derived-dataset-obsolete.dto"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; @@ -74,13 +74,13 @@ import { validate, ValidationError, ValidatorOptions } from "class-validator"; import { HistoryInterceptor } from "src/common/interceptors/history.interceptor"; import { CreateDatasetOrigDatablockDto } from "src/origdatablocks/dto/create-dataset-origdatablock"; import { - PartialUpdateRawDatasetDto, - UpdateRawDatasetDto, -} from "./dto/update-raw-dataset.dto"; + PartialUpdateRawDatasetObsoleteDto, + UpdateRawDatasetObsoleteDto, +} from "./dto/update-raw-dataset-obsolete.dto"; import { - PartialUpdateDerivedDatasetDto, - UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset.dto"; + PartialUpdateDerivedDatasetObsoleteDto, + UpdateDerivedDatasetObsoleteDto, +} from "./dto/update-derived-dataset-obsolete.dto"; import { CreateDatasetDatablockDto } from "src/datablocks/dto/create-dataset-datablock"; import { filterDescription, @@ -99,12 +99,13 @@ import { LogbooksService } from "src/logbooks/logbooks.service"; import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; +import { CreateDatasetDto } from "./dto/create-dataset.dto"; @ApiBearerAuth() @ApiExtraModels( CreateAttachmentDto, - CreateDerivedDatasetDto, - CreateRawDatasetDto, + CreateDerivedDatasetObsoleteDto, + CreateRawDatasetObsoleteDto, HistoryClass, TechniqueClass, RelationshipClass, @@ -283,7 +284,7 @@ export class DatasetsController { return dataset; } - async checkPermissionsForDataset(request: Request, id: string) { + async checkPermissionsForDatasetObsolete(request: Request, id: string) { const dataset = await this.datasetsService.findOne({ where: { pid: id } }); const user: JWTUser = request.user as JWTUser; @@ -332,7 +333,10 @@ export class DatasetsController { } async generateDatasetInstanceForPermissions( - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto | DatasetClass, + dataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | DatasetClass, ): Promise { const datasetInstance = new DatasetClass(); datasetInstance._id = ""; @@ -345,9 +349,9 @@ export class DatasetsController { return datasetInstance; } - async checkPermissionsForDatasetCreate( + async checkPermissionsForObsoleteDatasetCreate( request: Request, - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto, + dataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, ) { const user: JWTUser = request.user as JWTUser; @@ -388,6 +392,69 @@ export class DatasetsController { return dataset; } + convertObsoleteToCurrentSchema( + inputDataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, + ): CreateDatasetDto { + const propertiesModifier: Record = {}; + if (inputDataset.type == "raw") { + if ("proposalId" in inputDataset) { + propertiesModifier.proposalIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).proposalId, + ]; + } + if ("sampleId" in inputDataset) { + propertiesModifier.sampleIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).sampleId, + ]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).instrumentId, + ]; + } + } else { + if ("investigator" in inputDataset) { + propertiesModifier.principalInvestigator = [ + (inputDataset as CreateDerivedDatasetObsoleteDto).investigator, + ]; + } + } + + const outputDataset: CreateDatasetDto = { + ...(inputDataset as CreateDatasetDto), + ...propertiesModifier, + }; + + return outputDataset; + } + + convertCurrentToObsoleteSchema( + inputDataset: DatasetClass, + ): OutputDatasetObsoleteDto { + const propertiesModifier: Record = {}; + if ("proposalIds" in inputDataset) { + propertiesModifier.proposalIds = inputDataset.proposalIds![0]; + } + if ("sampleIds" in inputDataset) { + propertiesModifier.sampleIds = inputDataset.sampleIds![0]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; + } + if (inputDataset.type == "raw") { + if ("investigator" in inputDataset) { + propertiesModifier.investigator = inputDataset.principalInvestigator; + } + } + + const outputDataset: OutputDatasetObsoleteDto = { + ...(inputDataset as OutputDatasetObsoleteDto), + ...propertiesModifier, + }; + + return outputDataset; + } + // POST /datasets @UseGuards(PoliciesGuard) @CheckPolicies("datasets", (ability: AppAbility) => @@ -404,14 +471,14 @@ export class DatasetsController { description: "It creates a new dataset and returns it completed with systems fields.", }) - @ApiExtraModels(CreateRawDatasetDto, CreateDerivedDatasetDto) + @ApiExtraModels(CreateRawDatasetObsoleteDto, CreateDerivedDatasetObsoleteDto) @ApiBody({ description: "Input fields for the dataset to be created", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(CreateRawDatasetDto) }, - { $ref: getSchemaPath(CreateDerivedDatasetDto) }, + { $ref: getSchemaPath(CreateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(CreateDerivedDatasetObsoleteDto) }, ], }, }) @@ -422,25 +489,34 @@ export class DatasetsController { }) async create( @Req() request: Request, - @Body() createDatasetDto: CreateRawDatasetDto | CreateDerivedDatasetDto, - ): Promise { + @Body() + createDatasetObsoleteDto: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto, + ): Promise { // validate dataset - await this.validateDataset( - createDatasetDto, - createDatasetDto.type === "raw" - ? CreateRawDatasetDto - : CreateDerivedDatasetDto, + await this.validateDatasetObsolete( + createDatasetObsoleteDto, + createDatasetObsoleteDto.type === "raw" + ? CreateRawDatasetObsoleteDto + : CreateDerivedDatasetObsoleteDto, ); - const datasetDTO = await this.checkPermissionsForDatasetCreate( - request, - createDatasetDto, - ); + const obsoleteDatasetDto = + await this.checkPermissionsForObsoleteDatasetCreate( + request, + createDatasetObsoleteDto, + ); try { - const createdDataset = await this.datasetsService.create(datasetDTO); + const datasetDto = + this.convertObsoleteToCurrentSchema(obsoleteDatasetDto); + const createdDataset = await this.datasetsService.create(datasetDto); + + const outputObsoleteDatasetDto = + this.convertCurrentToObsoleteSchema(createdDataset); - return createdDataset; + return outputObsoleteDatasetDto; } catch (error) { if ((error as MongoError).code === 11000) { throw new ConflictException( @@ -452,21 +528,21 @@ export class DatasetsController { } } - async validateDataset( + async validateDatasetObsolete( inputDatasetDto: - | CreateRawDatasetDto - | CreateDerivedDatasetDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto, + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, dto: ClassConstructor< - | CreateRawDatasetDto - | CreateDerivedDatasetDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto >, ) { const validateOptions: ValidatorOptions = { @@ -481,7 +557,7 @@ export class DatasetsController { if ( inputDatasetDto instanceof - (CreateRawDatasetDto || CreateDerivedDatasetDto) + (CreateRawDatasetObsoleteDto || CreateDerivedDatasetObsoleteDto) ) { if (!(inputDatasetDto.type in DatasetType)) { throw new HttpException( @@ -526,14 +602,14 @@ export class DatasetsController { description: "It validates the dataset provided as input, and returns true if the information is a valid dataset", }) - @ApiExtraModels(CreateRawDatasetDto, CreateDerivedDatasetDto) + @ApiExtraModels(CreateRawDatasetObsoleteDto, CreateDerivedDatasetObsoleteDto) @ApiBody({ description: "Input fields for the dataset that needs to be validated", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(CreateRawDatasetDto) }, - { $ref: getSchemaPath(CreateDerivedDatasetDto) }, + { $ref: getSchemaPath(CreateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(CreateDerivedDatasetObsoleteDto) }, ], }, }) @@ -545,9 +621,15 @@ export class DatasetsController { }) async isValid( @Req() request: Request, - @Body() createDatasetDto: CreateRawDatasetDto | CreateDerivedDatasetDto, + @Body() + createDatasetObsoleteDto: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto, ): Promise<{ valid: boolean }> { - await this.checkPermissionsForDatasetCreate(request, createDatasetDto); + await this.checkPermissionsForObsoleteDatasetCreate( + request, + createDatasetObsoleteDto, + ); const dtoTestRawCorrect = plainToInstance( CreateRawDatasetDto, diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 680222e8e..60793750d 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -24,7 +24,7 @@ import { ElasticSearchService } from "src/elastic-search/elastic-search.service" import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; -import { CreateDatasetObsoleteDto } from "./dto/create-dataset-obsolete.dto"; +import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { PartialUpdateDatasetObsoleteDto, UpdateDatasetObsoleteDto, @@ -32,11 +32,11 @@ import { import { PartialUpdateDerivedDatasetDto, UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset.dto"; +} from "./dto/update-derived-dataset-obsolete.dto"; import { PartialUpdateRawDatasetDto, UpdateRawDatasetDto, -} from "./dto/update-raw-dataset.dto"; +} from "./dto/update-raw-dataset-obsolete.dto"; import { IDatasetFields } from "./interfaces/dataset-filters.interface"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; @@ -58,9 +58,7 @@ export class DatasetsService { } } - async create( - createDatasetDto: CreateDatasetObsoleteDto, - ): Promise { + async create(createDatasetDto: CreateDatasetDto): Promise { const username = (this.request.user as JWTUser).username; const createdDataset = new this.datasetModel( // insert created and updated fields diff --git a/src/datasets/dto/create-derived-dataset.dto.ts b/src/datasets/dto/create-derived-dataset.dto.ts deleted file mode 100644 index f95240c82..000000000 --- a/src/datasets/dto/create-derived-dataset.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UpdateDerivedDatasetDto } from "./update-derived-dataset.dto"; -import { ApiProperty } from "@nestjs/swagger"; -import { IsEnum, IsOptional, IsString } from "class-validator"; -import { DatasetType } from "../dataset-type.enum"; - -export class CreateDerivedDatasetDto extends UpdateDerivedDatasetDto { - @ApiProperty({ - type: String, - required: false, - description: "Persistent identifier of the dataset.", - }) - @IsOptional() - @IsString() - pid?: string; - - @IsEnum(DatasetType) - readonly type: string = DatasetType.Derived; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; -} diff --git a/src/datasets/dto/create-raw-dataset.dto.ts b/src/datasets/dto/create-raw-dataset.dto.ts deleted file mode 100644 index fafa70b78..000000000 --- a/src/datasets/dto/create-raw-dataset.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UpdateRawDatasetDto } from "./update-raw-dataset.dto"; -import { ApiProperty } from "@nestjs/swagger"; -import { IsEnum, IsOptional, IsString } from "class-validator"; -import { DatasetType } from "../dataset-type.enum"; - -export class CreateRawDatasetDto extends UpdateRawDatasetDto { - @ApiProperty({ - type: String, - required: false, - description: "Persistent identifier of the dataset.", - }) - @IsOptional() - @IsString() - pid?: string; - - @IsEnum(DatasetType) - readonly type: string = DatasetType.Raw; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; -} diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index c4ea63c4b..ad928772f 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -348,7 +348,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: true, }) - readonly proposalId?: string[]; + readonly proposalIds?: string[]; @ApiProperty({ type: [String], @@ -360,7 +360,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: true, }) - readonly sampleId?: string[]; + readonly sampleIds?: string[]; @ApiProperty({ type: String, @@ -372,7 +372,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: false, }) - readonly instrumentId?: string[]; + readonly instrumentIds?: string[]; @ApiProperty({ type: [String], diff --git a/src/datasets/dto/update-derived-dataset.dto.ts b/src/datasets/dto/update-derived-dataset.dto.ts deleted file mode 100644 index a654c5bca..000000000 --- a/src/datasets/dto/update-derived-dataset.dto.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; -import { ApiProperty, PartialType } from "@nestjs/swagger"; -import { IsObject, IsOptional, IsString } from "class-validator"; - -export class UpdateDerivedDatasetDto extends UpdateDatasetObsoleteDto { - @ApiProperty({ - type: String, - required: true, - description: - "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", - }) - @IsString() - readonly investigator: string; - - @ApiProperty({ - type: [String], - required: true, - description: - "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", - }) - @IsString({ - each: true, - }) - readonly inputDatasets: string[]; - - @ApiProperty({ - type: [String], - required: true, - description: - "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", - }) - @IsString({ - each: true, - }) - readonly usedSoftware: string[]; - - @ApiProperty({ - type: Object, - required: false, - description: - "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", - }) - @IsOptional() - @IsObject() - readonly jobParameters?: Record; - - @ApiProperty({ - type: String, - required: false, - description: - "The output job logfile. Keep the size of this log data well below 15 MB.", - }) - @IsOptional() - @IsString() - readonly jobLogData?: string; -} - -export class PartialUpdateDerivedDatasetDto extends PartialType( - UpdateDerivedDatasetDto, -) {} diff --git a/src/datasets/dto/update-raw-dataset.dto.ts b/src/datasets/dto/update-raw-dataset.dto.ts deleted file mode 100644 index 5926b854f..000000000 --- a/src/datasets/dto/update-raw-dataset.dto.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { IsDateString, IsOptional, IsString } from "class-validator"; -import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; -import { ApiProperty, PartialType } from "@nestjs/swagger"; - -export class UpdateRawDatasetDto extends UpdateDatasetObsoleteDto { - /* we need to discuss if the naming is adequate. */ - @ApiProperty({ - type: String, - required: true, - description: - "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", - }) - @IsString() - readonly principalInvestigator: string; - - @ApiProperty({ - type: Date, - required: false, - description: - "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", - }) - @IsOptional() - @IsDateString() - readonly startTime?: Date; - - @ApiProperty({ - type: Date, - required: false, - description: - "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", - }) - @IsOptional() - @IsDateString() - readonly endTime?: Date; - - @ApiProperty({ - type: String, - required: true, - description: - "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", - }) - @IsString() - readonly creationLocation: string; - - @ApiProperty({ - type: String, - required: false, - description: - "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", - }) - @IsOptional() - @IsString() - readonly dataFormat?: string; - - @ApiProperty({ - type: String, - required: false, - description: "The ID of the proposal to which the dataset belongs.", - }) - @IsOptional() - @IsString() - readonly proposalId?: string; - - @ApiProperty({ - type: String, - required: false, - description: "ID of the sample used when collecting the data.", - }) - @IsOptional() - @IsString() - readonly sampleId?: string; - - @ApiProperty({ - type: String, - required: false, - description: "ID of the instrument where the data was created.", - }) - @IsOptional() - @IsString() - readonly instrumentId: string; - - @IsOptional() - investigator?: string; - - @IsOptional() - inputDatasets?: string[]; - - @IsOptional() - usedSoftware?: string[]; - - @IsOptional() - jobParameters?: Record; - - @IsOptional() - jobLogData?: string; -} - -export class PartialUpdateRawDatasetDto extends PartialType( - UpdateRawDatasetDto, -) {} diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index a50055b98..58fdcd1e4 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -455,7 +455,7 @@ export class DatasetClass extends OwnableClass { "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) @Prop({ type: String, ref: "Proposal", required: false }) - proposalId?: string; + proposalIds?: string; @ApiProperty({ type: [String], @@ -464,7 +464,7 @@ export class DatasetClass extends OwnableClass { "Single ID or array of IDS of the samples used when collecting the data.", }) @Prop({ type: [String], ref: "Sample", required: false }) - sampleId?: string[]; + sampleIds?: string[]; @ApiProperty({ type: [String], @@ -473,7 +473,7 @@ export class DatasetClass extends OwnableClass { "Id of the instrument or array of IDS of the instruments where the data contained in this dataset was created/acquired.", }) @Prop({ type: [String], ref: "Instrument", required: false }) - instrumentId?: string[]; + instrumentIds?: string[]; /* * Derived Dataset diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index f1a0f13be..308eb32e9 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -45,8 +45,8 @@ import { PartialUpdateDatasetDto } from "src/datasets/dto/update-dataset.dto"; import { filterDescription, filterExample } from "src/common/utils"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset.dto"; -import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset.dto"; +import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; import { logger } from "@user-office-software/duo-logger"; @ApiBearerAuth() diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index ab707200d..56a8b7717 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -45,7 +45,7 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -76,13 +76,14 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { password: TestData.Accounts["archiveManager"]["password"], }); }); - + afterEach((done) => { sandbox.restore(); done(); }); it("0010: adds dataset 1 as Admin Ingestor", async () => { + console.log(JSON.stringify(dataset1)); return request(appUrl) .post("/api/v3/Datasets") .send(dataset1) @@ -91,6 +92,8 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { + console.log("Results"); + console.log(res.body); res.body.should.have.property("ownerGroup").and.equal("group4"); res.body.should.have.property("type").and.equal("raw"); res.body.should.have.property("isPublished").and.equal(true); @@ -100,1440 +103,1440 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - it("0020: adds dataset 2 as Admin Ingestor", async () => { - return request(appUrl) - .post("/api/v3/Datasets") - .send(dataset2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("ownerGroup").and.equal("group1"); - res.body.should.have.property("type").and.equal("raw"); - res.body.should.have.property("isPublished").and.equal(false); - res.body.should.have.property("pid").and.be.string; - datasetPid2 = res.body["pid"]; - encodedDatasetPid2 = encodeURIComponent(datasetPid2); - }); - }); - - it("0030: adds dataset 3 as Admin Ingestor", async () => { - return request(appUrl) - .post("/api/v3/Datasets") - .send(dataset3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("ownerGroup").and.equal("group2"); - res.body.should.have.property("type").and.equal("raw"); - res.body.should.have.property("isPublished").and.equal(false); - res.body.should.have.property("pid").and.be.string; - datasetPid3 = res.body["pid"]; - encodedDatasetPid3 = encodeURIComponent(datasetPid3); - }); - }); - - it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) - .send(TestData.OrigDataBlockCorrect1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have - .property("size") - .and.equal(TestData.OrigDataBlockCorrect1.size); - res.body.should.have.property("id").and.be.string; - }); - }); - - it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { - const randomArchiveId = Math.random().toString(36).slice(2); - - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) - .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have - .property("size") - .and.equal(TestData.DataBlockCorrect.size); - res.body.should.have.property("id").and.be.string; - }); - }); - - it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) - .send(TestData.AttachmentCorrect) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/); - }); - - it("0070: list of public datasets, aka as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0080: access public dataset as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0090: access private dataset as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0100: list of datasets for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0110: datasets counts for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(3); - }); - }); - - it("0120: access dataset 1 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0130: full query for datasets for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0140: access dataset 2 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0150: access dataset 3 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0160: list of datasets for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - res.body[1]["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0170: datasets count for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(2); - }); - }); - - it("0180: access dataset 1 as User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0190: access dataset 2 as User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0210: full query for datasets for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0220: list of datasets for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - res.body[1]["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0230: datasets count for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(2); - }); - }); - - it("0240: access dataset 1 as User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0260: access dataset 3 as User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0270: full query for datasets for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0280: list of datasets for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0290: datasets count for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(3); - }); - }); - - it("0300: access dataset 1 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0310: access dataset 2 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0320: access dataset 3 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0330: full query for datasets for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - }); - }); - - it("0340: update dataset 2 to be published as Admin Ingestor", async () => { - return request(appUrl) - .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) - .send({ isPublished: true }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) - .expect("Content-Type", /json/); - }); - - it("0350: full query for datasets for User 2", async () => { - const fields = { - isPublished: true, - }; - - return request(appUrl) - .get( - `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( - JSON.stringify(fields), - )}`, - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - }); - }); - - it("0360: full facet for datasets for User 2", async () => { - const fields = { - isPublished: true, - }; - return request(appUrl) - .get( - `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( - JSON.stringify(fields), - )}`, - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body[0].all[0].totalSets.should.be.equal(2); - }); - }); - - it("0370: access dataset 1 origdatablocks as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0380: access dataset 1 datablocks as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0390: access dataset 1 attachments as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0400: access dataset 1 thumbnail as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode); - }); - - it("0410: should delete dataset 1 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0420: should delete dataset 2 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0430: should delete dataset 3 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0500: add a new raw dataset as Admin", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0502: add a new raw dataset with specified pid as Admin", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "admin", - }; - console.log("0502: pid : " + datasetWithPid["pid"]); - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: uuidv4(), - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0510: add a new raw dataset with different owner group as Admin", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); + // it("0020: adds dataset 2 as Admin Ingestor", async () => { + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(dataset2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("ownerGroup").and.equal("group1"); + // res.body.should.have.property("type").and.equal("raw"); + // res.body.should.have.property("isPublished").and.equal(false); + // res.body.should.have.property("pid").and.be.string; + // datasetPid2 = res.body["pid"]; + // encodedDatasetPid2 = encodeURIComponent(datasetPid2); + // }); + // }); + + // it("0030: adds dataset 3 as Admin Ingestor", async () => { + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(dataset3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("ownerGroup").and.equal("group2"); + // res.body.should.have.property("type").and.equal("raw"); + // res.body.should.have.property("isPublished").and.equal(false); + // res.body.should.have.property("pid").and.be.string; + // datasetPid3 = res.body["pid"]; + // encodedDatasetPid3 = encodeURIComponent(datasetPid3); + // }); + // }); + + // it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) + // .send(TestData.OrigDataBlockCorrect1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have + // .property("size") + // .and.equal(TestData.OrigDataBlockCorrect1.size); + // res.body.should.have.property("id").and.be.string; + // }); + // }); + + // it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { + // const randomArchiveId = Math.random().toString(36).slice(2); + + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) + // .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have + // .property("size") + // .and.equal(TestData.DataBlockCorrect.size); + // res.body.should.have.property("id").and.be.string; + // }); + // }); + + // it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) + // .send(TestData.AttachmentCorrect) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0070: list of public datasets, aka as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0080: access public dataset as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0090: access private dataset as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0100: list of datasets for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0110: datasets counts for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(3); + // }); + // }); + + // it("0120: access dataset 1 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0130: full query for datasets for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0140: access dataset 2 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0150: access dataset 3 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0160: list of datasets for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // res.body[1]["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0170: datasets count for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(2); + // }); + // }); + + // it("0180: access dataset 1 as User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0190: access dataset 2 as User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0210: full query for datasets for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0220: list of datasets for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // res.body[1]["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0230: datasets count for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(2); + // }); + // }); + + // it("0240: access dataset 1 as User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0260: access dataset 3 as User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0270: full query for datasets for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0280: list of datasets for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0290: datasets count for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(3); + // }); + // }); + + // it("0300: access dataset 1 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0310: access dataset 2 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0320: access dataset 3 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0330: full query for datasets for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // }); + // }); + + // it("0340: update dataset 2 to be published as Admin Ingestor", async () => { + // return request(appUrl) + // .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) + // .send({ isPublished: true }) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulPatchStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0350: full query for datasets for User 2", async () => { + // const fields = { + // isPublished: true, + // }; + + // return request(appUrl) + // .get( + // `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( + // JSON.stringify(fields), + // )}`, + // ) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // }); + // }); + + // it("0360: full facet for datasets for User 2", async () => { + // const fields = { + // isPublished: true, + // }; + // return request(appUrl) + // .get( + // `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( + // JSON.stringify(fields), + // )}`, + // ) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body[0].all[0].totalSets.should.be.equal(2); + // }); + // }); + + // it("0370: access dataset 1 origdatablocks as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0380: access dataset 1 datablocks as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0390: access dataset 1 attachments as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0400: access dataset 1 thumbnail as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode); + // }); + + // it("0410: should delete dataset 1 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0420: should delete dataset 2 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0430: should delete dataset 3 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0500: add a new raw dataset as Admin", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0502: add a new raw dataset with specified pid as Admin", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "admin", + // }; + // console.log("0502: pid : " + datasetWithPid["pid"]); + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: uuidv4(), + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0510: add a new raw dataset with different owner group as Admin", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); }); From fa3e93de0bb81d0527391a616f0cb3a4d201c55a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:36:13 +0000 Subject: [PATCH 197/258] build(deps): bump openid-client from 5.6.5 to 5.7.0 Bumps [openid-client](https://github.com/panva/node-openid-client) from 5.6.5 to 5.7.0. - [Release notes](https://github.com/panva/node-openid-client/releases) - [Changelog](https://github.com/panva/node-openid-client/blob/main/CHANGELOG.md) - [Commits](https://github.com/panva/node-openid-client/compare/v5.6.5...v5.7.0) --- updated-dependencies: - dependency-name: openid-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35dc1140e..a163d3361 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8734,9 +8734,9 @@ } }, "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -10759,11 +10759,11 @@ } }, "node_modules/openid-client": { - "version": "5.6.5", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.5.tgz", - "integrity": "sha512-5P4qO9nGJzB5PI0LFlhj4Dzg3m4odt0qsJTfyEtZyOlkgpILwEioOhVVJOrS1iVH494S4Ee5OCjjg6Bf5WOj3w==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.0.tgz", + "integrity": "sha512-4GCCGZt1i2kTHpwvaC/sCpTpQqDnBzDzuJcJMbH+y1Q5qI8U8RBvoSh28svarXszZHR5BAMXbJPX1PGPRE3VOA==", "dependencies": { - "jose": "^4.15.5", + "jose": "^4.15.9", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" From fc07f933f0375606ec332762b127b88c1f652344 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:47:51 +0000 Subject: [PATCH 198/258] build(deps): bump nodemailer from 6.9.14 to 6.9.15 Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.9.14 to 6.9.15. - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v6.9.14...v6.9.15) --- updated-dependencies: - dependency-name: nodemailer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a163d3361..794a5b23c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10597,9 +10597,9 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", - "integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==", + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", + "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", "engines": { "node": ">=6.0.0" } From 0cfd9ce8c3bb55ba76dd878e7b7b1d89a1200c0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:58:27 +0000 Subject: [PATCH 199/258] build(deps-dev): bump @types/node from 22.5.2 to 22.5.4 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.5.2 to 22.5.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 794a5b23c..5d9553034 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2994,9 +2994,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz", - "integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", "dependencies": { "undici-types": "~6.19.2" } From bcad5d28e1284c8cf06b29c4f01feea2addd18ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:09:00 +0000 Subject: [PATCH 200/258] build(deps-dev): bump concurrently from 8.2.2 to 9.0.0 Bumps [concurrently](https://github.com/open-cli-tools/concurrently) from 8.2.2 to 9.0.0. - [Release notes](https://github.com/open-cli-tools/concurrently/releases) - [Commits](https://github.com/open-cli-tools/concurrently/compare/v8.2.2...v9.0.0) --- updated-dependencies: - dependency-name: concurrently dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 18 +++++------------- package.json | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d9553034..6078c16f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ "@typescript-eslint/parser": "^7.3.0", "chai": "^5.0.0", "chai-http": "^4.3.6", - "concurrently": "^8.0.1", + "concurrently": "^9.0.0", "eslint": "^8.46.0", "eslint-config-loopback": "^13.1.0", "eslint-config-prettier": "^9.0.0", @@ -5073,17 +5073,15 @@ } }, "node_modules/concurrently": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", - "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.0.0.tgz", + "integrity": "sha512-iAxbsDeUkn8E/4+QalT7T3WvlyTfmsoez+19lbbcsxZdOEMfBukd8LA30KYez2UR5xkKFzbcqXIZy5RisCbaxw==", "dev": true, "dependencies": { "chalk": "^4.1.2", - "date-fns": "^2.30.0", "lodash": "^4.17.21", "rxjs": "^7.8.1", "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", "supports-color": "^8.1.1", "tree-kill": "^1.2.2", "yargs": "^17.7.2" @@ -5093,7 +5091,7 @@ "concurrently": "dist/bin/concurrently.js" }, "engines": { - "node": "^14.13.0 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" @@ -12509,12 +12507,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/spawn-command": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", - "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", - "dev": true - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", diff --git a/package.json b/package.json index 748681b4c..14df56fb1 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "@typescript-eslint/parser": "^7.3.0", "chai": "^5.0.0", "chai-http": "^4.3.6", - "concurrently": "^8.0.1", + "concurrently": "^9.0.0", "eslint": "^8.46.0", "eslint-config-loopback": "^13.1.0", "eslint-config-prettier": "^9.0.0", From cffb06064b5a2df33a817df08de94fee6455a5d3 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 11 Sep 2024 15:01:03 +0200 Subject: [PATCH 201/258] fix types on obsolete schemas --- src/datasets/datasets.controller.ts | 54 +++++++++++++++++------------ 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 89e6f7536..19c480a9d 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -632,14 +632,14 @@ export class DatasetsController { ); const dtoTestRawCorrect = plainToInstance( - CreateRawDatasetDto, - createDatasetDto, + CreateRawDatasetObsoleteDto, + createDatasetObsoleteDto, ); const errorsTestRawCorrect = await validate(dtoTestRawCorrect); const dtoTestDerivedCorrect = plainToInstance( - CreateDerivedDatasetDto, - createDatasetDto, + CreateDerivedDatasetObsoleteDto, + createDatasetObsoleteDto, ); const errorsTestDerivedCorrect = await validate(dtoTestDerivedCorrect); @@ -1109,7 +1109,7 @@ export class DatasetsController { @Req() request: Request, @Param("pid") id: string, ): Promise { - const dataset = await this.checkPermissionsForDataset(request, id); + const dataset = await this.checkPermissionsForDatasetObsolete(request, id); return dataset; } @@ -1137,15 +1137,18 @@ export class DatasetsController { description: "Id of the dataset to modify", type: String, }) - @ApiExtraModels(PartialUpdateRawDatasetDto, PartialUpdateDerivedDatasetDto) + @ApiExtraModels( + PartialUpdateRawDatasetObsoleteDto, + PartialUpdateDerivedDatasetObsoleteDto, + ) @ApiBody({ description: "Fields that needs to be updated in the dataset. Only the fields that needs to be updated have to be passed in.", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(PartialUpdateRawDatasetDto) }, - { $ref: getSchemaPath(PartialUpdateDerivedDatasetDto) }, + { $ref: getSchemaPath(PartialUpdateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(PartialUpdateDerivedDatasetObsoleteDto) }, ], }, }) @@ -1160,8 +1163,8 @@ export class DatasetsController { @Param("pid") pid: string, @Body() updateDatasetDto: - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto, + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto, ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); @@ -1170,11 +1173,11 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - await this.validateDataset( + await this.validateDatasetObsolete( updateDatasetDto, foundDataset.type === "raw" - ? PartialUpdateRawDatasetDto - : PartialUpdateDerivedDatasetDto, + ? PartialUpdateRawDatasetObsoleteDto + : PartialUpdateDerivedDatasetObsoleteDto, ); // NOTE: We need DatasetClass instance because casl module can not recognize the type from dataset mongo database model. If other fields are needed can be added later. @@ -1220,15 +1223,15 @@ export class DatasetsController { description: "Id of the dataset to modify", type: String, }) - @ApiExtraModels(UpdateRawDatasetDto, UpdateDerivedDatasetDto) + @ApiExtraModels(UpdateRawDatasetObsoleteDto, UpdateDerivedDatasetObsoleteDto) @ApiBody({ description: "Dataset object that needs to be updated. The whole dataset object with updated fields have to be passed in.", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(UpdateRawDatasetDto) }, - { $ref: getSchemaPath(UpdateDerivedDatasetDto) }, + { $ref: getSchemaPath(UpdateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(UpdateDerivedDatasetObsoleteDto) }, ], }, }) @@ -1241,7 +1244,10 @@ export class DatasetsController { async findByIdAndReplace( @Req() request: Request, @Param("pid") pid: string, - @Body() updateDatasetDto: UpdateRawDatasetDto | UpdateDerivedDatasetDto, + @Body() + updateDatasetObsoleteDto: + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); @@ -1250,11 +1256,11 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - const outputDto = await this.validateDataset( - updateDatasetDto, + const outputDto = await this.validateDatasetObsolete( + updateDatasetObsoleteDto, foundDataset.type === "raw" - ? UpdateRawDatasetDto - : UpdateDerivedDatasetDto, + ? UpdateRawDatasetObsoleteDto + : UpdateDerivedDatasetObsoleteDto, ); const datasetInstance = @@ -1274,7 +1280,9 @@ export class DatasetsController { return this.datasetsService.findByIdAndReplace( pid, - outputDto as UpdateRawDatasetDto | UpdateDerivedDatasetDto, + outputDto as + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, ); } @@ -2172,7 +2180,7 @@ export class DatasetsController { Action.DatasetLogbookRead, ); - const proposalId = dataset?.proposalId; + const proposalId = (dataset?.proposalIds || [])[0]; if (!proposalId) return null; From c6416645d6996612132a0ff90066bca3f00b8078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:39:52 +0000 Subject: [PATCH 202/258] build(deps-dev): bump @faker-js/faker from 8.4.1 to 9.0.0 Bumps [@faker-js/faker](https://github.com/faker-js/faker) from 8.4.1 to 9.0.0. - [Release notes](https://github.com/faker-js/faker/releases) - [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md) - [Commits](https://github.com/faker-js/faker/compare/v8.4.1...v9.0.0) --- updated-dependencies: - dependency-name: "@faker-js/faker" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6078c16f7..0775f4673 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "uuid": "^10.0.0" }, "devDependencies": { - "@faker-js/faker": "^8.0.1", + "@faker-js/faker": "^9.0.0", "@nestjs/cli": "^10.0.5", "@nestjs/schematics": "^10.0.1", "@nestjs/testing": "^10.3.8", @@ -1241,9 +1241,9 @@ } }, "node_modules/@faker-js/faker": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.4.1.tgz", - "integrity": "sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.0.0.tgz", + "integrity": "sha512-dTDHJSmz6c1OJ6HO7jiUiIb4sB20Dlkb3pxYsKm0qTXm2Bmj97rlXIhlvaFsW2rvCi+OLlwKLVSS6ZxFUVZvjQ==", "dev": true, "funding": [ { @@ -1252,8 +1252,8 @@ } ], "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0", - "npm": ">=6.14.13" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "node_modules/@hapi/hoek": { diff --git a/package.json b/package.json index 14df56fb1..5e0a998b7 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ } }, "devDependencies": { - "@faker-js/faker": "^8.0.1", + "@faker-js/faker": "^9.0.0", "@nestjs/cli": "^10.0.5", "@nestjs/schematics": "^10.0.1", "@nestjs/testing": "^10.3.8", From f79e5f99726bd5420558232894ad598669d1deca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:50:37 +0000 Subject: [PATCH 203/258] build(deps): bump mongoose from 8.5.4 to 8.6.2 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.4 to 8.6.2. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.5.4...8.6.2) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0775f4673..42c8412f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10299,9 +10299,9 @@ } }, "node_modules/mongodb": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", - "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", + "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -10384,13 +10384,13 @@ } }, "node_modules/mongoose": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.4.tgz", - "integrity": "sha512-nG3eehhWf9l1q80WuHvp5DV+4xDNFpDWLE5ZgcFD5tslUV2USJ56ogun8gaZ62MKAocJnoStjAdno08b8U57hg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.6.2.tgz", + "integrity": "sha512-ErbDVvuUzUfyQpXvJ6sXznmZDICD8r6wIsa0VKjJtB6/LZncqwUn5Um040G1BaNo6L3Jz+xItLSwT0wZmSmUaQ==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.7.0", + "mongodb": "6.8.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", From fc8127231ab1d99ac3aca6691980cd565378ad46 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Sep 2024 15:56:54 +0200 Subject: [PATCH 204/258] updated to use latest dataset schema in service --- src/datasets/datasets.controller.ts | 125 +++++++++++++++++-------- src/datasets/datasets.service.ts | 47 ++++------ src/datasets/dto/update-dataset.dto.ts | 20 ++++ 3 files changed, 123 insertions(+), 69 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 19c480a9d..9071f6e53 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -100,6 +100,10 @@ import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; +import { + PartialUpdateDatasetDto, + UpdateDatasetDto, +} from "./dto/update-dataset.dto"; @ApiBearerAuth() @ApiExtraModels( @@ -393,60 +397,98 @@ export class DatasetsController { } convertObsoleteToCurrentSchema( - inputDataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, - ): CreateDatasetDto { + inputObsoleteDataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto, + ): CreateDatasetDto | UpdateDatasetDto | PartialUpdateDatasetDto { const propertiesModifier: Record = {}; - if (inputDataset.type == "raw") { - if ("proposalId" in inputDataset) { + + if ( + inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof UpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof PartialUpdateRawDatasetObsoleteDto + ) { + if ("proposalId" in inputObsoleteDataset) { propertiesModifier.proposalIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).proposalId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).proposalId, ]; } - if ("sampleId" in inputDataset) { + if ("sampleId" in inputObsoleteDataset) { propertiesModifier.sampleIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).sampleId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).sampleId, ]; } - if ("instrumentIds" in inputDataset) { + if ("instrumentIds" in inputObsoleteDataset) { propertiesModifier.instrumentIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).instrumentId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).instrumentId, ]; } } else { - if ("investigator" in inputDataset) { + if ("investigator" in inputObsoleteDataset) { propertiesModifier.principalInvestigator = [ - (inputDataset as CreateDerivedDatasetObsoleteDto).investigator, + (inputObsoleteDataset as CreateDerivedDatasetObsoleteDto) + .investigator, ]; } } - const outputDataset: CreateDatasetDto = { - ...(inputDataset as CreateDatasetDto), - ...propertiesModifier, - }; + let outputDataset: + | CreateDatasetDto + | UpdateDatasetDto + | PartialUpdateDatasetDto = {}; + if ( + inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof CreateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as CreateDatasetDto), + ...propertiesModifier, + } as CreateDatasetDto; + } else if ( + inputObsoleteDataset instanceof UpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof UpdateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as UpdateDatasetDto), + ...propertiesModifier, + } as UpdateDatasetDto; + } else if ( + inputObsoleteDataset instanceof PartialUpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof PartialUpdateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as PartialUpdateDatasetDto), + ...propertiesModifier, + } as PartialUpdateDatasetDto; + } return outputDataset; } convertCurrentToObsoleteSchema( - inputDataset: DatasetClass, + inputDataset: DatasetClass | null, ): OutputDatasetObsoleteDto { const propertiesModifier: Record = {}; - if ("proposalIds" in inputDataset) { - propertiesModifier.proposalIds = inputDataset.proposalIds![0]; - } - if ("sampleIds" in inputDataset) { - propertiesModifier.sampleIds = inputDataset.sampleIds![0]; - } - if ("instrumentIds" in inputDataset) { - propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; - } - if (inputDataset.type == "raw") { - if ("investigator" in inputDataset) { - propertiesModifier.investigator = inputDataset.principalInvestigator; + if (inputDataset) { + if ("proposalIds" in inputDataset) { + propertiesModifier.proposalIds = inputDataset.proposalIds![0]; + } + if ("sampleIds" in inputDataset) { + propertiesModifier.sampleIds = inputDataset.sampleIds![0]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; + } + if (inputDataset.type == "raw") { + if ("investigator" in inputDataset) { + propertiesModifier.investigator = inputDataset.principalInvestigator; + } } } - const outputDataset: OutputDatasetObsoleteDto = { ...(inputDataset as OutputDatasetObsoleteDto), ...propertiesModifier, @@ -509,8 +551,9 @@ export class DatasetsController { ); try { - const datasetDto = - this.convertObsoleteToCurrentSchema(obsoleteDatasetDto); + const datasetDto = this.convertObsoleteToCurrentSchema( + obsoleteDatasetDto, + ) as CreateDatasetDto; const createdDataset = await this.datasetsService.create(datasetDto); const outputObsoleteDatasetDto = @@ -772,7 +815,7 @@ export class DatasetsController { async fullquery( @Req() request: Request, @Query() filters: { fields?: string; limits?: string }, - ): Promise { + ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); @@ -809,7 +852,9 @@ export class DatasetsController { limits: JSON.parse(filters.limits ?? "{}"), }; - return this.datasetsService.fullquery(parsedFilters); + const results = await this.datasetsService.fullquery(parsedFilters); + + return results as OutputDatasetObsoleteDto[]; } // GET /fullfacets @@ -1108,10 +1153,12 @@ export class DatasetsController { async findById( @Req() request: Request, @Param("pid") id: string, - ): Promise { - const dataset = await this.checkPermissionsForDatasetObsolete(request, id); + ): Promise { + const dataset = this.convertCurrentToObsoleteSchema( + await this.checkPermissionsForDatasetObsolete(request, id), + ); - return dataset; + return dataset as OutputDatasetObsoleteDto; } // PATCH /datasets/:id @@ -1165,7 +1212,7 @@ export class DatasetsController { updateDatasetDto: | PartialUpdateRawDatasetObsoleteDto | PartialUpdateDerivedDatasetObsoleteDto, - ): Promise { + ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); if (!foundDataset) { @@ -1196,7 +1243,9 @@ export class DatasetsController { throw new ForbiddenException("Unauthorized to update this dataset"); } - return this.datasetsService.findByIdAndUpdate(pid, updateDatasetDto); + return this.convertCurrentToObsoleteSchema( + await this.datasetsService.findByIdAndUpdate(pid, updateDatasetDto), + ); } // PUT /datasets/:id diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 60793750d..723552172 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -25,20 +25,13 @@ import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.se import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; -import { - PartialUpdateDatasetObsoleteDto, - UpdateDatasetObsoleteDto, -} from "./dto/update-dataset-obsolete.dto"; -import { - PartialUpdateDerivedDatasetDto, - UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset-obsolete.dto"; -import { - PartialUpdateRawDatasetDto, - UpdateRawDatasetDto, -} from "./dto/update-raw-dataset-obsolete.dto"; import { IDatasetFields } from "./interfaces/dataset-filters.interface"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; +import { + PartialUpdateDatasetDto, + PartialUpdateDatasetWithHistoryDto, + UpdateDatasetDto, +} from "./dto/update-dataset.dto"; @Injectable({ scope: Scope.REQUEST }) export class DatasetsService { @@ -205,10 +198,7 @@ export class DatasetsService { // we update the full dataset if exist or create a new one if it does not async findByIdAndReplace( id: string, - updateDatasetDto: - | UpdateDatasetObsoleteDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto, + updateDatasetDto: UpdateDatasetDto, ): Promise { const username = (this.request.user as JWTUser).username; const existingDataset = await this.datasetModel.findOne({ pid: id }).exec(); @@ -252,10 +242,8 @@ export class DatasetsService { async findByIdAndUpdate( id: string, updateDatasetDto: - | PartialUpdateDatasetObsoleteDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateQuery, + | PartialUpdateDatasetDto + | PartialUpdateDatasetWithHistoryDto, ): Promise { const existingDataset = await this.datasetModel.findOne({ pid: id }).exec(); // check if we were able to find the dataset @@ -434,7 +422,7 @@ export class DatasetsService { async updateHistory( req: Request, dataset: DatasetClass, - data: UpdateDatasetObsoleteDto, + data: PartialUpdateDatasetDto, ) { if (req.body.history) { delete req.body.history; @@ -442,17 +430,17 @@ export class DatasetsService { if (!req.body.size && !req.body.packedSize) { const updatedFields: Omit< - UpdateDatasetObsoleteDto, + PartialUpdateDatasetDto, "updatedAt" | "updatedBy" > = data; const historyItem: Record = {}; Object.keys(updatedFields).forEach((updatedField) => { - historyItem[updatedField as keyof UpdateDatasetObsoleteDto] = { - currentValue: data[updatedField as keyof UpdateDatasetObsoleteDto], + historyItem[updatedField as keyof UpdateDatasetDto] = { + currentValue: data[updatedField as keyof UpdateDatasetDto], previousValue: dataset[ updatedField as keyof Omit< - UpdateDatasetObsoleteDto, + UpdateDatasetDto, "attachments" | "origdatablocks" | "datablocks" > ], @@ -468,18 +456,15 @@ export class DatasetsService { if (logbookEnabled) { const user = (req.user as JWTUser).username.replace("ldap.", ""); const datasetPid = dataset.pid; - const proposalId = - dataset.type === DatasetType.Raw - ? (dataset as unknown as DatasetClass).proposalId - : undefined; - if (proposalId) { + const proposalIds = dataset.proposalIds || []; + (proposalIds as Array).forEach(async (proposalId) => { await Promise.all( Object.keys(updatedFields).map(async (updatedField) => { const message = `${user} updated "${updatedField}" of dataset with PID ${datasetPid}`; await this.logbooksService.sendMessage(proposalId, { message }); }), ); - } + }); } } } diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index ad928772f..26866705d 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -24,6 +24,7 @@ import { CreateTechniqueDto } from "./create-technique.dto"; import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; +import { HistoryClass } from "../schemas/history.schema"; @ApiTags("datasets") export class UpdateDatasetDto extends OwnableDto { @@ -420,3 +421,22 @@ export class UpdateDatasetDto extends OwnableDto { } export class PartialUpdateDatasetDto extends PartialType(UpdateDatasetDto) {} + +export class UpdateDatasetWithHistoryDto extends UpdateDatasetDto { + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(HistoryClass) }, + required: false, + default: [], + description: "List of history objects containing old and new values.", + }) + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => HistoryClass) + readonly history?: HistoryClass[]; +} + +export class PartialUpdateDatasetWithHistoryDto extends PartialType( + UpdateDatasetWithHistoryDto, +) {} From 41d304cb331ded691f2bcc977d3fa9a4b54a39fa Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Sep 2024 16:04:08 +0200 Subject: [PATCH 205/258] refactoring data types --- src/datasets/datasets.controller.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 9071f6e53..575adc98b 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -1297,7 +1297,7 @@ export class DatasetsController { updateDatasetObsoleteDto: | UpdateRawDatasetObsoleteDto | UpdateDerivedDatasetObsoleteDto, - ): Promise { + ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); if (!foundDataset) { @@ -1305,7 +1305,7 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - const outputDto = await this.validateDatasetObsolete( + const updateValidatedDto = await this.validateDatasetObsolete( updateDatasetObsoleteDto, foundDataset.type === "raw" ? UpdateRawDatasetObsoleteDto @@ -1327,12 +1327,15 @@ export class DatasetsController { throw new ForbiddenException("Unauthorized to update this dataset"); } - return this.datasetsService.findByIdAndReplace( + const updateDatasetDto = + await this.convertObsoleteToCurrentSchema(updateValidatedDto); + + const outputDatasetDto = await this.datasetsService.findByIdAndReplace( pid, - outputDto as - | UpdateRawDatasetObsoleteDto - | UpdateDerivedDatasetObsoleteDto, + updateDatasetDto as UpdateDatasetDto, ); + + return await this.convertCurrentToObsoleteSchema(outputDatasetDto); } // DELETE /datasets/:id From e986e218d82f951be518f6096da291749c718ee1 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 16 Sep 2024 10:18:30 +0200 Subject: [PATCH 206/258] feat: add OpenAPI configuration files and new SDK artifact upload workflow --- .github/openapi/python-config.json | 4 +- .../openapi/python-pydantic-v1-config.json | 5 + .github/openapi/typescript-config.json | 2 +- .github/workflows/github-tag-and-release.yml | 78 ------ .github/workflows/publish-sdk-packages.yml | 166 ------------ .github/workflows/release-and-publish-sdk.yml | 242 ++++++++++++++++++ .github/workflows/upload-sdk-artifact.yml | 82 ++++++ 7 files changed, 332 insertions(+), 247 deletions(-) create mode 100644 .github/openapi/python-pydantic-v1-config.json delete mode 100644 .github/workflows/github-tag-and-release.yml delete mode 100644 .github/workflows/publish-sdk-packages.yml create mode 100644 .github/workflows/release-and-publish-sdk.yml create mode 100644 .github/workflows/upload-sdk-artifact.yml diff --git a/.github/openapi/python-config.json b/.github/openapi/python-config.json index 1323b5f58..709747cf2 100644 --- a/.github/openapi/python-config.json +++ b/.github/openapi/python-config.json @@ -1,5 +1,5 @@ { "generatorName": "python", - "packageName": "Scicat-Python-SDK", - "projectName": "Scicat-Python-SDK" + "packageName": "scicat-sdk-py", + "projectName": "scicat-sdk-py" } diff --git a/.github/openapi/python-pydantic-v1-config.json b/.github/openapi/python-pydantic-v1-config.json new file mode 100644 index 000000000..ef10d66f2 --- /dev/null +++ b/.github/openapi/python-pydantic-v1-config.json @@ -0,0 +1,5 @@ +{ + "generatorName": "python-pydantic-v1", + "packageName": "scicat-sdk-pydantic", + "projectName": "scicat-sdk-pydantic" +} diff --git a/.github/openapi/typescript-config.json b/.github/openapi/typescript-config.json index 4248aecec..fc279bbcf 100644 --- a/.github/openapi/typescript-config.json +++ b/.github/openapi/typescript-config.json @@ -1,6 +1,6 @@ { "generatorName": "typescript-angular", - "npmName": "@scicat-sdk/typescript-angular", + "npmName": "@scicatproject/scicat-sdk-ts", "ngVersion": "16.2.12", "withInterfaces": true } diff --git a/.github/workflows/github-tag-and-release.yml b/.github/workflows/github-tag-and-release.yml deleted file mode 100644 index 6b3ddb5cc..000000000 --- a/.github/workflows/github-tag-and-release.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Bump release version and build-push - -on: - push: - branches: - - release - -env: - NODE_VERSION: 20.x - RELEASE_BRANCH: release - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - ## Commit message examples for Release type (patch|minor|major) can be found: - ## https://github.com/mathieudutour/github-tag-action - - name: Bump version and push tag - id: tag_version - uses: mathieudutour/github-tag-action@v6.2 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - release_branches: ${{ env.RELEASE_BRANCH }} - - - name: Create a GitHub release - uses: ncipollo/release-action@v1 - with: - tag: ${{ steps.tag_version.outputs.new_tag }} - name: Release ${{ steps.tag_version.outputs.new_tag }} - body: ${{ steps.tag_version.outputs.changelog }} - - ## The setup-qemu-action simplifies the setup of QEMU for cross-platform builds - ## https://github.com/docker/setup-qemu-action - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install Node.js dependencies - run: npm ci - - ## The metadata-action dynamically generates and manages metadata for Docker images, - ## like tags and labels, based on the provided inputs and workflow context. - ## https://github.com/docker/metadata-action - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/scicatproject/backend-next - tags: | - type=raw,value=stable - type=raw,value=${{ steps.tag_version.outputs.new_tag }} - type=semver,pattern={{version}} - type=raw,value={{date 'YYYY_MM'}},prefix=r_ - - - name: Build and push - uses: docker/build-push-action@v6 - with: - context: . - platforms: linux/amd64,linux/arm64/v8 - push: true - tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/publish-sdk-packages.yml b/.github/workflows/publish-sdk-packages.yml deleted file mode 100644 index fc0bc77ad..000000000 --- a/.github/workflows/publish-sdk-packages.yml +++ /dev/null @@ -1,166 +0,0 @@ -name: Generate and Publish SDK for multiple languages - -on: - workflow_run: - workflows: ["Bump release version and build-push"] - types: - - completed - -env: - NODE_VERSION: 18.x - PYTHON_VERSION: 3.x - -jobs: - start-backend-and-upload-swagger-schema: - runs-on: ubuntu-latest - outputs: - current-version: ${{ steps.package-version.outputs.current-version }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{env.NODE_VERSION}} - - - name: get-npm-version - id: package-version - uses: martinbeentjes/npm-get-version-action@v1.3.1 - - - name: Pull MongoDB Image - run: | - docker pull mongo:latest - docker run -d --name mongo-container -p 27017:27017 mongo:latest - - - name: Install Backend and wait for it to be ready - env: - MONGODB_URI: "mongodb://localhost:27017/scicat" - JWT_SECRET: thisIsTheJwtSecret - run: | - npm install -g wait-on && npm install - npm run start & wait-on http://localhost:3000/api/v3/health --timeout 200000 - - - name: Download the Swagger schema - run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json - - - uses: actions/upload-artifact@v4 - with: - name: swagger-schema - path: ./swagger-schema.json - - generate-and-upload-sdk: - runs-on: ubuntu-latest - needs: start-backend-and-upload-swagger-schema - strategy: - matrix: - generator: [python, typescript] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set packageVersion variable - run: echo "packageVersion=${{ needs.start-backend-and-upload-swagger-schema.outputs.current-version }}" >> $GITHUB_ENV - - - uses: actions/download-artifact@v4 - with: - name: swagger-schema - path: . - - - name: Check packageVersion - run: | - if [ -z "$packageVersion" ]; then - echo "packageVersion is not set, exiting..." - exit 1 - fi - - - name: Generate Client - uses: openapi-generators/openapitools-generator-action@v1 - with: - generator: ${{ matrix.generator }} - openapi-file: ./swagger-schema.json - config-file: .github/openapi/${{ matrix.generator }}-config.json - command-args: | - -o ./sdk/${{ matrix.generator }} $( - if [ "${{ matrix.generator }}" == "typescript" ]; then - echo "--additional-properties=npmVersion=$packageVersion"; - elif [ "${{ matrix.generator }}" == "python" ]; then - echo "--additional-properties=packageVersion=$packageVersion"; - fi - ) - - - uses: actions/upload-artifact@v4 - with: - name: sdk-${{ matrix.generator }} - path: ./sdk - - npm-publish: - needs: generate-and-upload-sdk - runs-on: ubuntu-latest - environment: - name: npm-sdk-package - url: https://www.npmjs.com/package/@scicat-sdk/typescript-angular - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - registry-url: "https://registry.npmjs.org/" - - - uses: actions/download-artifact@v4 - with: - name: sdk-typescript - path: ./sdk - - - name: Publish package - run: | - npm install - npm run build - npm publish --access public - working-directory: ./sdk/typescript/ - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - pypi-publish: - needs: generate-and-upload-sdk - runs-on: ubuntu-latest - environment: - name: pypi-sdk-package - url: https://pypi.org/p/Scicat-Python-SDK - permissions: - id-token: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - uses: actions/download-artifact@v4 - with: - name: sdk-python - path: ./sdk - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel - working-directory: ./sdk/python/ - - - name: Build package - run: | - python setup.py sdist bdist_wheel - working-directory: ./sdk/python/ - - - name: Publish package - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: ./sdk/python/dist/ diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml new file mode 100644 index 000000000..4228642e6 --- /dev/null +++ b/.github/workflows/release-and-publish-sdk.yml @@ -0,0 +1,242 @@ +name: Bump release version, build-push image and publish SDK + +on: + push: + branches: + - release + +env: + NODE_VERSION: 20.x + PYTHON_VERSION: 3.x + RELEASE_BRANCH: release + +jobs: + build-release: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + outputs: + new_tag: ${{ steps.without_v.outputs.tag }} + changelog: ${{ steps.tag_version.outputs.changelog }} + + steps: + - uses: actions/checkout@v4 + + ## Commit message examples for Release type (patch|minor|major) can be found: + ## https://github.com/mathieudutour/github-tag-action + - name: Bump version and push tag + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + release_branches: ${{ env.RELEASE_BRANCH }} + + - name: Strip 'v' from the tag + id: without_v + run: | + TAG=${{ steps.tag_version.outputs.new_tag }} + WITHOUT_V=${TAG#v} + echo "tag=$WITHOUT_V" >> $GITHUB_OUTPUT + + - name: Create a GitHub release + uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.tag_version.outputs.new_tag }} + name: Release ${{ steps.tag_version.outputs.new_tag }} + body: ${{ steps.tag_version.outputs.changelog }} + + ## The setup-qemu-action simplifies the setup of QEMU for cross-platform builds + ## https://github.com/docker/setup-qemu-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install Node.js dependencies + run: npm ci + + ## The metadata-action dynamically generates and manages metadata for Docker images, + ## like tags and labels, based on the provided inputs and workflow context. + ## https://github.com/docker/metadata-action + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/scicatproject/backend-next + tags: | + type=raw,value=stable + type=raw,value=${{ steps.tag_version.outputs.new_tag }} + type=semver,pattern={{version}} + type=raw,value={{date 'YYYY_MM'}},prefix=r_ + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64/v8 + push: true + tags: ${{ steps.meta.outputs.tags }} + + start-backend-export-swagger: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{env.NODE_VERSION}} + + - name: Pull and Run MongoDB + run: | + docker pull mongo:latest + docker run -d --name mongo-container -p 27017:27017 mongo:latest + + - name: Install Backend and wait for it to be ready + env: + MONGODB_URI: "mongodb://localhost:27017/scicat" + JWT_SECRET: thisIsTheJwtSecret + run: | + npm install -g wait-on && npm install + npm run start & wait-on http://localhost:3000/api/v3/health --timeout 200000 + + - name: Download the Swagger schema + run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json + + - uses: actions/upload-artifact@v4 + with: + name: swagger-schema + path: ./swagger-schema.json + + generate-upload-sdk: + runs-on: ubuntu-latest + needs: + - build-release + - start-backend-export-swagger + strategy: + matrix: + generator: [python, python-pydantic-v1, typescript] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: swagger-schema + path: . + + - name: Generate Client + uses: openapi-generators/openapitools-generator-action@v1 + with: + generator: ${{ matrix.generator }} + openapi-file: ./swagger-schema.json + config-file: .github/openapi/${{ matrix.generator }}-config.json + command-args: | + --git-repo-id scicat-backend-next \ + --git-user-id SciCatProject \ + -o ./sdk/${{ matrix.generator }} $( + if [ "${{ matrix.generator }}" == "typescript" ]; then + echo "--additional-properties=npmVersion=${{ needs.build-release.outputs.new_tag}}"; + elif [ "${{ matrix.generator }}" == "python" ]; then + echo "--additional-properties=packageVersion=${{ needs.build-release.outputs.new_tag}}"; + elif [ "${{ matrix.generator }}" == "python-pydantic-v1" ]; then + echo "--additional-properties=packageVersion=${{ needs.build-release.outputs.new_tag}}"; + fi + ) + + - uses: actions/upload-artifact@v4 + with: + name: sdk-${{ matrix.generator }}-${{ github.sha }} + path: ./sdk + + npm-publish: + needs: generate-upload-sdk + runs-on: ubuntu-latest + environment: + name: npm-sdk-package + url: https://www.npmjs.com/package/@scicatproject/scicat-sdk-ts + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + registry-url: "https://registry.npmjs.org/" + + - name: Download TypeScript SDK Artifact + uses: actions/download-artifact@v4 + with: + name: sdk-typescript-${{github.sha}} + path: ./sdk + + - name: Publish package + run: | + npm install + npm run build + npm publish --access public + working-directory: ./sdk/typescript/ + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + pypi-publish: + needs: generate-upload-sdk + runs-on: ubuntu-latest + strategy: + matrix: + sdk_type: [python, python-pydantic-v1] + environment: + name: ${{ matrix.sdk_type }}-sdk-package + url: ${{ matrix.sdk_type == 'python' && 'https://pypi.org/project/scicat-sdk-py' || 'https://pypi.org/project/scicat-sdk-pydantic' }} + permissions: + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Download Python SDK Artifact + uses: actions/download-artifact@v4 + with: + name: sdk-${{ matrix.sdk_type }}-${{github.sha}} + path: ./sdk + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel + working-directory: ./sdk/${{ matrix.sdk_type }}/ + + - name: Build package + run: | + python setup.py sdist bdist_wheel + working-directory: ./sdk/${{ matrix.sdk_type }}/ + + - name: Publish package + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: ./sdk/${{ matrix.sdk_type }}/dist/ diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml new file mode 100644 index 000000000..cbce35fc4 --- /dev/null +++ b/.github/workflows/upload-sdk-artifact.yml @@ -0,0 +1,82 @@ +name: Generate and upload latest SDK artifacts + +on: + push: + branches: + - master + +env: + NODE_VERSION: 20.x + SDK_VERSION: latest + +jobs: + start-backend-and-upload-swagger-schema: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{env.NODE_VERSION}} + + - name: Pull MongoDB Image + run: | + docker pull mongo:latest + docker run -d --name mongo-container -p 27017:27017 mongo:latest + + - name: Install Backend and wait for it to be ready + env: + MONGODB_URI: "mongodb://localhost:27017/scicat" + JWT_SECRET: thisIsTheJwtSecret + run: | + npm install -g wait-on && npm install + npm run start & wait-on http://localhost:3000/api/v3/health --timeout 200000 + + - name: Download the Swagger schema + run: curl -o ./swagger-schema.json http://localhost:3000/explorer-json + + - uses: actions/upload-artifact@v4 + with: + name: swagger-schema + path: ./swagger-schema.json + + generate-and-upload-sdk: + runs-on: ubuntu-latest + needs: + - start-backend-and-upload-swagger-schema + strategy: + matrix: + generator: [python, typescript, python-pydantic-v1] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + name: swagger-schema + path: . + + - name: Generate Client + uses: openapi-generators/openapitools-generator-action@v1 + with: + generator: ${{ matrix.generator }} + openapi-file: ./swagger-schema.json + config-file: .github/openapi/${{ matrix.generator }}-config.json + command-args: | + -o ./sdk/${{ matrix.generator }} $( + if [ "${{ matrix.generator }}" == "typescript" ]; then + echo "--additional-properties=npmVersion=${{env.SDK_VERSION}}"; + elif [ "${{ matrix.generator }}" == "python" ]; then + echo "--additional-properties=packageVersion=${{env.SDK_VERSION}}"; + elif [ "${{ matrix.generator }}" == "python-pydantic-v1" ]; then + echo "--additional-properties=packageVersion=${{env.SDK_VERSION}}"; + fi + ) + + - uses: actions/upload-artifact@v4 + with: + name: sdk-${{ matrix.generator }}-${{ github.sha }} + path: ./sdk From 0c3b316dcf153c18ac05f6cfc9b4a0c4695ac5c0 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Mon, 16 Sep 2024 14:31:38 +0200 Subject: [PATCH 207/258] First two dataset test passing --- src/datasets/datasets.controller.ts | 27 +++++++++----- src/datasets/schemas/dataset.schema.ts | 6 +-- .../origdatablocks.controller.ts | 9 +++-- .../published-data.controller.ts | 8 +++- test/DatasetAuthorization.js | 37 +++++++++---------- 5 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 575adc98b..9e1430701 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -61,7 +61,7 @@ import { DatablocksService } from "src/datablocks/datablocks.service"; import { Datablock } from "src/datablocks/schemas/datablock.schema"; import { CreateDatablockDto } from "src/datablocks/dto/create-datablock.dto"; import { PartialUpdateDatablockDto } from "src/datablocks/dto/update-datablock.dto"; -import { UpdateQuery } from "mongoose"; +import { Document, UpdateQuery } from "mongoose"; import { FilterPipe } from "src/common/pipes/filter.pipe"; import { UTCTimeInterceptor } from "src/common/interceptors/utc-time.interceptor"; import { DataFile } from "src/common/schemas/datafile.schema"; @@ -405,7 +405,9 @@ export class DatasetsController { | PartialUpdateRawDatasetObsoleteDto | PartialUpdateDerivedDatasetObsoleteDto, ): CreateDatasetDto | UpdateDatasetDto | PartialUpdateDatasetDto { - const propertiesModifier: Record = {}; + const propertiesModifier: Record = { + version: "v3", + }; if ( inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || @@ -489,8 +491,9 @@ export class DatasetsController { } } } + const outputDataset: OutputDatasetObsoleteDto = { - ...(inputDataset as OutputDatasetObsoleteDto), + ...(inputDataset as DatasetDocument).toObject(), ...propertiesModifier, }; @@ -537,17 +540,17 @@ export class DatasetsController { | CreateDerivedDatasetObsoleteDto, ): Promise { // validate dataset - await this.validateDatasetObsolete( + const validatedDatasetObsoleteDto = (await this.validateDatasetObsolete( createDatasetObsoleteDto, createDatasetObsoleteDto.type === "raw" ? CreateRawDatasetObsoleteDto : CreateDerivedDatasetObsoleteDto, - ); + )) as CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto; const obsoleteDatasetDto = await this.checkPermissionsForObsoleteDatasetCreate( request, - createDatasetObsoleteDto, + validatedDatasetObsoleteDto, ); try { @@ -598,11 +601,18 @@ export class DatasetsController { }, }; + // first we convert input object to the correct class + const outputDatasetDto = plainToInstance(dto, inputDatasetDto); + if ( - inputDatasetDto instanceof + outputDatasetDto instanceof (CreateRawDatasetObsoleteDto || CreateDerivedDatasetObsoleteDto) ) { - if (!(inputDatasetDto.type in DatasetType)) { + if ( + !(Object.values(DatasetType) as string[]).includes( + outputDatasetDto.type, + ) + ) { throw new HttpException( { status: HttpStatus.BAD_REQUEST, @@ -613,7 +623,6 @@ export class DatasetsController { } } - const outputDatasetDto = plainToInstance(dto, inputDatasetDto); const errors = await validate(outputDatasetDto, validateOptions); if (errors.length > 0) { diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 58fdcd1e4..9b3d7f7e2 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -449,13 +449,13 @@ export class DatasetClass extends OwnableClass { dataFormat?: string; @ApiProperty({ - type: String, + type: [String], required: false, description: "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) - @Prop({ type: String, ref: "Proposal", required: false }) - proposalIds?: string; + @Prop({ type: [String], ref: "Proposal", required: false }) + proposalIds?: string[]; @ApiProperty({ type: [String], diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 308eb32e9..97e21d50b 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -45,8 +45,8 @@ import { PartialUpdateDatasetDto } from "src/datasets/dto/update-dataset.dto"; import { filterDescription, filterExample } from "src/common/utils"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; -import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; +import { CreateRawDatasetObsoleteDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetObsoleteDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; import { logger } from "@user-office-software/duo-logger"; @ApiBearerAuth() @@ -103,7 +103,10 @@ export class OrigDatablocksController { // } async generateOrigDatablockInstanceInstanceForPermissions( - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto | DatasetClass, + dataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | DatasetClass, ): Promise { const origDatablockInstance = new OrigDatablock(); origDatablockInstance.datasetId = dataset.pid || ""; diff --git a/src/published-data/published-data.controller.ts b/src/published-data/published-data.controller.ts index 3d8199c7d..0786e9a53 100644 --- a/src/published-data/published-data.controller.ts +++ b/src/published-data/published-data.controller.ts @@ -166,13 +166,17 @@ export class PublishedDataController { }) async formPopulate(@Query("pid") pid: string) { const formData: IFormPopulateData = {}; - const dataset = await this.datasetsService.findOne({ where: { pid } }); + const dataset = (await this.datasetsService.findOne({ + where: { pid }, + })) as unknown as DatasetClass; let proposalId; if (dataset) { formData.resourceType = dataset.type; formData.description = dataset.description; - proposalId = (dataset as unknown as DatasetClass).proposalId; + if ("proposalIds" in dataset) { + proposalId = dataset.proposalIds![0]; + } } let proposal; diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index 56a8b7717..63e4b21c5 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -83,7 +83,6 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); it("0010: adds dataset 1 as Admin Ingestor", async () => { - console.log(JSON.stringify(dataset1)); return request(appUrl) .post("/api/v3/Datasets") .send(dataset1) @@ -92,8 +91,6 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - console.log("Results"); - console.log(res.body); res.body.should.have.property("ownerGroup").and.equal("group4"); res.body.should.have.property("type").and.equal("raw"); res.body.should.have.property("isPublished").and.equal(true); @@ -103,23 +100,23 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - // it("0020: adds dataset 2 as Admin Ingestor", async () => { - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(dataset2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("ownerGroup").and.equal("group1"); - // res.body.should.have.property("type").and.equal("raw"); - // res.body.should.have.property("isPublished").and.equal(false); - // res.body.should.have.property("pid").and.be.string; - // datasetPid2 = res.body["pid"]; - // encodedDatasetPid2 = encodeURIComponent(datasetPid2); - // }); - // }); + it("0020: adds dataset 2 as Admin Ingestor", async () => { + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerGroup").and.equal("group1"); + res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); + res.body.should.have.property("pid").and.be.string; + datasetPid2 = res.body["pid"]; + encodedDatasetPid2 = encodeURIComponent(datasetPid2); + }); + }); // it("0030: adds dataset 3 as Admin Ingestor", async () => { // return request(appUrl) From bc4532ca162b64347a64e33244560761761e8371 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 17 Sep 2024 14:47:28 +0200 Subject: [PATCH 208/258] fixed tests in Datasets Simple --- src/datasets/datasets.controller.ts | 7 +- test/DatasetAuthorization.js | 2835 +++++++++++++-------------- 2 files changed, 1420 insertions(+), 1422 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 9e1430701..2b4b3aec1 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -431,10 +431,9 @@ export class DatasetsController { } } else { if ("investigator" in inputObsoleteDataset) { - propertiesModifier.principalInvestigator = [ - (inputObsoleteDataset as CreateDerivedDatasetObsoleteDto) - .investigator, - ]; + propertiesModifier.principalInvestigator = ( + inputObsoleteDataset as CreateDerivedDatasetObsoleteDto + ).investigator; } } diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index 63e4b21c5..3aeb7f749 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -118,1422 +118,1421 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - // it("0030: adds dataset 3 as Admin Ingestor", async () => { - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(dataset3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("ownerGroup").and.equal("group2"); - // res.body.should.have.property("type").and.equal("raw"); - // res.body.should.have.property("isPublished").and.equal(false); - // res.body.should.have.property("pid").and.be.string; - // datasetPid3 = res.body["pid"]; - // encodedDatasetPid3 = encodeURIComponent(datasetPid3); - // }); - // }); - - // it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) - // .send(TestData.OrigDataBlockCorrect1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have - // .property("size") - // .and.equal(TestData.OrigDataBlockCorrect1.size); - // res.body.should.have.property("id").and.be.string; - // }); - // }); - - // it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { - // const randomArchiveId = Math.random().toString(36).slice(2); - - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) - // .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have - // .property("size") - // .and.equal(TestData.DataBlockCorrect.size); - // res.body.should.have.property("id").and.be.string; - // }); - // }); - - // it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) - // .send(TestData.AttachmentCorrect) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0070: list of public datasets, aka as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0080: access public dataset as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0090: access private dataset as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0100: list of datasets for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0110: datasets counts for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(3); - // }); - // }); - - // it("0120: access dataset 1 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0130: full query for datasets for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0140: access dataset 2 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0150: access dataset 3 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0160: list of datasets for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // res.body[1]["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0170: datasets count for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(2); - // }); - // }); - - // it("0180: access dataset 1 as User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0190: access dataset 2 as User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0210: full query for datasets for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0220: list of datasets for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // res.body[1]["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0230: datasets count for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(2); - // }); - // }); - - // it("0240: access dataset 1 as User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0260: access dataset 3 as User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0270: full query for datasets for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0280: list of datasets for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0290: datasets count for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(3); - // }); - // }); - - // it("0300: access dataset 1 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0310: access dataset 2 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0320: access dataset 3 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0330: full query for datasets for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // }); - // }); - - // it("0340: update dataset 2 to be published as Admin Ingestor", async () => { - // return request(appUrl) - // .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) - // .send({ isPublished: true }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulPatchStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0350: full query for datasets for User 2", async () => { - // const fields = { - // isPublished: true, - // }; - - // return request(appUrl) - // .get( - // `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( - // JSON.stringify(fields), - // )}`, - // ) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // }); - // }); - - // it("0360: full facet for datasets for User 2", async () => { - // const fields = { - // isPublished: true, - // }; - // return request(appUrl) - // .get( - // `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( - // JSON.stringify(fields), - // )}`, - // ) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body[0].all[0].totalSets.should.be.equal(2); - // }); - // }); - - // it("0370: access dataset 1 origdatablocks as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0380: access dataset 1 datablocks as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0390: access dataset 1 attachments as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0400: access dataset 1 thumbnail as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode); - // }); - - // it("0410: should delete dataset 1 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0420: should delete dataset 2 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0430: should delete dataset 3 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0500: add a new raw dataset as Admin", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0502: add a new raw dataset with specified pid as Admin", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "admin", - // }; - // console.log("0502: pid : " + datasetWithPid["pid"]); - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: uuidv4(), - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0510: add a new raw dataset with different owner group as Admin", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); + it("0030: adds dataset 3 as Admin Ingestor", async () => { + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerGroup").and.equal("group2"); + res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); + res.body.should.have.property("pid").and.be.string; + datasetPid3 = res.body["pid"]; + encodedDatasetPid3 = encodeURIComponent(datasetPid3); + }); + }); + + it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) + .send(TestData.OrigDataBlockCorrect1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have + .property("size") + .and.equal(TestData.OrigDataBlockCorrect1.size); + res.body.should.have.property("id").and.be.string; + }); + }); + + it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { + const randomArchiveId = Math.random().toString(36).slice(2); + + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) + .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have + .property("size") + .and.equal(TestData.DataBlockCorrect.size); + res.body.should.have.property("id").and.be.string; + }); + }); + + it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) + .send(TestData.AttachmentCorrect) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/); + }); + + it("0070: list of public datasets, aka as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0080: access public dataset as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0090: access private dataset as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0100: list of datasets for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0110: datasets counts for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(3); + }); + }); + + it("0120: access dataset 1 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0130: full query for datasets for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0140: access dataset 2 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0150: access dataset 3 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0160: list of datasets for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + res.body[1]["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0170: datasets count for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(2); + }); + }); + + it("0180: access dataset 1 as User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0190: access dataset 2 as User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0210: full query for datasets for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0220: list of datasets for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + res.body[1]["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0230: datasets count for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(2); + }); + }); + + it("0240: access dataset 1 as User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0260: access dataset 3 as User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0270: full query for datasets for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0280: list of datasets for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0290: datasets count for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(3); + }); + }); + + it("0300: access dataset 1 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0310: access dataset 2 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0320: access dataset 3 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0330: full query for datasets for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("0340: update dataset 2 to be published as Admin Ingestor", async () => { + return request(appUrl) + .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) + .send({ isPublished: true }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0350: full query for datasets for User 2", async () => { + const fields = { + isPublished: true, + }; + + return request(appUrl) + .get( + `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( + JSON.stringify(fields), + )}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("0360: full facet for datasets for User 2", async () => { + const fields = { + isPublished: true, + }; + return request(appUrl) + .get( + `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( + JSON.stringify(fields), + )}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body[0].all[0].totalSets.should.be.equal(2); + }); + }); + + it("0370: access dataset 1 origdatablocks as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0380: access dataset 1 datablocks as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0390: access dataset 1 attachments as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0400: access dataset 1 thumbnail as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode); + }); + + it("0410: should delete dataset 1 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0420: should delete dataset 2 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0430: should delete dataset 3 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0500: add a new raw dataset as Admin", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0502: add a new raw dataset with specified pid as Admin", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: uuidv4(), + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0510: add a new raw dataset with different owner group as Admin", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); }); From 5f84530aedff67270a60ae71232448d06c05ea8b Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 17 Sep 2024 17:35:20 +0200 Subject: [PATCH 209/258] making progress with tests --- src/datasets/datasets.controller.ts | 31 +++++++++++++++++------------ test/DerivedDatasetDatablock.js | 2 +- test/OrigDatablockForRawDataset.js | 3 ++- test/TestData.js | 4 +++- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 2b4b3aec1..741c41e79 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -556,6 +556,7 @@ export class DatasetsController { const datasetDto = this.convertObsoleteToCurrentSchema( obsoleteDatasetDto, ) as CreateDatasetDto; + console.log(datasetDto); const createdDataset = await this.datasetsService.create(datasetDto); const outputObsoleteDatasetDto = @@ -1063,30 +1064,34 @@ export class DatasetsController { ) as Record, ) as IFilters; - const dataset = (await this.datasetsService.findOne( - mergedFilters, - )) as OutputDatasetObsoleteDto; + const databaseDataset = await this.datasetsService.findOne(mergedFilters); - if (dataset) { + const outputDataset = + await this.convertCurrentToObsoleteSchema(databaseDataset); + + if (outputDataset) { const includeFilters = mergedFilters.include ?? []; await Promise.all( includeFilters.map(async ({ relation }) => { switch (relation) { case "attachments": { - dataset.attachments = await this.attachmentsService.findAll({ - datasetId: dataset.pid, - }); + outputDataset.attachments = await this.attachmentsService.findAll( + { + datasetId: outputDataset.pid, + }, + ); break; } case "origdatablocks": { - dataset.origdatablocks = await this.origDatablocksService.findAll( - { where: { datasetId: dataset.pid } }, - ); + outputDataset.origdatablocks = + await this.origDatablocksService.findAll({ + where: { datasetId: outputDataset.pid }, + }); break; } case "datablocks": { - dataset.datablocks = await this.datablocksService.findAll({ - datasetId: dataset.pid, + outputDataset.datablocks = await this.datablocksService.findAll({ + datasetId: outputDataset.pid, }); break; } @@ -1094,7 +1099,7 @@ export class DatasetsController { }), ); } - return dataset; + return outputDataset; } // GET /datasets/count diff --git a/test/DerivedDatasetDatablock.js b/test/DerivedDatasetDatablock.js index 8ef6ff8c7..6c223246c 100644 --- a/test/DerivedDatasetDatablock.js +++ b/test/DerivedDatasetDatablock.js @@ -13,7 +13,7 @@ describe("0750: DerivedDatasetDatablock: Test Datablocks and their relation to d before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index 057134d35..859b49333 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -23,7 +23,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati db.collection("Dataset").deleteMany({}); db.collection("OrigDatablock").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -304,6 +304,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { + console.log(res.body); res.body["pid"].should.be.equal(decodeURIComponent(datasetPid1)); res.body.origdatablocks.should.be .instanceof(Array) diff --git a/test/TestData.js b/test/TestData.js index 538f657bf..bee14fe4c 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -119,6 +119,7 @@ const TestData = { sourceFolder: faker.system.directoryPath(), owner: faker.internet.userName(), contactEmail: faker.internet.email(), + datasetName: faker.string.sample(), }, RawCorrect: { @@ -384,13 +385,14 @@ const TestData = { DerivedCorrectMin: { investigator: faker.internet.email(), - inputDatasets: [faker.system.filePath()], + inputDatasets: [faker.string.uuid()], usedSoftware: [faker.internet.url()], owner: faker.internet.userName(), contactEmail: faker.internet.email(), sourceFolder: faker.system.directoryPath(), creationTime: faker.date.past(), ownerGroup: faker.string.alphanumeric(6), + datasetName: faker.string.sample(), type: "derived", }, From 6bdbb4311759187086249afdd9c2402dec602336 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 4 Sep 2024 17:28:26 +0200 Subject: [PATCH 210/258] refactor naming of current dataset schema and dto. Added new unified dataset schema and dto --- src/datasets/datasets.controller.ts | 19 +- src/datasets/datasets.service.ts | 36 ++- .../dto/create-dataset-obsolete.dto.ts | 34 ++ src/datasets/dto/create-dataset.dto.ts | 9 - .../dto/output-dataset-obsolete.dto.ts | 237 ++++++++++++++ src/datasets/dto/output-dataset.dto.ts | 41 +++ .../dto/update-dataset-obsolete.dto.ts | 298 ++++++++++++++++++ src/datasets/dto/update-dataset.dto.ts | 141 ++++++++- .../dto/update-derived-dataset.dto.ts | 4 +- src/datasets/dto/update-raw-dataset.dto.ts | 4 +- src/datasets/schemas/dataset.schema.ts | 149 ++++----- 11 files changed, 852 insertions(+), 120 deletions(-) create mode 100644 src/datasets/dto/create-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/output-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/output-dataset.dto.ts create mode 100644 src/datasets/dto/update-dataset-obsolete.dto.ts diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 0d7706ee1..42233e22a 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -36,7 +36,7 @@ import { } from "@nestjs/swagger"; import { Request } from "express"; import { DatasetsService } from "./datasets.service"; -import { PartialUpdateDatasetDto } from "./dto/update-dataset.dto"; +import { PartialUpdateDatasetObsoleteDto } from "./dto/update-dataset-obsolete.dto"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; import { CreateRawDatasetDto } from "./dto/create-raw-dataset.dto"; import { CreateDerivedDatasetDto } from "./dto/create-derived-dataset.dto"; @@ -98,6 +98,7 @@ import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { LogbooksService } from "src/logbooks/logbooks.service"; import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; +import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; @ApiBearerAuth() @ApiExtraModels( @@ -597,7 +598,7 @@ export class DatasetsController { @Req() request: Request, @Headers() headers: Record, @Query(new FilterPipe()) queryFilter: { filter?: string }, - ): Promise { + ): Promise { const mergedFilters = replaceLikeOperator( this.updateMergedFiltersForList( request, @@ -606,7 +607,9 @@ export class DatasetsController { ) as IFilters; // this should be implemented at database level - const datasets = await this.datasetsService.findAll(mergedFilters); + const datasets = (await this.datasetsService.findAll( + mergedFilters, + )) as OutputDatasetObsoleteDto[]; if (datasets && datasets.length > 0) { const includeFilters = mergedFilters.include ?? []; await Promise.all( @@ -917,7 +920,7 @@ export class DatasetsController { @Req() request: Request, @Headers() headers: Record, @Query(new FilterPipe()) queryFilter: { filter?: string }, - ): Promise { + ): Promise { const mergedFilters = replaceLikeOperator( this.updateMergedFiltersForList( request, @@ -927,7 +930,7 @@ export class DatasetsController { const dataset = (await this.datasetsService.findOne( mergedFilters, - )) as DatasetClass; + )) as OutputDatasetObsoleteDto; if (dataset) { const includeFilters = mergedFilters.include ?? []; @@ -1585,7 +1588,7 @@ export class DatasetsController { const datablock = await this.origDatablocksService.create(createOrigDatablock); - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { size: dataset.size + datablock.size, numberOfFiles: dataset.numberOfFiles + datablock.dataFileList.length, }; @@ -1804,7 +1807,7 @@ export class DatasetsController { where: { datasetId: pid }, }); // update dataset size and files number - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { size: odb.reduce((a, b) => a + b.size, 0), numberOfFiles: odb.reduce((a, b) => a + b.dataFileList.length, 0), }; @@ -2034,7 +2037,7 @@ export class DatasetsController { datasetId: pid, }); // update dataset size and files number - const updateDatasetDto: PartialUpdateDatasetDto = { + const updateDatasetDto: PartialUpdateDatasetObsoleteDto = { packedSize: remainingDatablocks.reduce((a, b) => a + b.packedSize, 0), numberOfFilesArchived: remainingDatablocks.reduce( (a, b) => a + b.dataFileList.length, diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index c78974c1e..680222e8e 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -24,11 +24,11 @@ import { ElasticSearchService } from "src/elastic-search/elastic-search.service" import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; -import { CreateDatasetDto } from "./dto/create-dataset.dto"; +import { CreateDatasetObsoleteDto } from "./dto/create-dataset-obsolete.dto"; import { - PartialUpdateDatasetDto, - UpdateDatasetDto, -} from "./dto/update-dataset.dto"; + PartialUpdateDatasetObsoleteDto, + UpdateDatasetObsoleteDto, +} from "./dto/update-dataset-obsolete.dto"; import { PartialUpdateDerivedDatasetDto, UpdateDerivedDatasetDto, @@ -58,7 +58,9 @@ export class DatasetsService { } } - async create(createDatasetDto: CreateDatasetDto): Promise { + async create( + createDatasetDto: CreateDatasetObsoleteDto, + ): Promise { const username = (this.request.user as JWTUser).username; const createdDataset = new this.datasetModel( // insert created and updated fields @@ -206,7 +208,7 @@ export class DatasetsService { async findByIdAndReplace( id: string, updateDatasetDto: - | UpdateDatasetDto + | UpdateDatasetObsoleteDto | UpdateRawDatasetDto | UpdateDerivedDatasetDto, ): Promise { @@ -252,7 +254,7 @@ export class DatasetsService { async findByIdAndUpdate( id: string, updateDatasetDto: - | PartialUpdateDatasetDto + | PartialUpdateDatasetObsoleteDto | PartialUpdateRawDatasetDto | PartialUpdateDerivedDatasetDto | UpdateQuery, @@ -434,20 +436,28 @@ export class DatasetsService { async updateHistory( req: Request, dataset: DatasetClass, - data: UpdateDatasetDto, + data: UpdateDatasetObsoleteDto, ) { if (req.body.history) { delete req.body.history; } if (!req.body.size && !req.body.packedSize) { - const updatedFields: Omit = - data; + const updatedFields: Omit< + UpdateDatasetObsoleteDto, + "updatedAt" | "updatedBy" + > = data; const historyItem: Record = {}; Object.keys(updatedFields).forEach((updatedField) => { - historyItem[updatedField as keyof UpdateDatasetDto] = { - currentValue: data[updatedField as keyof UpdateDatasetDto], - previousValue: dataset[updatedField as keyof UpdateDatasetDto], + historyItem[updatedField as keyof UpdateDatasetObsoleteDto] = { + currentValue: data[updatedField as keyof UpdateDatasetObsoleteDto], + previousValue: + dataset[ + updatedField as keyof Omit< + UpdateDatasetObsoleteDto, + "attachments" | "origdatablocks" | "datablocks" + > + ], }; }); dataset.history = dataset.history ?? []; diff --git a/src/datasets/dto/create-dataset-obsolete.dto.ts b/src/datasets/dto/create-dataset-obsolete.dto.ts new file mode 100644 index 000000000..a75fe5dfe --- /dev/null +++ b/src/datasets/dto/create-dataset-obsolete.dto.ts @@ -0,0 +1,34 @@ +import { IsEnum, IsOptional, IsString } from "class-validator"; +import { ApiProperty } from "@nestjs/swagger"; +import { DatasetType } from "../dataset-type.enum"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; + +export class CreateDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsOptional() + @IsString() + pid?: string; + + @ApiProperty({ + type: String, + required: true, + enum: [DatasetType.Raw, DatasetType.Derived], + description: + "Characterize type of dataset, either 'raw' or 'derived'. Autofilled when choosing the proper inherited models.", + }) + @IsEnum(DatasetType) + readonly type: string; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; +} diff --git a/src/datasets/dto/create-dataset.dto.ts b/src/datasets/dto/create-dataset.dto.ts index c9b5b7ad5..8ee18d733 100644 --- a/src/datasets/dto/create-dataset.dto.ts +++ b/src/datasets/dto/create-dataset.dto.ts @@ -22,13 +22,4 @@ export class CreateDatasetDto extends UpdateDatasetDto { }) @IsEnum(DatasetType) readonly type: string; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; } diff --git a/src/datasets/dto/output-dataset-obsolete.dto.ts b/src/datasets/dto/output-dataset-obsolete.dto.ts new file mode 100644 index 000000000..dced6bc31 --- /dev/null +++ b/src/datasets/dto/output-dataset-obsolete.dto.ts @@ -0,0 +1,237 @@ +import { + IsArray, + IsDateString, + IsEnum, + IsObject, + IsOptional, + IsString, +} from "class-validator"; +import { ApiProperty, getSchemaPath } from "@nestjs/swagger"; +import { DatasetType } from "../dataset-type.enum"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; +import { Attachment } from "src/attachments/schemas/attachment.schema"; +import { Type } from "class-transformer"; +import { OrigDatablock } from "src/origdatablocks/schemas/origdatablock.schema"; +import { Datablock } from "src/datablocks/schemas/datablock.schema"; + +export class OutputDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsString() + readonly pid: string; + + @ApiProperty({ + type: String, + required: true, + enum: [DatasetType.Raw, DatasetType.Derived], + description: + "Characterize type of dataset, either 'raw' or 'derived'. Autofilled when choosing the proper inherited models.", + }) + @IsEnum(DatasetType) + readonly type: string; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + @IsOptional() + readonly principalInvestigator?: string; + + @ApiProperty({ + type: Date, + required: false, + description: + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly startTime?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly endTime?: Date; + + @ApiProperty({ + type: String, + required: true, + description: + "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + @IsOptional() + readonly creationLocation?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", + }) + @IsOptional() + @IsString() + readonly dataFormat?: string; + + @ApiProperty({ + type: String, + required: false, + description: "The ID of the proposal to which the dataset belongs.", + }) + @IsOptional() + @IsString() + readonly proposalId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the sample used when collecting the data.", + }) + @IsOptional() + @IsString() + readonly sampleId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the instrument where the data was created.", + }) + @IsOptional() + @IsString() + readonly instrumentId?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", + }) + @IsString() + @IsOptional() + readonly investigator?: string; + + @ApiProperty({ + type: [String], + required: true, + description: + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", + }) + @IsString({ + each: true, + }) + @IsOptional() + readonly inputDatasets?: string[]; + + @ApiProperty({ + type: [String], + required: true, + description: + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", + }) + @IsString({ + each: true, + }) + @IsOptional() + readonly usedSoftware?: string[]; + + @ApiProperty({ + type: Object, + required: false, + description: + "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", + }) + @IsOptional() + @IsObject() + readonly jobParameters?: Record; + + @ApiProperty({ + type: String, + required: false, + description: + "The output job logfile. Keep the size of this log data well below 15 MB.", + }) + @IsOptional() + @IsString() + readonly jobLogData?: string; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(Attachment) }, + required: false, + description: + "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", + }) + @IsOptional() + @IsArray() + @Type(() => Attachment) + attachments?: Attachment[]; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(OrigDatablock) }, + required: false, + description: + "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", + }) + origdatablocks?: OrigDatablock[]; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(Datablock) }, + required: false, + description: + "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", + }) + datablocks?: Datablock[]; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who created this record. This property is added and maintained by the system.", + }) + createdBy: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who updated this record last. This property is added and maintained by the system.", + }) + updatedBy: string; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was created. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + createdAt: Date; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was updated last. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + updatedAt: Date; +} diff --git a/src/datasets/dto/output-dataset.dto.ts b/src/datasets/dto/output-dataset.dto.ts new file mode 100644 index 000000000..8809e3756 --- /dev/null +++ b/src/datasets/dto/output-dataset.dto.ts @@ -0,0 +1,41 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { CreateDatasetDto } from "./create-dataset.dto"; +import { IsString } from "class-validator"; + +export class OutputDatasetDto extends CreateDatasetDto { + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who created this record. This property is added and maintained by the system.", + }) + @IsString() + createdBy: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Indicate the user who updated this record last. This property is added and maintained by the system.", + }) + @IsString() + updatedBy: string; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was created. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + @IsString() + createdAt: Date; + + @ApiProperty({ + type: Date, + required: true, + description: + "Date and time when this record was updated last. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", + }) + @IsString() + updatedAt: Date; +} diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts new file mode 100644 index 000000000..f2be1c2d2 --- /dev/null +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -0,0 +1,298 @@ +import { + ApiProperty, + ApiTags, + getSchemaPath, + PartialType, +} from "@nestjs/swagger"; +import { OwnableDto } from "../../common/dto/ownable.dto"; +import { + IsArray, + IsBoolean, + IsDateString, + IsEmail, + IsFQDN, + IsInt, + IsNumber, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from "class-validator"; +import { TechniqueClass } from "../schemas/technique.schema"; +import { Type } from "class-transformer"; +import { CreateTechniqueDto } from "./create-technique.dto"; +import { RelationshipClass } from "../schemas/relationship.schema"; +import { CreateRelationshipDto } from "./create-relationship.dto"; +import { LifecycleClass } from "../schemas/lifecycle.schema"; +import { Attachment } from "../../attachments/schemas/attachment.schema"; +import { OrigDatablock } from "../../origdatablocks/schemas/origdatablock.schema"; +import { Datablock } from "../../datablocks/schemas/datablock.schema"; + +@ApiTags("datasets") +export class UpdateDatasetObsoleteDto extends OwnableDto { + @ApiProperty({ + type: String, + required: true, + description: + "Owner or custodian of the dataset, usually first name + last name. The string may contain a list of persons, which should then be separated by semicolons.", + }) + @IsString() + readonly owner: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Email of the owner or custodian of the dataset. The string may contain a list of emails, which should then be separated by semicolons.", + }) + @IsOptional() + @IsEmail() + readonly ownerEmail?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "ORCID of the owner or custodian. The string may contain a list of ORCIDs, which should then be separated by semicolons.", + }) + @IsOptional() + @IsString() + readonly orcidOfOwner?: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Email of the contact person for this dataset. The string may contain a list of emails, which should then be separated by semicolons.", + }) + @IsEmail() + readonly contactEmail: string; + + @ApiProperty({ + type: String, + required: true, + description: + "Absolute file path on file server containing the files of this dataset, e.g. /some/path/to/sourcefolder. In case of a single file dataset, e.g. HDF5 data, it contains the path up to, but excluding the filename. Trailing slashes are removed.", + }) + @IsString() + readonly sourceFolder: string; + + @ApiProperty({ + type: String, + required: false, + description: + "DNS host name of file server hosting sourceFolder, optionally including a protocol e.g. [protocol://]fileserver1.example.com", + }) + @IsOptional() + @IsFQDN() + readonly sourceFolderHost?: string; + + /* + * size and number of files fields should be managed by the system + */ + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total size of all source files contained in source folder on disk when unpacked.", + }) + @IsOptional() + @IsInt() + readonly size?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total size of all datablock package files created for this dataset.", + }) + @IsOptional() + @IsInt() + readonly packedSize?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: false, + description: + "Total number of files in all OrigDatablocks for this dataset.", + }) + @IsOptional() + @IsInt() + readonly numberOfFiles?: number = 0; + + @ApiProperty({ + type: Number, + default: 0, + required: true, + description: "Total number of files in all Datablocks for this dataset.", + }) + @IsOptional() + @IsInt() + readonly numberOfFilesArchived?: number; + + @ApiProperty({ + type: Date, + required: true, + description: + "Time when dataset became fully available on disk, i.e. all containing files have been written, or the dataset was created in SciCat.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsDateString() + readonly creationTime: Date; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines a level of trust, e.g. a measure of how much data was verified or used by other persons.", + }) + @IsOptional() + @IsString() + readonly validationStatus?: string; + + @ApiProperty({ + type: [String], + required: false, + description: + "Array of tags associated with the meaning or contents of this dataset. Values should ideally come from defined vocabularies, taxonomies, ontologies or knowledge graphs.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly keywords?: string[]; + + @ApiProperty({ + type: String, + required: false, + description: "Free text explanation of contents of dataset.", + }) + @IsOptional() + @IsString() + readonly description?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", + }) + @IsOptional() + @IsString() + readonly datasetName?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'", + }) + @IsOptional() + @IsString() + readonly classification?: string; + + @ApiProperty({ + type: String, + required: false, + description: "Name of the license under which the data can be used.", + }) + @IsOptional() + @IsString() + readonly license?: string; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: Boolean, + required: false, + default: false, + description: "Flag is true when data are made publicly available.", + }) + @IsOptional() + @IsBoolean() + readonly isPublished?: boolean; + + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(TechniqueClass) }, + required: false, + default: [], + description: "Stores the metadata information for techniques.", + }) + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => CreateTechniqueDto) + readonly techniques?: TechniqueClass[]; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: [String], + required: false, + default: [], + description: "List of users that the dataset has been shared with.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly sharedWith?: string[]; + + // it needs to be discussed if this fields is managed by the user or by the system + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(RelationshipClass) }, + required: false, + default: [], + description: "Stores the relationships with other datasets.", + }) + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => CreateRelationshipDto) + readonly relationships?: RelationshipClass[]; + + @ApiProperty({ + type: LifecycleClass, + required: false, + default: {}, + description: + "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", + }) + @IsOptional() + readonly datasetlifecycle: LifecycleClass; + + @ApiProperty({ + type: Object, + required: false, + default: {}, + description: "JSON object containing the scientific metadata.", + }) + @IsOptional() + @IsObject() + readonly scientificMetadata?: Record; + + @ApiProperty({ + type: String, + required: false, + description: "Comment the user has about a given dataset.", + }) + @IsOptional() + @IsString() + readonly comment?: string; + + @ApiProperty({ + type: Number, + required: false, + description: + "Data Quality Metrics is a number given by the user to rate the dataset.", + }) + @IsOptional() + @IsNumber() + readonly dataQualityMetrics?: number; +} + +export class PartialUpdateDatasetObsoleteDto extends PartialType( + UpdateDatasetObsoleteDto, +) {} diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index aab14a7e5..c4ea63c4b 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -24,9 +24,6 @@ import { CreateTechniqueDto } from "./create-technique.dto"; import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; -import { Attachment } from "../../attachments/schemas/attachment.schema"; -import { OrigDatablock } from "../../origdatablocks/schemas/origdatablock.schema"; -import { Datablock } from "../../datablocks/schemas/datablock.schema"; @ApiTags("datasets") export class UpdateDatasetDto extends OwnableDto { @@ -37,7 +34,8 @@ export class UpdateDatasetDto extends OwnableDto { "Owner or custodian of the dataset, usually first name + last name. The string may contain a list of persons, which should then be separated by semicolons.", }) @IsString() - readonly owner: string; + @IsOptional() + readonly owner?: string; @ApiProperty({ type: String, @@ -175,13 +173,12 @@ export class UpdateDatasetDto extends OwnableDto { @ApiProperty({ type: String, - required: false, + required: true, description: "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", }) - @IsOptional() @IsString() - readonly datasetName?: string; + readonly datasetName: string; @ApiProperty({ type: String, @@ -211,7 +208,7 @@ export class UpdateDatasetDto extends OwnableDto { }) @IsOptional() @IsBoolean() - readonly isPublished?: boolean; + readonly isPublished?: boolean = false; @ApiProperty({ type: "array", @@ -261,7 +258,7 @@ export class UpdateDatasetDto extends OwnableDto { "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", }) @IsOptional() - readonly datasetlifecycle: LifecycleClass; + readonly datasetlifecycle?: LifecycleClass; @ApiProperty({ type: Object, @@ -292,14 +289,134 @@ export class UpdateDatasetDto extends OwnableDto { @IsNumber() readonly dataQualityMetrics?: number; + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + readonly principalInvestigator: string; + + @ApiProperty({ + type: Date, + required: false, + description: + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) @IsOptional() - attachments?: Attachment[]; + @IsDateString() + readonly startTime?: Date; + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) @IsOptional() - origdatablocks?: OrigDatablock[]; + @IsDateString() + readonly endTime?: Date; + @ApiProperty({ + type: String, + required: false, + description: + "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + }) @IsOptional() - datablocks?: Datablock[]; + @IsString() + readonly creationLocation?: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", + }) + @IsOptional() + @IsString() + readonly dataFormat?: string; + + @ApiProperty({ + type: [String], + required: false, + description: + "ID of the proposal or proposals which the dataset belongs to.
This dataset might have been acquired under the listed proposals or is derived from datasets acquired from datasets belonging to the listed datasets.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly proposalId?: string[]; + + @ApiProperty({ + type: [String], + required: false, + description: + "ID of the sample or samples used when collecting the data included or used in this dataset.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly sampleId?: string[]; + + @ApiProperty({ + type: String, + required: false, + description: + "ID of the instrument or instruments where the data included or used in this datasets was collected on.", + }) + @IsOptional() + @IsString({ + each: false, + }) + readonly instrumentId?: string[]; + + @ApiProperty({ + type: [String], + required: true, + description: + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", + }) + @IsOptional() + @IsString({ + each: false, + }) + readonly inputDatasets?: string[]; + + @ApiProperty({ + type: [String], + required: false, + description: + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", + }) + @IsOptional() + @IsString({ + each: true, + }) + readonly usedSoftware?: string[]; + + @ApiProperty({ + type: Object, + required: false, + description: + "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", + }) + @IsOptional() + @IsObject() + readonly jobParameters?: Record; + + @ApiProperty({ + type: String, + required: false, + description: + "The output job logfile. Keep the size of this log data well below 15 MB.", + }) + @IsOptional() + @IsString() + readonly jobLogData?: string; } export class PartialUpdateDatasetDto extends PartialType(UpdateDatasetDto) {} diff --git a/src/datasets/dto/update-derived-dataset.dto.ts b/src/datasets/dto/update-derived-dataset.dto.ts index 5f4d83a1d..a654c5bca 100644 --- a/src/datasets/dto/update-derived-dataset.dto.ts +++ b/src/datasets/dto/update-derived-dataset.dto.ts @@ -1,8 +1,8 @@ -import { UpdateDatasetDto } from "./update-dataset.dto"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; import { ApiProperty, PartialType } from "@nestjs/swagger"; import { IsObject, IsOptional, IsString } from "class-validator"; -export class UpdateDerivedDatasetDto extends UpdateDatasetDto { +export class UpdateDerivedDatasetDto extends UpdateDatasetObsoleteDto { @ApiProperty({ type: String, required: true, diff --git a/src/datasets/dto/update-raw-dataset.dto.ts b/src/datasets/dto/update-raw-dataset.dto.ts index a03fa14ad..5926b854f 100644 --- a/src/datasets/dto/update-raw-dataset.dto.ts +++ b/src/datasets/dto/update-raw-dataset.dto.ts @@ -1,8 +1,8 @@ import { IsDateString, IsOptional, IsString } from "class-validator"; -import { UpdateDatasetDto } from "./update-dataset.dto"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; import { ApiProperty, PartialType } from "@nestjs/swagger"; -export class UpdateRawDatasetDto extends UpdateDatasetDto { +export class UpdateRawDatasetDto extends UpdateDatasetObsoleteDto { /* we need to discuss if the naming is adequate. */ @ApiProperty({ type: String, diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 74c29aaa7..a50055b98 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -244,28 +244,21 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, - required: false, + required: true, description: - "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid. Will be autofilled if missing using info from sourceFolder.", + "A name for the dataset, given by the creator to carry some semantic meaning. Useful for display purposes e.g. instead of displaying the pid.", }) @Prop({ type: String, - required: false, - default: function datasetName() { - const sourceFolder = (this as DatasetDocument).sourceFolder; - if (!sourceFolder) return ""; - const arr = sourceFolder.split("/"); - if (arr.length == 1) return arr[0]; - else return arr[arr.length - 2] + "/" + arr[arr.length - 1]; - }, + required: true, }) - datasetName?: string; + datasetName: string; @ApiProperty({ type: String, required: false, description: - "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'", + "ACIA information about AUthenticity,COnfidentiality,INtegrity and AVailability requirements of dataset. E.g. AV(ailabilty)=medium could trigger the creation of a two tape copies. Format 'AV=medium,CO=low'. Please check the following post for more info: https://en.wikipedia.org/wiki/Parkerian_Hexad", }) @Prop({ type: String, required: false }) classification?: string; @@ -280,11 +273,12 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, - required: false, - description: "Version of the API used in creation of the dataset.", + required: true, + description: + "Version of the API used when the dataset was created or last updated. API version is defined in code for each release. Managed by the system.", }) - @Prop({ type: String, required: false }) - version?: string; + @Prop({ type: String, required: true }) + version: string; @ApiProperty({ type: "array", @@ -298,12 +292,12 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: LifecycleClass, - required: false, + required: true, default: {}, description: "Describes the current status of the dataset during its lifetime with respect to the storage handling systems.", }) - @Prop({ type: LifecycleSchema, default: {}, required: false }) + @Prop({ type: LifecycleSchema, default: {}, required: true }) datasetlifecycle?: LifecycleClass; @ApiProperty({ @@ -311,7 +305,8 @@ export class DatasetClass extends OwnableClass { items: { $ref: getSchemaPath(TechniqueClass) }, required: false, default: [], - description: "Stores the metadata information for techniques.", + description: + "Array of techniques information, with technique name and pid.", }) @Prop({ type: [TechniqueSchema], required: false, default: [] }) techniques?: TechniqueClass[]; @@ -321,7 +316,8 @@ export class DatasetClass extends OwnableClass { items: { $ref: getSchemaPath(RelationshipClass) }, required: false, default: [], - description: "Stores the relationships with other datasets.", + description: + "Array of relationships with other datasets. It contains relationship type and destination dataset", }) @Prop({ type: [RelationshipSchema], required: false, default: [] }) relationships?: RelationshipClass[]; @@ -330,7 +326,8 @@ export class DatasetClass extends OwnableClass { type: [String], required: false, default: [], - description: "List of users that the dataset has been shared with.", + description: + "List of additional users that the dataset has been shared with.", }) @Prop({ type: [String], @@ -339,37 +336,37 @@ export class DatasetClass extends OwnableClass { }) sharedWith?: string[]; - @ApiProperty({ - type: "array", - items: { $ref: getSchemaPath(Attachment) }, - required: false, - description: - "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", - }) - @Prop({ type: [AttachmentSchema], default: [] }) - attachments?: Attachment[]; - - @ApiProperty({ - isArray: true, - type: OrigDatablock, - items: { $ref: getSchemaPath(OrigDatablock) }, - required: false, - description: - "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", - }) - @Prop({ type: [OrigDatablockSchema], default: [] }) - origdatablocks: OrigDatablock[]; - - @ApiProperty({ - isArray: true, - type: Datablock, - items: { $ref: getSchemaPath(Datablock) }, - required: false, - description: - "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", - }) - @Prop({ type: [DatablockSchema], default: [] }) - datablocks: Datablock[]; + // @ApiProperty({ + // type: "array", + // items: { $ref: getSchemaPath(Attachment) }, + // required: false, + // description: + // "Small, less than 16 MB attachments, envisaged for png/jpeg previews.", + // }) + // @Prop({ type: [AttachmentSchema], default: [] }) + // attachments?: Attachment[]; + + // @ApiProperty({ + // isArray: true, + // type: OrigDatablock, + // items: { $ref: getSchemaPath(OrigDatablock) }, + // required: false, + // description: + // "Containers that list all files and their attributes which make up a dataset. Usually filled at the time the dataset's metadata is created in the data catalog. Can be used by subsequent archiving processes to create the archived datasets.", + // }) + // @Prop({ type: [OrigDatablockSchema], default: [] }) + // origdatablocks: OrigDatablock[]; + + // @ApiProperty({ + // isArray: true, + // type: Datablock, + // items: { $ref: getSchemaPath(Datablock) }, + // required: false, + // description: + // "When archiving a dataset, all files contained in the dataset are listed here together with their checksum information. Several datablocks can be created if the file listing is too long for a single datablock. This partitioning decision is done by the archiving system to allow for chunks of datablocks with manageable sizes. E.g a datasets consisting of 10 TB of data could be split into 10 datablocks of about 1 TB each. The upper limit set by the data catalog system itself is given by the fact that documents must be smaller than 16 MB, which typically allows for datasets of about 100000 files.", + // }) + // @Prop({ type: [DatablockSchema], default: [] }) + // datablocks: Datablock[]; @ApiProperty({ type: Object, @@ -383,7 +380,8 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, required: false, - description: "Comment the user has about a given dataset.", + description: + "Short comment provided by the user about a given dataset. This is additional to the description field.", }) @Prop({ type: String, @@ -400,7 +398,7 @@ export class DatasetClass extends OwnableClass { type: Number, required: false, }) - dataQualityMetrics: number; + dataQualityMetrics?: number; /* * fields related to Raw Datasets @@ -436,7 +434,7 @@ export class DatasetClass extends OwnableClass { type: String, required: true, description: - "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + "Unique location identifier where data was acquired. Usually in the form /Site-name/facility-name/instrumentOrBeamline-name.", }) @Prop({ type: String, required: false, index: true }) creationLocation?: string; @@ -453,44 +451,47 @@ export class DatasetClass extends OwnableClass { @ApiProperty({ type: String, required: false, - description: "The ID of the proposal to which the dataset belongs.", + description: + "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) @Prop({ type: String, ref: "Proposal", required: false }) proposalId?: string; @ApiProperty({ - type: String, + type: [String], required: false, - description: "ID of the sample used when collecting the data.", + description: + "Single ID or array of IDS of the samples used when collecting the data.", }) - @Prop({ type: String, ref: "Sample", required: false }) - sampleId?: string; + @Prop({ type: [String], ref: "Sample", required: false }) + sampleId?: string[]; @ApiProperty({ - type: String, + type: [String], required: false, - description: "ID of the instrument where the data was created.", + description: + "Id of the instrument or array of IDS of the instruments where the data contained in this dataset was created/acquired.", }) - @Prop({ type: String, ref: "Instrument", required: false }) - instrumentId?: string; + @Prop({ type: [String], ref: "Instrument", required: false }) + instrumentId?: string[]; /* * Derived Dataset */ - @ApiProperty({ - type: String, - required: false, - description: - "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", - }) - @Prop({ type: String, required: false, index: true }) - investigator?: string; + // @ApiProperty({ + // type: String, + // required: false, + // description: + // "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", + // }) + // @Prop({ type: String, required: false, index: true }) + // investigator?: string; @ApiProperty({ type: [String], required: false, description: - "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs. This field is required if the dataset is a Derived dataset.", + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", }) @Prop({ type: [String], required: false }) inputDatasets?: string[]; @@ -499,7 +500,7 @@ export class DatasetClass extends OwnableClass { type: [String], required: false, description: - "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data. This field is required if the dataset is a Derived dataset.", + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", }) @Prop({ type: [String], required: false }) usedSoftware?: string[]; From 2fdc8bf1d89927dc4b8f7c7f42a24fc649e18311 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 5 Sep 2024 13:58:25 +0200 Subject: [PATCH 211/258] solved weird dependency in jobs --- src/jobs/jobs.controller.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/jobs/jobs.controller.ts b/src/jobs/jobs.controller.ts index 588f202f9..838fc724c 100644 --- a/src/jobs/jobs.controller.ts +++ b/src/jobs/jobs.controller.ts @@ -179,25 +179,26 @@ export class JobsController { // Indexing originDataBlock with pid and create set of files for each dataset const datasets = await this.datasetsService.findAll(filter); // Include origdatablocks - await Promise.all( + const aggregatedData = await Promise.all( datasets.map(async (dataset) => { - dataset.origdatablocks = await this.origDatablocksService.findAll( - { + return { + dataset: dataset, + origdatablocks: await this.origDatablocksService.findAll({ datasetId: dataset.pid, - }, - ); + }), + }; }), ); - const result: Record> = datasets.reduce( - (acc: Record>, dataset) => { + const result: Record> = aggregatedData.reduce( + (acc: Record>, data) => { // Using Set make searching more efficient - const files = dataset.origdatablocks.reduce((acc, block) => { + const files = data.origdatablocks.reduce((acc, block) => { block.dataFileList.forEach((file) => { acc.add(file.path); }); return acc; }, new Set()); - acc[dataset.pid] = files; + acc[data.dataset.pid] = files; return acc; }, {}, From ac468a1fd0e3f6e20d94e481c1b442aca2f88239 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 6 Sep 2024 16:57:59 +0200 Subject: [PATCH 212/258] still refactoring names, started working on tests --- src/datasets/datasets.controller.ts | 180 +- src/datasets/datasets.service.ts | 10 +- .../dto/create-derived-dataset.dto.ts | 27 - src/datasets/dto/create-raw-dataset.dto.ts | 27 - src/datasets/dto/update-dataset.dto.ts | 6 +- .../dto/update-derived-dataset.dto.ts | 60 - src/datasets/dto/update-raw-dataset.dto.ts | 100 - src/datasets/schemas/dataset.schema.ts | 6 +- .../origdatablocks.controller.ts | 4 +- test/DatasetAuthorization.js | 2879 +++++++++-------- 10 files changed, 1584 insertions(+), 1715 deletions(-) delete mode 100644 src/datasets/dto/create-derived-dataset.dto.ts delete mode 100644 src/datasets/dto/create-raw-dataset.dto.ts delete mode 100644 src/datasets/dto/update-derived-dataset.dto.ts delete mode 100644 src/datasets/dto/update-raw-dataset.dto.ts diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 42233e22a..89e6f7536 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -38,8 +38,8 @@ import { Request } from "express"; import { DatasetsService } from "./datasets.service"; import { PartialUpdateDatasetObsoleteDto } from "./dto/update-dataset-obsolete.dto"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; -import { CreateRawDatasetDto } from "./dto/create-raw-dataset.dto"; -import { CreateDerivedDatasetDto } from "./dto/create-derived-dataset.dto"; +import { CreateRawDatasetObsoleteDto } from "./dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetObsoleteDto } from "./dto/create-derived-dataset-obsolete.dto"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; @@ -74,13 +74,13 @@ import { validate, ValidationError, ValidatorOptions } from "class-validator"; import { HistoryInterceptor } from "src/common/interceptors/history.interceptor"; import { CreateDatasetOrigDatablockDto } from "src/origdatablocks/dto/create-dataset-origdatablock"; import { - PartialUpdateRawDatasetDto, - UpdateRawDatasetDto, -} from "./dto/update-raw-dataset.dto"; + PartialUpdateRawDatasetObsoleteDto, + UpdateRawDatasetObsoleteDto, +} from "./dto/update-raw-dataset-obsolete.dto"; import { - PartialUpdateDerivedDatasetDto, - UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset.dto"; + PartialUpdateDerivedDatasetObsoleteDto, + UpdateDerivedDatasetObsoleteDto, +} from "./dto/update-derived-dataset-obsolete.dto"; import { CreateDatasetDatablockDto } from "src/datablocks/dto/create-dataset-datablock"; import { filterDescription, @@ -99,12 +99,13 @@ import { LogbooksService } from "src/logbooks/logbooks.service"; import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; +import { CreateDatasetDto } from "./dto/create-dataset.dto"; @ApiBearerAuth() @ApiExtraModels( CreateAttachmentDto, - CreateDerivedDatasetDto, - CreateRawDatasetDto, + CreateDerivedDatasetObsoleteDto, + CreateRawDatasetObsoleteDto, HistoryClass, TechniqueClass, RelationshipClass, @@ -283,7 +284,7 @@ export class DatasetsController { return dataset; } - async checkPermissionsForDataset(request: Request, id: string) { + async checkPermissionsForDatasetObsolete(request: Request, id: string) { const dataset = await this.datasetsService.findOne({ where: { pid: id } }); const user: JWTUser = request.user as JWTUser; @@ -332,7 +333,10 @@ export class DatasetsController { } async generateDatasetInstanceForPermissions( - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto | DatasetClass, + dataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | DatasetClass, ): Promise { const datasetInstance = new DatasetClass(); datasetInstance._id = ""; @@ -345,9 +349,9 @@ export class DatasetsController { return datasetInstance; } - async checkPermissionsForDatasetCreate( + async checkPermissionsForObsoleteDatasetCreate( request: Request, - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto, + dataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, ) { const user: JWTUser = request.user as JWTUser; @@ -388,6 +392,69 @@ export class DatasetsController { return dataset; } + convertObsoleteToCurrentSchema( + inputDataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, + ): CreateDatasetDto { + const propertiesModifier: Record = {}; + if (inputDataset.type == "raw") { + if ("proposalId" in inputDataset) { + propertiesModifier.proposalIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).proposalId, + ]; + } + if ("sampleId" in inputDataset) { + propertiesModifier.sampleIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).sampleId, + ]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = [ + (inputDataset as CreateRawDatasetObsoleteDto).instrumentId, + ]; + } + } else { + if ("investigator" in inputDataset) { + propertiesModifier.principalInvestigator = [ + (inputDataset as CreateDerivedDatasetObsoleteDto).investigator, + ]; + } + } + + const outputDataset: CreateDatasetDto = { + ...(inputDataset as CreateDatasetDto), + ...propertiesModifier, + }; + + return outputDataset; + } + + convertCurrentToObsoleteSchema( + inputDataset: DatasetClass, + ): OutputDatasetObsoleteDto { + const propertiesModifier: Record = {}; + if ("proposalIds" in inputDataset) { + propertiesModifier.proposalIds = inputDataset.proposalIds![0]; + } + if ("sampleIds" in inputDataset) { + propertiesModifier.sampleIds = inputDataset.sampleIds![0]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; + } + if (inputDataset.type == "raw") { + if ("investigator" in inputDataset) { + propertiesModifier.investigator = inputDataset.principalInvestigator; + } + } + + const outputDataset: OutputDatasetObsoleteDto = { + ...(inputDataset as OutputDatasetObsoleteDto), + ...propertiesModifier, + }; + + return outputDataset; + } + // POST /datasets @UseGuards(PoliciesGuard) @CheckPolicies("datasets", (ability: AppAbility) => @@ -404,14 +471,14 @@ export class DatasetsController { description: "It creates a new dataset and returns it completed with systems fields.", }) - @ApiExtraModels(CreateRawDatasetDto, CreateDerivedDatasetDto) + @ApiExtraModels(CreateRawDatasetObsoleteDto, CreateDerivedDatasetObsoleteDto) @ApiBody({ description: "Input fields for the dataset to be created", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(CreateRawDatasetDto) }, - { $ref: getSchemaPath(CreateDerivedDatasetDto) }, + { $ref: getSchemaPath(CreateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(CreateDerivedDatasetObsoleteDto) }, ], }, }) @@ -422,25 +489,34 @@ export class DatasetsController { }) async create( @Req() request: Request, - @Body() createDatasetDto: CreateRawDatasetDto | CreateDerivedDatasetDto, - ): Promise { + @Body() + createDatasetObsoleteDto: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto, + ): Promise { // validate dataset - await this.validateDataset( - createDatasetDto, - createDatasetDto.type === "raw" - ? CreateRawDatasetDto - : CreateDerivedDatasetDto, + await this.validateDatasetObsolete( + createDatasetObsoleteDto, + createDatasetObsoleteDto.type === "raw" + ? CreateRawDatasetObsoleteDto + : CreateDerivedDatasetObsoleteDto, ); - const datasetDTO = await this.checkPermissionsForDatasetCreate( - request, - createDatasetDto, - ); + const obsoleteDatasetDto = + await this.checkPermissionsForObsoleteDatasetCreate( + request, + createDatasetObsoleteDto, + ); try { - const createdDataset = await this.datasetsService.create(datasetDTO); + const datasetDto = + this.convertObsoleteToCurrentSchema(obsoleteDatasetDto); + const createdDataset = await this.datasetsService.create(datasetDto); + + const outputObsoleteDatasetDto = + this.convertCurrentToObsoleteSchema(createdDataset); - return createdDataset; + return outputObsoleteDatasetDto; } catch (error) { if ((error as MongoError).code === 11000) { throw new ConflictException( @@ -452,21 +528,21 @@ export class DatasetsController { } } - async validateDataset( + async validateDatasetObsolete( inputDatasetDto: - | CreateRawDatasetDto - | CreateDerivedDatasetDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto, + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, dto: ClassConstructor< - | CreateRawDatasetDto - | CreateDerivedDatasetDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto >, ) { const validateOptions: ValidatorOptions = { @@ -481,7 +557,7 @@ export class DatasetsController { if ( inputDatasetDto instanceof - (CreateRawDatasetDto || CreateDerivedDatasetDto) + (CreateRawDatasetObsoleteDto || CreateDerivedDatasetObsoleteDto) ) { if (!(inputDatasetDto.type in DatasetType)) { throw new HttpException( @@ -526,14 +602,14 @@ export class DatasetsController { description: "It validates the dataset provided as input, and returns true if the information is a valid dataset", }) - @ApiExtraModels(CreateRawDatasetDto, CreateDerivedDatasetDto) + @ApiExtraModels(CreateRawDatasetObsoleteDto, CreateDerivedDatasetObsoleteDto) @ApiBody({ description: "Input fields for the dataset that needs to be validated", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(CreateRawDatasetDto) }, - { $ref: getSchemaPath(CreateDerivedDatasetDto) }, + { $ref: getSchemaPath(CreateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(CreateDerivedDatasetObsoleteDto) }, ], }, }) @@ -545,9 +621,15 @@ export class DatasetsController { }) async isValid( @Req() request: Request, - @Body() createDatasetDto: CreateRawDatasetDto | CreateDerivedDatasetDto, + @Body() + createDatasetObsoleteDto: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto, ): Promise<{ valid: boolean }> { - await this.checkPermissionsForDatasetCreate(request, createDatasetDto); + await this.checkPermissionsForObsoleteDatasetCreate( + request, + createDatasetObsoleteDto, + ); const dtoTestRawCorrect = plainToInstance( CreateRawDatasetDto, diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 680222e8e..60793750d 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -24,7 +24,7 @@ import { ElasticSearchService } from "src/elastic-search/elastic-search.service" import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; -import { CreateDatasetObsoleteDto } from "./dto/create-dataset-obsolete.dto"; +import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { PartialUpdateDatasetObsoleteDto, UpdateDatasetObsoleteDto, @@ -32,11 +32,11 @@ import { import { PartialUpdateDerivedDatasetDto, UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset.dto"; +} from "./dto/update-derived-dataset-obsolete.dto"; import { PartialUpdateRawDatasetDto, UpdateRawDatasetDto, -} from "./dto/update-raw-dataset.dto"; +} from "./dto/update-raw-dataset-obsolete.dto"; import { IDatasetFields } from "./interfaces/dataset-filters.interface"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; @@ -58,9 +58,7 @@ export class DatasetsService { } } - async create( - createDatasetDto: CreateDatasetObsoleteDto, - ): Promise { + async create(createDatasetDto: CreateDatasetDto): Promise { const username = (this.request.user as JWTUser).username; const createdDataset = new this.datasetModel( // insert created and updated fields diff --git a/src/datasets/dto/create-derived-dataset.dto.ts b/src/datasets/dto/create-derived-dataset.dto.ts deleted file mode 100644 index f95240c82..000000000 --- a/src/datasets/dto/create-derived-dataset.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UpdateDerivedDatasetDto } from "./update-derived-dataset.dto"; -import { ApiProperty } from "@nestjs/swagger"; -import { IsEnum, IsOptional, IsString } from "class-validator"; -import { DatasetType } from "../dataset-type.enum"; - -export class CreateDerivedDatasetDto extends UpdateDerivedDatasetDto { - @ApiProperty({ - type: String, - required: false, - description: "Persistent identifier of the dataset.", - }) - @IsOptional() - @IsString() - pid?: string; - - @IsEnum(DatasetType) - readonly type: string = DatasetType.Derived; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; -} diff --git a/src/datasets/dto/create-raw-dataset.dto.ts b/src/datasets/dto/create-raw-dataset.dto.ts deleted file mode 100644 index fafa70b78..000000000 --- a/src/datasets/dto/create-raw-dataset.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UpdateRawDatasetDto } from "./update-raw-dataset.dto"; -import { ApiProperty } from "@nestjs/swagger"; -import { IsEnum, IsOptional, IsString } from "class-validator"; -import { DatasetType } from "../dataset-type.enum"; - -export class CreateRawDatasetDto extends UpdateRawDatasetDto { - @ApiProperty({ - type: String, - required: false, - description: "Persistent identifier of the dataset.", - }) - @IsOptional() - @IsString() - pid?: string; - - @IsEnum(DatasetType) - readonly type: string = DatasetType.Raw; - - @ApiProperty({ - type: String, - required: false, - description: "Version of the API used in creation of the dataset.", - }) - @IsOptional() - @IsString() - readonly version?: string; -} diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index c4ea63c4b..ad928772f 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -348,7 +348,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: true, }) - readonly proposalId?: string[]; + readonly proposalIds?: string[]; @ApiProperty({ type: [String], @@ -360,7 +360,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: true, }) - readonly sampleId?: string[]; + readonly sampleIds?: string[]; @ApiProperty({ type: String, @@ -372,7 +372,7 @@ export class UpdateDatasetDto extends OwnableDto { @IsString({ each: false, }) - readonly instrumentId?: string[]; + readonly instrumentIds?: string[]; @ApiProperty({ type: [String], diff --git a/src/datasets/dto/update-derived-dataset.dto.ts b/src/datasets/dto/update-derived-dataset.dto.ts deleted file mode 100644 index a654c5bca..000000000 --- a/src/datasets/dto/update-derived-dataset.dto.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; -import { ApiProperty, PartialType } from "@nestjs/swagger"; -import { IsObject, IsOptional, IsString } from "class-validator"; - -export class UpdateDerivedDatasetDto extends UpdateDatasetObsoleteDto { - @ApiProperty({ - type: String, - required: true, - description: - "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", - }) - @IsString() - readonly investigator: string; - - @ApiProperty({ - type: [String], - required: true, - description: - "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", - }) - @IsString({ - each: true, - }) - readonly inputDatasets: string[]; - - @ApiProperty({ - type: [String], - required: true, - description: - "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", - }) - @IsString({ - each: true, - }) - readonly usedSoftware: string[]; - - @ApiProperty({ - type: Object, - required: false, - description: - "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", - }) - @IsOptional() - @IsObject() - readonly jobParameters?: Record; - - @ApiProperty({ - type: String, - required: false, - description: - "The output job logfile. Keep the size of this log data well below 15 MB.", - }) - @IsOptional() - @IsString() - readonly jobLogData?: string; -} - -export class PartialUpdateDerivedDatasetDto extends PartialType( - UpdateDerivedDatasetDto, -) {} diff --git a/src/datasets/dto/update-raw-dataset.dto.ts b/src/datasets/dto/update-raw-dataset.dto.ts deleted file mode 100644 index 5926b854f..000000000 --- a/src/datasets/dto/update-raw-dataset.dto.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { IsDateString, IsOptional, IsString } from "class-validator"; -import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; -import { ApiProperty, PartialType } from "@nestjs/swagger"; - -export class UpdateRawDatasetDto extends UpdateDatasetObsoleteDto { - /* we need to discuss if the naming is adequate. */ - @ApiProperty({ - type: String, - required: true, - description: - "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", - }) - @IsString() - readonly principalInvestigator: string; - - @ApiProperty({ - type: Date, - required: false, - description: - "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", - }) - @IsOptional() - @IsDateString() - readonly startTime?: Date; - - @ApiProperty({ - type: Date, - required: false, - description: - "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", - }) - @IsOptional() - @IsDateString() - readonly endTime?: Date; - - @ApiProperty({ - type: String, - required: true, - description: - "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", - }) - @IsString() - readonly creationLocation: string; - - @ApiProperty({ - type: String, - required: false, - description: - "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", - }) - @IsOptional() - @IsString() - readonly dataFormat?: string; - - @ApiProperty({ - type: String, - required: false, - description: "The ID of the proposal to which the dataset belongs.", - }) - @IsOptional() - @IsString() - readonly proposalId?: string; - - @ApiProperty({ - type: String, - required: false, - description: "ID of the sample used when collecting the data.", - }) - @IsOptional() - @IsString() - readonly sampleId?: string; - - @ApiProperty({ - type: String, - required: false, - description: "ID of the instrument where the data was created.", - }) - @IsOptional() - @IsString() - readonly instrumentId: string; - - @IsOptional() - investigator?: string; - - @IsOptional() - inputDatasets?: string[]; - - @IsOptional() - usedSoftware?: string[]; - - @IsOptional() - jobParameters?: Record; - - @IsOptional() - jobLogData?: string; -} - -export class PartialUpdateRawDatasetDto extends PartialType( - UpdateRawDatasetDto, -) {} diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index a50055b98..58fdcd1e4 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -455,7 +455,7 @@ export class DatasetClass extends OwnableClass { "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) @Prop({ type: String, ref: "Proposal", required: false }) - proposalId?: string; + proposalIds?: string; @ApiProperty({ type: [String], @@ -464,7 +464,7 @@ export class DatasetClass extends OwnableClass { "Single ID or array of IDS of the samples used when collecting the data.", }) @Prop({ type: [String], ref: "Sample", required: false }) - sampleId?: string[]; + sampleIds?: string[]; @ApiProperty({ type: [String], @@ -473,7 +473,7 @@ export class DatasetClass extends OwnableClass { "Id of the instrument or array of IDS of the instruments where the data contained in this dataset was created/acquired.", }) @Prop({ type: [String], ref: "Instrument", required: false }) - instrumentId?: string[]; + instrumentIds?: string[]; /* * Derived Dataset diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index f1a0f13be..308eb32e9 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -45,8 +45,8 @@ import { PartialUpdateDatasetDto } from "src/datasets/dto/update-dataset.dto"; import { filterDescription, filterExample } from "src/common/utils"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset.dto"; -import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset.dto"; +import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; import { logger } from "@user-office-software/duo-logger"; @ApiBearerAuth() diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index ab707200d..56a8b7717 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -45,7 +45,7 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -76,13 +76,14 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { password: TestData.Accounts["archiveManager"]["password"], }); }); - + afterEach((done) => { sandbox.restore(); done(); }); it("0010: adds dataset 1 as Admin Ingestor", async () => { + console.log(JSON.stringify(dataset1)); return request(appUrl) .post("/api/v3/Datasets") .send(dataset1) @@ -91,6 +92,8 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { + console.log("Results"); + console.log(res.body); res.body.should.have.property("ownerGroup").and.equal("group4"); res.body.should.have.property("type").and.equal("raw"); res.body.should.have.property("isPublished").and.equal(true); @@ -100,1440 +103,1440 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - it("0020: adds dataset 2 as Admin Ingestor", async () => { - return request(appUrl) - .post("/api/v3/Datasets") - .send(dataset2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("ownerGroup").and.equal("group1"); - res.body.should.have.property("type").and.equal("raw"); - res.body.should.have.property("isPublished").and.equal(false); - res.body.should.have.property("pid").and.be.string; - datasetPid2 = res.body["pid"]; - encodedDatasetPid2 = encodeURIComponent(datasetPid2); - }); - }); - - it("0030: adds dataset 3 as Admin Ingestor", async () => { - return request(appUrl) - .post("/api/v3/Datasets") - .send(dataset3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("ownerGroup").and.equal("group2"); - res.body.should.have.property("type").and.equal("raw"); - res.body.should.have.property("isPublished").and.equal(false); - res.body.should.have.property("pid").and.be.string; - datasetPid3 = res.body["pid"]; - encodedDatasetPid3 = encodeURIComponent(datasetPid3); - }); - }); - - it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) - .send(TestData.OrigDataBlockCorrect1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have - .property("size") - .and.equal(TestData.OrigDataBlockCorrect1.size); - res.body.should.have.property("id").and.be.string; - }); - }); - - it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { - const randomArchiveId = Math.random().toString(36).slice(2); - - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) - .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have - .property("size") - .and.equal(TestData.DataBlockCorrect.size); - res.body.should.have.property("id").and.be.string; - }); - }); - - it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { - return request(appUrl) - .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) - .send(TestData.AttachmentCorrect) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/); - }); - - it("0070: list of public datasets, aka as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0080: access public dataset as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0090: access private dataset as unauthenticated user", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0100: list of datasets for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0110: datasets counts for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(3); - }); - }); - - it("0120: access dataset 1 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0130: full query for datasets for Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0140: access dataset 2 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0150: access dataset 3 as Admin Ingestor", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0160: list of datasets for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - res.body[1]["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0170: datasets count for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(2); - }); - }); - - it("0180: access dataset 1 as User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0190: access dataset 2 as User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0210: full query for datasets for User 1", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0220: list of datasets for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - res.body[1]["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0230: datasets count for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(2); - }); - }); - - it("0240: access dataset 1 as User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.AccessForbiddenStatusCode); - }); - - it("0260: access dataset 3 as User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0270: full query for datasets for User 2", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - res.body[0]["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0280: list of datasets for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(3); - }); - }); - - it("0290: datasets count for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/count") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body["count"].should.be.equal(3); - }); - }); - - it("0300: access dataset 1 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid1); - }); - }); - - it("0310: access dataset 2 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid2); - }); - }); - - it("0320: access dataset 3 as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body["pid"].should.be.equal(datasetPid3); - }); - }); - - it("0330: full query for datasets for User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/fullquery") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - }); - }); - - it("0340: update dataset 2 to be published as Admin Ingestor", async () => { - return request(appUrl) - .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) - .send({ isPublished: true }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) - .expect("Content-Type", /json/); - }); - - it("0350: full query for datasets for User 2", async () => { - const fields = { - isPublished: true, - }; - - return request(appUrl) - .get( - `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( - JSON.stringify(fields), - )}`, - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(2); - }); - }); - - it("0360: full facet for datasets for User 2", async () => { - const fields = { - isPublished: true, - }; - return request(appUrl) - .get( - `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( - JSON.stringify(fields), - )}`, - ) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.SuccessfulGetStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body[0].all[0].totalSets.should.be.equal(2); - }); - }); - - it("0370: access dataset 1 origdatablocks as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0380: access dataset 1 datablocks as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0390: access dataset 1 attachments as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode) - .then((res) => { - res.body.should.be.an("array").to.have.lengthOf(1); - }); - }); - - it("0400: access dataset 1 thumbnail as User 3", async () => { - return request(appUrl) - .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect("Content-Type", /json/) - .expect(TestData.SuccessfulGetStatusCode); - }); - - it("0410: should delete dataset 1 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid1) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0420: should delete dataset 2 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid2) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0430: should delete dataset 3 as Archive Manager", async () => { - return request(appUrl) - .delete("/api/v3/datasets/" + encodedDatasetPid3) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); - }); - - it("0500: add a new raw dataset as Admin", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0502: add a new raw dataset with specified pid as Admin", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "admin", - }; - console.log("0502: pid : " + datasetWithPid["pid"]); - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: uuidv4(), - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "admin", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0510: add a new raw dataset with different owner group as Admin", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group2", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.CreationForbiddenStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser2}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group3", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { - const newDataset = { - ...TestData.RawCorrect, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.be.string; - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const newDataset = { - ...TestData.RawWrong_1, - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(newDataset) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.EntryCreatedStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - res.body.should.have.property("owner").and.be.string; - res.body.should.have.property("type").and.equal("raw"); - }); - }); - - it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const datasetWithPid = { - ...TestData.RawCorrect, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(datasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithPid = { - ...TestData.RawWrong_1, - pid: TestData.PidPrefix + "/" + uuidv4(), - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); - - it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - const invalidDatasetWithInvalidPid = { - ...TestData.RawWrong_1, - pid: "this-is-invalid-pid-1", - ownerGroup: "group1", - }; - - return request(appUrl) - .post("/api/v3/Datasets") - .send(invalidDatasetWithInvalidPid) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) - .expect(TestData.BadRequestStatusCode) - .expect("Content-Type", /json/) - .then((res) => { - res.body.should.not.have.property("pid"); - }); - }); + // it("0020: adds dataset 2 as Admin Ingestor", async () => { + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(dataset2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("ownerGroup").and.equal("group1"); + // res.body.should.have.property("type").and.equal("raw"); + // res.body.should.have.property("isPublished").and.equal(false); + // res.body.should.have.property("pid").and.be.string; + // datasetPid2 = res.body["pid"]; + // encodedDatasetPid2 = encodeURIComponent(datasetPid2); + // }); + // }); + + // it("0030: adds dataset 3 as Admin Ingestor", async () => { + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(dataset3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("ownerGroup").and.equal("group2"); + // res.body.should.have.property("type").and.equal("raw"); + // res.body.should.have.property("isPublished").and.equal(false); + // res.body.should.have.property("pid").and.be.string; + // datasetPid3 = res.body["pid"]; + // encodedDatasetPid3 = encodeURIComponent(datasetPid3); + // }); + // }); + + // it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) + // .send(TestData.OrigDataBlockCorrect1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have + // .property("size") + // .and.equal(TestData.OrigDataBlockCorrect1.size); + // res.body.should.have.property("id").and.be.string; + // }); + // }); + + // it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { + // const randomArchiveId = Math.random().toString(36).slice(2); + + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) + // .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have + // .property("size") + // .and.equal(TestData.DataBlockCorrect.size); + // res.body.should.have.property("id").and.be.string; + // }); + // }); + + // it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { + // return request(appUrl) + // .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) + // .send(TestData.AttachmentCorrect) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0070: list of public datasets, aka as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0080: access public dataset as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0090: access private dataset as unauthenticated user", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0100: list of datasets for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0110: datasets counts for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(3); + // }); + // }); + + // it("0120: access dataset 1 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0130: full query for datasets for Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0140: access dataset 2 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0150: access dataset 3 as Admin Ingestor", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0160: list of datasets for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // res.body[1]["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0170: datasets count for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(2); + // }); + // }); + + // it("0180: access dataset 1 as User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0190: access dataset 2 as User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0210: full query for datasets for User 1", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0220: list of datasets for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // res.body[1]["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0230: datasets count for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(2); + // }); + // }); + + // it("0240: access dataset 1 as User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.AccessForbiddenStatusCode); + // }); + + // it("0260: access dataset 3 as User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0270: full query for datasets for User 2", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // res.body[0]["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0280: list of datasets for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(3); + // }); + // }); + + // it("0290: datasets count for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/count") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body["count"].should.be.equal(3); + // }); + // }); + + // it("0300: access dataset 1 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid1); + // }); + // }); + + // it("0310: access dataset 2 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid2); + // }); + // }); + + // it("0320: access dataset 3 as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body["pid"].should.be.equal(datasetPid3); + // }); + // }); + + // it("0330: full query for datasets for User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/fullquery") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // }); + // }); + + // it("0340: update dataset 2 to be published as Admin Ingestor", async () => { + // return request(appUrl) + // .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) + // .send({ isPublished: true }) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + // .expect(TestData.SuccessfulPatchStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0350: full query for datasets for User 2", async () => { + // const fields = { + // isPublished: true, + // }; + + // return request(appUrl) + // .get( + // `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( + // JSON.stringify(fields), + // )}`, + // ) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(2); + // }); + // }); + + // it("0360: full facet for datasets for User 2", async () => { + // const fields = { + // isPublished: true, + // }; + // return request(appUrl) + // .get( + // `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( + // JSON.stringify(fields), + // )}`, + // ) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.SuccessfulGetStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body[0].all[0].totalSets.should.be.equal(2); + // }); + // }); + + // it("0370: access dataset 1 origdatablocks as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0380: access dataset 1 datablocks as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0390: access dataset 1 attachments as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode) + // .then((res) => { + // res.body.should.be.an("array").to.have.lengthOf(1); + // }); + // }); + + // it("0400: access dataset 1 thumbnail as User 3", async () => { + // return request(appUrl) + // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect("Content-Type", /json/) + // .expect(TestData.SuccessfulGetStatusCode); + // }); + + // it("0410: should delete dataset 1 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid1) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0420: should delete dataset 2 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid2) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0430: should delete dataset 3 as Archive Manager", async () => { + // return request(appUrl) + // .delete("/api/v3/datasets/" + encodedDatasetPid3) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + // .expect(TestData.SuccessfulDeleteStatusCode) + // .expect("Content-Type", /json/); + // }); + + // it("0500: add a new raw dataset as Admin", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0502: add a new raw dataset with specified pid as Admin", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "admin", + // }; + // console.log("0502: pid : " + datasetWithPid["pid"]); + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: uuidv4(), + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "admin", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0510: add a new raw dataset with different owner group as Admin", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser1}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group2", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.CreationForbiddenStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser2}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group3", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { + // const newDataset = { + // ...TestData.RawCorrect, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.be.string; + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const newDataset = { + // ...TestData.RawWrong_1, + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(newDataset) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.EntryCreatedStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + // res.body.should.have.property("owner").and.be.string; + // res.body.should.have.property("type").and.equal("raw"); + // }); + // }); + + // it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const datasetWithPid = { + // ...TestData.RawCorrect, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(datasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithPid = { + // ...TestData.RawWrong_1, + // pid: TestData.PidPrefix + "/" + uuidv4(), + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); + + // it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + // const invalidDatasetWithInvalidPid = { + // ...TestData.RawWrong_1, + // pid: "this-is-invalid-pid-1", + // ownerGroup: "group1", + // }; + + // return request(appUrl) + // .post("/api/v3/Datasets") + // .send(invalidDatasetWithInvalidPid) + // .set("Accept", "application/json") + // .set({ Authorization: `Bearer ${accessTokenUser3}` }) + // .expect(TestData.BadRequestStatusCode) + // .expect("Content-Type", /json/) + // .then((res) => { + // res.body.should.not.have.property("pid"); + // }); + // }); }); From c6d59fb04ed0fc05066b90a53f93c51fdb49c333 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 11 Sep 2024 15:01:03 +0200 Subject: [PATCH 213/258] fix types on obsolete schemas --- src/datasets/datasets.controller.ts | 54 +++++++++++++++++------------ 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 89e6f7536..19c480a9d 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -632,14 +632,14 @@ export class DatasetsController { ); const dtoTestRawCorrect = plainToInstance( - CreateRawDatasetDto, - createDatasetDto, + CreateRawDatasetObsoleteDto, + createDatasetObsoleteDto, ); const errorsTestRawCorrect = await validate(dtoTestRawCorrect); const dtoTestDerivedCorrect = plainToInstance( - CreateDerivedDatasetDto, - createDatasetDto, + CreateDerivedDatasetObsoleteDto, + createDatasetObsoleteDto, ); const errorsTestDerivedCorrect = await validate(dtoTestDerivedCorrect); @@ -1109,7 +1109,7 @@ export class DatasetsController { @Req() request: Request, @Param("pid") id: string, ): Promise { - const dataset = await this.checkPermissionsForDataset(request, id); + const dataset = await this.checkPermissionsForDatasetObsolete(request, id); return dataset; } @@ -1137,15 +1137,18 @@ export class DatasetsController { description: "Id of the dataset to modify", type: String, }) - @ApiExtraModels(PartialUpdateRawDatasetDto, PartialUpdateDerivedDatasetDto) + @ApiExtraModels( + PartialUpdateRawDatasetObsoleteDto, + PartialUpdateDerivedDatasetObsoleteDto, + ) @ApiBody({ description: "Fields that needs to be updated in the dataset. Only the fields that needs to be updated have to be passed in.", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(PartialUpdateRawDatasetDto) }, - { $ref: getSchemaPath(PartialUpdateDerivedDatasetDto) }, + { $ref: getSchemaPath(PartialUpdateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(PartialUpdateDerivedDatasetObsoleteDto) }, ], }, }) @@ -1160,8 +1163,8 @@ export class DatasetsController { @Param("pid") pid: string, @Body() updateDatasetDto: - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto, + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto, ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); @@ -1170,11 +1173,11 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - await this.validateDataset( + await this.validateDatasetObsolete( updateDatasetDto, foundDataset.type === "raw" - ? PartialUpdateRawDatasetDto - : PartialUpdateDerivedDatasetDto, + ? PartialUpdateRawDatasetObsoleteDto + : PartialUpdateDerivedDatasetObsoleteDto, ); // NOTE: We need DatasetClass instance because casl module can not recognize the type from dataset mongo database model. If other fields are needed can be added later. @@ -1220,15 +1223,15 @@ export class DatasetsController { description: "Id of the dataset to modify", type: String, }) - @ApiExtraModels(UpdateRawDatasetDto, UpdateDerivedDatasetDto) + @ApiExtraModels(UpdateRawDatasetObsoleteDto, UpdateDerivedDatasetObsoleteDto) @ApiBody({ description: "Dataset object that needs to be updated. The whole dataset object with updated fields have to be passed in.", required: true, schema: { oneOf: [ - { $ref: getSchemaPath(UpdateRawDatasetDto) }, - { $ref: getSchemaPath(UpdateDerivedDatasetDto) }, + { $ref: getSchemaPath(UpdateRawDatasetObsoleteDto) }, + { $ref: getSchemaPath(UpdateDerivedDatasetObsoleteDto) }, ], }, }) @@ -1241,7 +1244,10 @@ export class DatasetsController { async findByIdAndReplace( @Req() request: Request, @Param("pid") pid: string, - @Body() updateDatasetDto: UpdateRawDatasetDto | UpdateDerivedDatasetDto, + @Body() + updateDatasetObsoleteDto: + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); @@ -1250,11 +1256,11 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - const outputDto = await this.validateDataset( - updateDatasetDto, + const outputDto = await this.validateDatasetObsolete( + updateDatasetObsoleteDto, foundDataset.type === "raw" - ? UpdateRawDatasetDto - : UpdateDerivedDatasetDto, + ? UpdateRawDatasetObsoleteDto + : UpdateDerivedDatasetObsoleteDto, ); const datasetInstance = @@ -1274,7 +1280,9 @@ export class DatasetsController { return this.datasetsService.findByIdAndReplace( pid, - outputDto as UpdateRawDatasetDto | UpdateDerivedDatasetDto, + outputDto as + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto, ); } @@ -2172,7 +2180,7 @@ export class DatasetsController { Action.DatasetLogbookRead, ); - const proposalId = dataset?.proposalId; + const proposalId = (dataset?.proposalIds || [])[0]; if (!proposalId) return null; From 74a6c266cbde1c61eaa4c651059c496e6f01f20b Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Sep 2024 15:56:54 +0200 Subject: [PATCH 214/258] updated to use latest dataset schema in service --- src/datasets/datasets.controller.ts | 125 +++++++++++++++++-------- src/datasets/datasets.service.ts | 47 ++++------ src/datasets/dto/update-dataset.dto.ts | 20 ++++ 3 files changed, 123 insertions(+), 69 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 19c480a9d..9071f6e53 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -100,6 +100,10 @@ import configuration from "src/config/configuration"; import { DatasetType } from "./dataset-type.enum"; import { OutputDatasetObsoleteDto } from "./dto/output-dataset-obsolete.dto"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; +import { + PartialUpdateDatasetDto, + UpdateDatasetDto, +} from "./dto/update-dataset.dto"; @ApiBearerAuth() @ApiExtraModels( @@ -393,60 +397,98 @@ export class DatasetsController { } convertObsoleteToCurrentSchema( - inputDataset: CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto, - ): CreateDatasetDto { + inputObsoleteDataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | UpdateRawDatasetObsoleteDto + | UpdateDerivedDatasetObsoleteDto + | PartialUpdateRawDatasetObsoleteDto + | PartialUpdateDerivedDatasetObsoleteDto, + ): CreateDatasetDto | UpdateDatasetDto | PartialUpdateDatasetDto { const propertiesModifier: Record = {}; - if (inputDataset.type == "raw") { - if ("proposalId" in inputDataset) { + + if ( + inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof UpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof PartialUpdateRawDatasetObsoleteDto + ) { + if ("proposalId" in inputObsoleteDataset) { propertiesModifier.proposalIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).proposalId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).proposalId, ]; } - if ("sampleId" in inputDataset) { + if ("sampleId" in inputObsoleteDataset) { propertiesModifier.sampleIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).sampleId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).sampleId, ]; } - if ("instrumentIds" in inputDataset) { + if ("instrumentIds" in inputObsoleteDataset) { propertiesModifier.instrumentIds = [ - (inputDataset as CreateRawDatasetObsoleteDto).instrumentId, + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).instrumentId, ]; } } else { - if ("investigator" in inputDataset) { + if ("investigator" in inputObsoleteDataset) { propertiesModifier.principalInvestigator = [ - (inputDataset as CreateDerivedDatasetObsoleteDto).investigator, + (inputObsoleteDataset as CreateDerivedDatasetObsoleteDto) + .investigator, ]; } } - const outputDataset: CreateDatasetDto = { - ...(inputDataset as CreateDatasetDto), - ...propertiesModifier, - }; + let outputDataset: + | CreateDatasetDto + | UpdateDatasetDto + | PartialUpdateDatasetDto = {}; + if ( + inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof CreateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as CreateDatasetDto), + ...propertiesModifier, + } as CreateDatasetDto; + } else if ( + inputObsoleteDataset instanceof UpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof UpdateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as UpdateDatasetDto), + ...propertiesModifier, + } as UpdateDatasetDto; + } else if ( + inputObsoleteDataset instanceof PartialUpdateRawDatasetObsoleteDto || + inputObsoleteDataset instanceof PartialUpdateDerivedDatasetObsoleteDto + ) { + outputDataset = { + ...(inputObsoleteDataset as PartialUpdateDatasetDto), + ...propertiesModifier, + } as PartialUpdateDatasetDto; + } return outputDataset; } convertCurrentToObsoleteSchema( - inputDataset: DatasetClass, + inputDataset: DatasetClass | null, ): OutputDatasetObsoleteDto { const propertiesModifier: Record = {}; - if ("proposalIds" in inputDataset) { - propertiesModifier.proposalIds = inputDataset.proposalIds![0]; - } - if ("sampleIds" in inputDataset) { - propertiesModifier.sampleIds = inputDataset.sampleIds![0]; - } - if ("instrumentIds" in inputDataset) { - propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; - } - if (inputDataset.type == "raw") { - if ("investigator" in inputDataset) { - propertiesModifier.investigator = inputDataset.principalInvestigator; + if (inputDataset) { + if ("proposalIds" in inputDataset) { + propertiesModifier.proposalIds = inputDataset.proposalIds![0]; + } + if ("sampleIds" in inputDataset) { + propertiesModifier.sampleIds = inputDataset.sampleIds![0]; + } + if ("instrumentIds" in inputDataset) { + propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; + } + if (inputDataset.type == "raw") { + if ("investigator" in inputDataset) { + propertiesModifier.investigator = inputDataset.principalInvestigator; + } } } - const outputDataset: OutputDatasetObsoleteDto = { ...(inputDataset as OutputDatasetObsoleteDto), ...propertiesModifier, @@ -509,8 +551,9 @@ export class DatasetsController { ); try { - const datasetDto = - this.convertObsoleteToCurrentSchema(obsoleteDatasetDto); + const datasetDto = this.convertObsoleteToCurrentSchema( + obsoleteDatasetDto, + ) as CreateDatasetDto; const createdDataset = await this.datasetsService.create(datasetDto); const outputObsoleteDatasetDto = @@ -772,7 +815,7 @@ export class DatasetsController { async fullquery( @Req() request: Request, @Query() filters: { fields?: string; limits?: string }, - ): Promise { + ): Promise { const user: JWTUser = request.user as JWTUser; const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}"); @@ -809,7 +852,9 @@ export class DatasetsController { limits: JSON.parse(filters.limits ?? "{}"), }; - return this.datasetsService.fullquery(parsedFilters); + const results = await this.datasetsService.fullquery(parsedFilters); + + return results as OutputDatasetObsoleteDto[]; } // GET /fullfacets @@ -1108,10 +1153,12 @@ export class DatasetsController { async findById( @Req() request: Request, @Param("pid") id: string, - ): Promise { - const dataset = await this.checkPermissionsForDatasetObsolete(request, id); + ): Promise { + const dataset = this.convertCurrentToObsoleteSchema( + await this.checkPermissionsForDatasetObsolete(request, id), + ); - return dataset; + return dataset as OutputDatasetObsoleteDto; } // PATCH /datasets/:id @@ -1165,7 +1212,7 @@ export class DatasetsController { updateDatasetDto: | PartialUpdateRawDatasetObsoleteDto | PartialUpdateDerivedDatasetObsoleteDto, - ): Promise { + ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); if (!foundDataset) { @@ -1196,7 +1243,9 @@ export class DatasetsController { throw new ForbiddenException("Unauthorized to update this dataset"); } - return this.datasetsService.findByIdAndUpdate(pid, updateDatasetDto); + return this.convertCurrentToObsoleteSchema( + await this.datasetsService.findByIdAndUpdate(pid, updateDatasetDto), + ); } // PUT /datasets/:id diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 60793750d..723552172 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -25,20 +25,13 @@ import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.se import { LogbooksService } from "src/logbooks/logbooks.service"; import { DatasetType } from "./dataset-type.enum"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; -import { - PartialUpdateDatasetObsoleteDto, - UpdateDatasetObsoleteDto, -} from "./dto/update-dataset-obsolete.dto"; -import { - PartialUpdateDerivedDatasetDto, - UpdateDerivedDatasetDto, -} from "./dto/update-derived-dataset-obsolete.dto"; -import { - PartialUpdateRawDatasetDto, - UpdateRawDatasetDto, -} from "./dto/update-raw-dataset-obsolete.dto"; import { IDatasetFields } from "./interfaces/dataset-filters.interface"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; +import { + PartialUpdateDatasetDto, + PartialUpdateDatasetWithHistoryDto, + UpdateDatasetDto, +} from "./dto/update-dataset.dto"; @Injectable({ scope: Scope.REQUEST }) export class DatasetsService { @@ -205,10 +198,7 @@ export class DatasetsService { // we update the full dataset if exist or create a new one if it does not async findByIdAndReplace( id: string, - updateDatasetDto: - | UpdateDatasetObsoleteDto - | UpdateRawDatasetDto - | UpdateDerivedDatasetDto, + updateDatasetDto: UpdateDatasetDto, ): Promise { const username = (this.request.user as JWTUser).username; const existingDataset = await this.datasetModel.findOne({ pid: id }).exec(); @@ -252,10 +242,8 @@ export class DatasetsService { async findByIdAndUpdate( id: string, updateDatasetDto: - | PartialUpdateDatasetObsoleteDto - | PartialUpdateRawDatasetDto - | PartialUpdateDerivedDatasetDto - | UpdateQuery, + | PartialUpdateDatasetDto + | PartialUpdateDatasetWithHistoryDto, ): Promise { const existingDataset = await this.datasetModel.findOne({ pid: id }).exec(); // check if we were able to find the dataset @@ -434,7 +422,7 @@ export class DatasetsService { async updateHistory( req: Request, dataset: DatasetClass, - data: UpdateDatasetObsoleteDto, + data: PartialUpdateDatasetDto, ) { if (req.body.history) { delete req.body.history; @@ -442,17 +430,17 @@ export class DatasetsService { if (!req.body.size && !req.body.packedSize) { const updatedFields: Omit< - UpdateDatasetObsoleteDto, + PartialUpdateDatasetDto, "updatedAt" | "updatedBy" > = data; const historyItem: Record = {}; Object.keys(updatedFields).forEach((updatedField) => { - historyItem[updatedField as keyof UpdateDatasetObsoleteDto] = { - currentValue: data[updatedField as keyof UpdateDatasetObsoleteDto], + historyItem[updatedField as keyof UpdateDatasetDto] = { + currentValue: data[updatedField as keyof UpdateDatasetDto], previousValue: dataset[ updatedField as keyof Omit< - UpdateDatasetObsoleteDto, + UpdateDatasetDto, "attachments" | "origdatablocks" | "datablocks" > ], @@ -468,18 +456,15 @@ export class DatasetsService { if (logbookEnabled) { const user = (req.user as JWTUser).username.replace("ldap.", ""); const datasetPid = dataset.pid; - const proposalId = - dataset.type === DatasetType.Raw - ? (dataset as unknown as DatasetClass).proposalId - : undefined; - if (proposalId) { + const proposalIds = dataset.proposalIds || []; + (proposalIds as Array).forEach(async (proposalId) => { await Promise.all( Object.keys(updatedFields).map(async (updatedField) => { const message = `${user} updated "${updatedField}" of dataset with PID ${datasetPid}`; await this.logbooksService.sendMessage(proposalId, { message }); }), ); - } + }); } } } diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index ad928772f..26866705d 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -24,6 +24,7 @@ import { CreateTechniqueDto } from "./create-technique.dto"; import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; +import { HistoryClass } from "../schemas/history.schema"; @ApiTags("datasets") export class UpdateDatasetDto extends OwnableDto { @@ -420,3 +421,22 @@ export class UpdateDatasetDto extends OwnableDto { } export class PartialUpdateDatasetDto extends PartialType(UpdateDatasetDto) {} + +export class UpdateDatasetWithHistoryDto extends UpdateDatasetDto { + @ApiProperty({ + type: "array", + items: { $ref: getSchemaPath(HistoryClass) }, + required: false, + default: [], + description: "List of history objects containing old and new values.", + }) + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => HistoryClass) + readonly history?: HistoryClass[]; +} + +export class PartialUpdateDatasetWithHistoryDto extends PartialType( + UpdateDatasetWithHistoryDto, +) {} From 15b2740fbbcb1daa95f9bd93f724e40cb17c7484 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 13 Sep 2024 16:04:08 +0200 Subject: [PATCH 215/258] refactoring data types --- src/datasets/datasets.controller.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 9071f6e53..575adc98b 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -1297,7 +1297,7 @@ export class DatasetsController { updateDatasetObsoleteDto: | UpdateRawDatasetObsoleteDto | UpdateDerivedDatasetObsoleteDto, - ): Promise { + ): Promise { const foundDataset = await this.datasetsService.findOne({ where: { pid } }); if (!foundDataset) { @@ -1305,7 +1305,7 @@ export class DatasetsController { } // NOTE: Default validation pipe does not validate union types. So we need custom validation. - const outputDto = await this.validateDatasetObsolete( + const updateValidatedDto = await this.validateDatasetObsolete( updateDatasetObsoleteDto, foundDataset.type === "raw" ? UpdateRawDatasetObsoleteDto @@ -1327,12 +1327,15 @@ export class DatasetsController { throw new ForbiddenException("Unauthorized to update this dataset"); } - return this.datasetsService.findByIdAndReplace( + const updateDatasetDto = + await this.convertObsoleteToCurrentSchema(updateValidatedDto); + + const outputDatasetDto = await this.datasetsService.findByIdAndReplace( pid, - outputDto as - | UpdateRawDatasetObsoleteDto - | UpdateDerivedDatasetObsoleteDto, + updateDatasetDto as UpdateDatasetDto, ); + + return await this.convertCurrentToObsoleteSchema(outputDatasetDto); } // DELETE /datasets/:id From 2244c18663facd6835d5350b39422587cff042b0 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Mon, 16 Sep 2024 14:31:38 +0200 Subject: [PATCH 216/258] First two dataset test passing --- src/datasets/datasets.controller.ts | 27 +++++++++----- src/datasets/schemas/dataset.schema.ts | 6 +-- .../origdatablocks.controller.ts | 9 +++-- .../published-data.controller.ts | 8 +++- test/DatasetAuthorization.js | 37 +++++++++---------- 5 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 575adc98b..9e1430701 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -61,7 +61,7 @@ import { DatablocksService } from "src/datablocks/datablocks.service"; import { Datablock } from "src/datablocks/schemas/datablock.schema"; import { CreateDatablockDto } from "src/datablocks/dto/create-datablock.dto"; import { PartialUpdateDatablockDto } from "src/datablocks/dto/update-datablock.dto"; -import { UpdateQuery } from "mongoose"; +import { Document, UpdateQuery } from "mongoose"; import { FilterPipe } from "src/common/pipes/filter.pipe"; import { UTCTimeInterceptor } from "src/common/interceptors/utc-time.interceptor"; import { DataFile } from "src/common/schemas/datafile.schema"; @@ -405,7 +405,9 @@ export class DatasetsController { | PartialUpdateRawDatasetObsoleteDto | PartialUpdateDerivedDatasetObsoleteDto, ): CreateDatasetDto | UpdateDatasetDto | PartialUpdateDatasetDto { - const propertiesModifier: Record = {}; + const propertiesModifier: Record = { + version: "v3", + }; if ( inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || @@ -489,8 +491,9 @@ export class DatasetsController { } } } + const outputDataset: OutputDatasetObsoleteDto = { - ...(inputDataset as OutputDatasetObsoleteDto), + ...(inputDataset as DatasetDocument).toObject(), ...propertiesModifier, }; @@ -537,17 +540,17 @@ export class DatasetsController { | CreateDerivedDatasetObsoleteDto, ): Promise { // validate dataset - await this.validateDatasetObsolete( + const validatedDatasetObsoleteDto = (await this.validateDatasetObsolete( createDatasetObsoleteDto, createDatasetObsoleteDto.type === "raw" ? CreateRawDatasetObsoleteDto : CreateDerivedDatasetObsoleteDto, - ); + )) as CreateRawDatasetObsoleteDto | CreateDerivedDatasetObsoleteDto; const obsoleteDatasetDto = await this.checkPermissionsForObsoleteDatasetCreate( request, - createDatasetObsoleteDto, + validatedDatasetObsoleteDto, ); try { @@ -598,11 +601,18 @@ export class DatasetsController { }, }; + // first we convert input object to the correct class + const outputDatasetDto = plainToInstance(dto, inputDatasetDto); + if ( - inputDatasetDto instanceof + outputDatasetDto instanceof (CreateRawDatasetObsoleteDto || CreateDerivedDatasetObsoleteDto) ) { - if (!(inputDatasetDto.type in DatasetType)) { + if ( + !(Object.values(DatasetType) as string[]).includes( + outputDatasetDto.type, + ) + ) { throw new HttpException( { status: HttpStatus.BAD_REQUEST, @@ -613,7 +623,6 @@ export class DatasetsController { } } - const outputDatasetDto = plainToInstance(dto, inputDatasetDto); const errors = await validate(outputDatasetDto, validateOptions); if (errors.length > 0) { diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 58fdcd1e4..9b3d7f7e2 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -449,13 +449,13 @@ export class DatasetClass extends OwnableClass { dataFormat?: string; @ApiProperty({ - type: String, + type: [String], required: false, description: "The ID of the proposal to which the dataset belongs to and it has been acquired under.", }) - @Prop({ type: String, ref: "Proposal", required: false }) - proposalIds?: string; + @Prop({ type: [String], ref: "Proposal", required: false }) + proposalIds?: string[]; @ApiProperty({ type: [String], diff --git a/src/origdatablocks/origdatablocks.controller.ts b/src/origdatablocks/origdatablocks.controller.ts index 308eb32e9..97e21d50b 100644 --- a/src/origdatablocks/origdatablocks.controller.ts +++ b/src/origdatablocks/origdatablocks.controller.ts @@ -45,8 +45,8 @@ import { PartialUpdateDatasetDto } from "src/datasets/dto/update-dataset.dto"; import { filterDescription, filterExample } from "src/common/utils"; import { JWTUser } from "src/auth/interfaces/jwt-user.interface"; import { DatasetClass } from "src/datasets/schemas/dataset.schema"; -import { CreateRawDatasetDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; -import { CreateDerivedDatasetDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; +import { CreateRawDatasetObsoleteDto } from "src/datasets/dto/create-raw-dataset-obsolete.dto"; +import { CreateDerivedDatasetObsoleteDto } from "src/datasets/dto/create-derived-dataset-obsolete.dto"; import { logger } from "@user-office-software/duo-logger"; @ApiBearerAuth() @@ -103,7 +103,10 @@ export class OrigDatablocksController { // } async generateOrigDatablockInstanceInstanceForPermissions( - dataset: CreateRawDatasetDto | CreateDerivedDatasetDto | DatasetClass, + dataset: + | CreateRawDatasetObsoleteDto + | CreateDerivedDatasetObsoleteDto + | DatasetClass, ): Promise { const origDatablockInstance = new OrigDatablock(); origDatablockInstance.datasetId = dataset.pid || ""; diff --git a/src/published-data/published-data.controller.ts b/src/published-data/published-data.controller.ts index 3d8199c7d..0786e9a53 100644 --- a/src/published-data/published-data.controller.ts +++ b/src/published-data/published-data.controller.ts @@ -166,13 +166,17 @@ export class PublishedDataController { }) async formPopulate(@Query("pid") pid: string) { const formData: IFormPopulateData = {}; - const dataset = await this.datasetsService.findOne({ where: { pid } }); + const dataset = (await this.datasetsService.findOne({ + where: { pid }, + })) as unknown as DatasetClass; let proposalId; if (dataset) { formData.resourceType = dataset.type; formData.description = dataset.description; - proposalId = (dataset as unknown as DatasetClass).proposalId; + if ("proposalIds" in dataset) { + proposalId = dataset.proposalIds![0]; + } } let proposal; diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index 56a8b7717..63e4b21c5 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -83,7 +83,6 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); it("0010: adds dataset 1 as Admin Ingestor", async () => { - console.log(JSON.stringify(dataset1)); return request(appUrl) .post("/api/v3/Datasets") .send(dataset1) @@ -92,8 +91,6 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - console.log("Results"); - console.log(res.body); res.body.should.have.property("ownerGroup").and.equal("group4"); res.body.should.have.property("type").and.equal("raw"); res.body.should.have.property("isPublished").and.equal(true); @@ -103,23 +100,23 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - // it("0020: adds dataset 2 as Admin Ingestor", async () => { - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(dataset2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("ownerGroup").and.equal("group1"); - // res.body.should.have.property("type").and.equal("raw"); - // res.body.should.have.property("isPublished").and.equal(false); - // res.body.should.have.property("pid").and.be.string; - // datasetPid2 = res.body["pid"]; - // encodedDatasetPid2 = encodeURIComponent(datasetPid2); - // }); - // }); + it("0020: adds dataset 2 as Admin Ingestor", async () => { + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerGroup").and.equal("group1"); + res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); + res.body.should.have.property("pid").and.be.string; + datasetPid2 = res.body["pid"]; + encodedDatasetPid2 = encodeURIComponent(datasetPid2); + }); + }); // it("0030: adds dataset 3 as Admin Ingestor", async () => { // return request(appUrl) From ebc2666f6c45bcb4c5cb95ede6145d0ec08644f5 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 17 Sep 2024 14:47:28 +0200 Subject: [PATCH 217/258] fixed tests in Datasets Simple --- src/datasets/datasets.controller.ts | 7 +- test/DatasetAuthorization.js | 2835 +++++++++++++-------------- 2 files changed, 1420 insertions(+), 1422 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 9e1430701..2b4b3aec1 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -431,10 +431,9 @@ export class DatasetsController { } } else { if ("investigator" in inputObsoleteDataset) { - propertiesModifier.principalInvestigator = [ - (inputObsoleteDataset as CreateDerivedDatasetObsoleteDto) - .investigator, - ]; + propertiesModifier.principalInvestigator = ( + inputObsoleteDataset as CreateDerivedDatasetObsoleteDto + ).investigator; } } diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index 63e4b21c5..3aeb7f749 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -118,1422 +118,1421 @@ describe("0300: DatasetAuthorization: Test access to dataset", () => { }); }); - // it("0030: adds dataset 3 as Admin Ingestor", async () => { - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(dataset3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("ownerGroup").and.equal("group2"); - // res.body.should.have.property("type").and.equal("raw"); - // res.body.should.have.property("isPublished").and.equal(false); - // res.body.should.have.property("pid").and.be.string; - // datasetPid3 = res.body["pid"]; - // encodedDatasetPid3 = encodeURIComponent(datasetPid3); - // }); - // }); - - // it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) - // .send(TestData.OrigDataBlockCorrect1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have - // .property("size") - // .and.equal(TestData.OrigDataBlockCorrect1.size); - // res.body.should.have.property("id").and.be.string; - // }); - // }); - - // it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { - // const randomArchiveId = Math.random().toString(36).slice(2); - - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) - // .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have - // .property("size") - // .and.equal(TestData.DataBlockCorrect.size); - // res.body.should.have.property("id").and.be.string; - // }); - // }); - - // it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { - // return request(appUrl) - // .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) - // .send(TestData.AttachmentCorrect) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0070: list of public datasets, aka as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0080: access public dataset as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0090: access private dataset as unauthenticated user", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0100: list of datasets for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0110: datasets counts for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(3); - // }); - // }); - - // it("0120: access dataset 1 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0130: full query for datasets for Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0140: access dataset 2 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0150: access dataset 3 as Admin Ingestor", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0160: list of datasets for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // res.body[1]["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0170: datasets count for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(2); - // }); - // }); - - // it("0180: access dataset 1 as User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0190: access dataset 2 as User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0210: full query for datasets for User 1", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0220: list of datasets for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // res.body[1]["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0230: datasets count for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(2); - // }); - // }); - - // it("0240: access dataset 1 as User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.AccessForbiddenStatusCode); - // }); - - // it("0260: access dataset 3 as User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0270: full query for datasets for User 2", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // res.body[0]["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0280: list of datasets for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(3); - // }); - // }); - - // it("0290: datasets count for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/count") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body["count"].should.be.equal(3); - // }); - // }); - - // it("0300: access dataset 1 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid1); - // }); - // }); - - // it("0310: access dataset 2 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid2); - // }); - // }); - - // it("0320: access dataset 3 as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body["pid"].should.be.equal(datasetPid3); - // }); - // }); - - // it("0330: full query for datasets for User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/fullquery") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // }); - // }); - - // it("0340: update dataset 2 to be published as Admin Ingestor", async () => { - // return request(appUrl) - // .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) - // .send({ isPublished: true }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - // .expect(TestData.SuccessfulPatchStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0350: full query for datasets for User 2", async () => { - // const fields = { - // isPublished: true, - // }; - - // return request(appUrl) - // .get( - // `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( - // JSON.stringify(fields), - // )}`, - // ) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(2); - // }); - // }); - - // it("0360: full facet for datasets for User 2", async () => { - // const fields = { - // isPublished: true, - // }; - // return request(appUrl) - // .get( - // `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( - // JSON.stringify(fields), - // )}`, - // ) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.SuccessfulGetStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body[0].all[0].totalSets.should.be.equal(2); - // }); - // }); - - // it("0370: access dataset 1 origdatablocks as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0380: access dataset 1 datablocks as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0390: access dataset 1 attachments as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode) - // .then((res) => { - // res.body.should.be.an("array").to.have.lengthOf(1); - // }); - // }); - - // it("0400: access dataset 1 thumbnail as User 3", async () => { - // return request(appUrl) - // .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect("Content-Type", /json/) - // .expect(TestData.SuccessfulGetStatusCode); - // }); - - // it("0410: should delete dataset 1 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid1) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0420: should delete dataset 2 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid2) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0430: should delete dataset 3 as Archive Manager", async () => { - // return request(appUrl) - // .delete("/api/v3/datasets/" + encodedDatasetPid3) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(TestData.SuccessfulDeleteStatusCode) - // .expect("Content-Type", /json/); - // }); - - // it("0500: add a new raw dataset as Admin", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0502: add a new raw dataset with specified pid as Admin", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "admin", - // }; - // console.log("0502: pid : " + datasetWithPid["pid"]); - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: uuidv4(), - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "admin", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0510: add a new raw dataset with different owner group as Admin", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenAdmin}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser1}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group2", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.CreationForbiddenStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser2}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group3", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { - // const newDataset = { - // ...TestData.RawCorrect, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.be.string; - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const newDataset = { - // ...TestData.RawWrong_1, - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(newDataset) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.EntryCreatedStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("pid").and.equal(datasetWithPid.pid); - // res.body.should.have.property("owner").and.be.string; - // res.body.should.have.property("type").and.equal("raw"); - // }); - // }); - - // it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const datasetWithPid = { - // ...TestData.RawCorrect, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(datasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithPid = { - // ...TestData.RawWrong_1, - // pid: TestData.PidPrefix + "/" + uuidv4(), - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); - - // it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { - // const invalidDatasetWithInvalidPid = { - // ...TestData.RawWrong_1, - // pid: "this-is-invalid-pid-1", - // ownerGroup: "group1", - // }; - - // return request(appUrl) - // .post("/api/v3/Datasets") - // .send(invalidDatasetWithInvalidPid) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenUser3}` }) - // .expect(TestData.BadRequestStatusCode) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.not.have.property("pid"); - // }); - // }); + it("0030: adds dataset 3 as Admin Ingestor", async () => { + return request(appUrl) + .post("/api/v3/Datasets") + .send(dataset3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerGroup").and.equal("group2"); + res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); + res.body.should.have.property("pid").and.be.string; + datasetPid3 = res.body["pid"]; + encodedDatasetPid3 = encodeURIComponent(datasetPid3); + }); + }); + + it("0040: adds a new origDatablock on the published dataset as Admin Ingestor", async () => { + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/origdatablocks`) + .send(TestData.OrigDataBlockCorrect1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have + .property("size") + .and.equal(TestData.OrigDataBlockCorrect1.size); + res.body.should.have.property("id").and.be.string; + }); + }); + + it("0050: adds a new datablock on the published dataset as Admin Ingestor", async () => { + const randomArchiveId = Math.random().toString(36).slice(2); + + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/datablocks`) + .send({ ...TestData.DataBlockCorrect, archiveId: randomArchiveId }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have + .property("size") + .and.equal(TestData.DataBlockCorrect.size); + res.body.should.have.property("id").and.be.string; + }); + }); + + it("0060: adds a new attachment on the published dataset as Admin Ingestor", async () => { + return request(appUrl) + .post(`/api/v3/datasets/${encodedDatasetPid1}/attachments`) + .send(TestData.AttachmentCorrect) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/); + }); + + it("0070: list of public datasets, aka as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0080: access public dataset as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0090: access private dataset as unauthenticated user", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0100: list of datasets for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0110: datasets counts for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(3); + }); + }); + + it("0120: access dataset 1 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0130: full query for datasets for Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0140: access dataset 2 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0150: access dataset 3 as Admin Ingestor", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0160: list of datasets for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + res.body[1]["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0170: datasets count for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(2); + }); + }); + + it("0180: access dataset 1 as User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0190: access dataset 2 as User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0200: access dataset 3 as User 1, which should fail as forbidden", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0210: full query for datasets for User 1", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0220: list of datasets for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + res.body[1]["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0230: datasets count for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(2); + }); + }); + + it("0240: access dataset 1 as User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0250: access dataset 2 as User 2, which should fail as forbidden", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.AccessForbiddenStatusCode); + }); + + it("0260: access dataset 3 as User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0270: full query for datasets for User 2", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + res.body[0]["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0280: list of datasets for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(3); + }); + }); + + it("0290: datasets count for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/count") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body["count"].should.be.equal(3); + }); + }); + + it("0300: access dataset 1 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid1); + }); + }); + + it("0310: access dataset 2 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid2); + }); + }); + + it("0320: access dataset 3 as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body["pid"].should.be.equal(datasetPid3); + }); + }); + + it("0330: full query for datasets for User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/fullquery") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("0340: update dataset 2 to be published as Admin Ingestor", async () => { + return request(appUrl) + .patch(`/api/v3/Datasets/${encodedDatasetPid2}`) + .send({ isPublished: true }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0350: full query for datasets for User 2", async () => { + const fields = { + isPublished: true, + }; + + return request(appUrl) + .get( + `/api/v3/Datasets/fullquery?fields=${encodeURIComponent( + JSON.stringify(fields), + )}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("0360: full facet for datasets for User 2", async () => { + const fields = { + isPublished: true, + }; + return request(appUrl) + .get( + `/api/v3/Datasets/fullfacet?fields=${encodeURIComponent( + JSON.stringify(fields), + )}`, + ) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body[0].all[0].totalSets.should.be.equal(2); + }); + }); + + it("0370: access dataset 1 origdatablocks as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/origdatablocks") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0380: access dataset 1 datablocks as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/datablocks") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0390: access dataset 1 attachments as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/attachments") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("0400: access dataset 1 thumbnail as User 3", async () => { + return request(appUrl) + .get("/api/v3/Datasets/" + encodedDatasetPid1 + "/thumbnail") + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect("Content-Type", /json/) + .expect(TestData.SuccessfulGetStatusCode); + }); + + it("0410: should delete dataset 1 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0420: should delete dataset 2 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid2) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0430: should delete dataset 3 as Archive Manager", async () => { + return request(appUrl) + .delete("/api/v3/datasets/" + encodedDatasetPid3) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) + .expect(TestData.SuccessfulDeleteStatusCode) + .expect("Content-Type", /json/); + }); + + it("0500: add a new raw dataset as Admin", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0501: add a new incomplete raw dataset as Admin, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0502: add a new raw dataset with specified pid as Admin", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0503: add a new raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0504: add a new invalid raw dataset with specified pid as Admin, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: uuidv4(), + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0505: add a new invalid raw dataset with specified invalid pid as Admin, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "admin", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0510: add a new raw dataset with different owner group as Admin", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0520: add a new incomplete raw dataset with different owner group as Admin, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0530: add a new raw dataset with specified pid and different owner group as Admin", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0540: add a new raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0550: add a new invalid raw dataset with specified pid and different owner group as Admin, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0560: add a new invalid raw dataset with specified invalid pid and different owner group as Admin, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0600: add a new raw dataset as User 1 which belongs to a create dataset group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0601: add a new incomplete raw dataset as User 1 which belongs to a create dataset group", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0602: add a new raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0603: add a new raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0604: add a new invalid raw dataset with specified pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0605: add a new invalid raw dataset with specified invalid pid as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0610: add a new raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0620: add a new incomplete raw dataset with different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0630: add a new raw dataset with specified pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0640: add a new raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0650: add a new invalid raw dataset with specified pid and different owner group as User 1 which belongs to a ", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0660: add a new invalid raw dataset with specified invalid pid and different owner group as User 1 which belongs to a create dataset group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0700: add a new raw dataset as User 2 which belongs to a create dataset with pid group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0701: add a new incomplete raw dataset as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0702: add a new raw dataset with specified pid as User 2 which belongs to a create dataset with pid group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0703: add a new raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0704: add a new invalid raw dataset with specified pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0705: add a new invalid raw dataset with specified invalid pid as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group2", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0710: add a new raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0720: add a new incomplete raw dataset with different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0730: add a new raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0740: add a new raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as forbidden", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.CreationForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0750: add a new invalid raw dataset with specified pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0760: add a new invalid raw dataset with specified invalid pid and different owner group as User 2 which belongs to a create dataset with pid group, which should fail as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser2}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0800: add a new raw dataset as User 3 which belongs to a create dataset privileged group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0801: add a new incomplete raw dataset as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0802: add a new raw dataset with specified pid as User 3 which belongs to a create dataset privileged group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0803: add a new raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0804: add a new invalid raw dataset with specified pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0805: add a new invalid raw dataset with specified invalid pid as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group3", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0810: add a new raw dataset with different owner group as User 3 which belongs to a create dataset privileged group", async () => { + const newDataset = { + ...TestData.RawCorrect, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0820: add a new incomplete raw dataset with different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const newDataset = { + ...TestData.RawWrong_1, + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0830: add a new raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("pid").and.equal(datasetWithPid.pid); + res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("type").and.equal("raw"); + }); + }); + + it("0840: add a new raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const datasetWithPid = { + ...TestData.RawCorrect, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(datasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0850: add a new invalid raw dataset with specified pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithPid = { + ...TestData.RawWrong_1, + pid: TestData.PidPrefix + "/" + uuidv4(), + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); + + it("0860: add a new invalid raw dataset with specified invalid pid and different owner group as User 3 which belongs to a create dataset privileged group, which fails as bad request", async () => { + const invalidDatasetWithInvalidPid = { + ...TestData.RawWrong_1, + pid: "this-is-invalid-pid-1", + ownerGroup: "group1", + }; + + return request(appUrl) + .post("/api/v3/Datasets") + .send(invalidDatasetWithInvalidPid) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("pid"); + }); + }); }); From b9cf5b338069aca506dbcda57cd9355d68b5780e Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 17 Sep 2024 17:35:20 +0200 Subject: [PATCH 218/258] making progress with tests --- src/datasets/datasets.controller.ts | 31 +++++++++++++++++------------ test/DerivedDatasetDatablock.js | 2 +- test/OrigDatablockForRawDataset.js | 3 ++- test/TestData.js | 4 +++- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 2b4b3aec1..741c41e79 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -556,6 +556,7 @@ export class DatasetsController { const datasetDto = this.convertObsoleteToCurrentSchema( obsoleteDatasetDto, ) as CreateDatasetDto; + console.log(datasetDto); const createdDataset = await this.datasetsService.create(datasetDto); const outputObsoleteDatasetDto = @@ -1063,30 +1064,34 @@ export class DatasetsController { ) as Record, ) as IFilters; - const dataset = (await this.datasetsService.findOne( - mergedFilters, - )) as OutputDatasetObsoleteDto; + const databaseDataset = await this.datasetsService.findOne(mergedFilters); - if (dataset) { + const outputDataset = + await this.convertCurrentToObsoleteSchema(databaseDataset); + + if (outputDataset) { const includeFilters = mergedFilters.include ?? []; await Promise.all( includeFilters.map(async ({ relation }) => { switch (relation) { case "attachments": { - dataset.attachments = await this.attachmentsService.findAll({ - datasetId: dataset.pid, - }); + outputDataset.attachments = await this.attachmentsService.findAll( + { + datasetId: outputDataset.pid, + }, + ); break; } case "origdatablocks": { - dataset.origdatablocks = await this.origDatablocksService.findAll( - { where: { datasetId: dataset.pid } }, - ); + outputDataset.origdatablocks = + await this.origDatablocksService.findAll({ + where: { datasetId: outputDataset.pid }, + }); break; } case "datablocks": { - dataset.datablocks = await this.datablocksService.findAll({ - datasetId: dataset.pid, + outputDataset.datablocks = await this.datablocksService.findAll({ + datasetId: outputDataset.pid, }); break; } @@ -1094,7 +1099,7 @@ export class DatasetsController { }), ); } - return dataset; + return outputDataset; } // GET /datasets/count diff --git a/test/DerivedDatasetDatablock.js b/test/DerivedDatasetDatablock.js index 8ef6ff8c7..6c223246c 100644 --- a/test/DerivedDatasetDatablock.js +++ b/test/DerivedDatasetDatablock.js @@ -13,7 +13,7 @@ describe("0750: DerivedDatasetDatablock: Test Datablocks and their relation to d before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index 057134d35..859b49333 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -23,7 +23,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati db.collection("Dataset").deleteMany({}); db.collection("OrigDatablock").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -304,6 +304,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { + console.log(res.body); res.body["pid"].should.be.equal(decodeURIComponent(datasetPid1)); res.body.origdatablocks.should.be .instanceof(Array) diff --git a/test/TestData.js b/test/TestData.js index 538f657bf..bee14fe4c 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -119,6 +119,7 @@ const TestData = { sourceFolder: faker.system.directoryPath(), owner: faker.internet.userName(), contactEmail: faker.internet.email(), + datasetName: faker.string.sample(), }, RawCorrect: { @@ -384,13 +385,14 @@ const TestData = { DerivedCorrectMin: { investigator: faker.internet.email(), - inputDatasets: [faker.system.filePath()], + inputDatasets: [faker.string.uuid()], usedSoftware: [faker.internet.url()], owner: faker.internet.userName(), contactEmail: faker.internet.email(), sourceFolder: faker.system.directoryPath(), creationTime: faker.date.past(), ownerGroup: faker.string.alphanumeric(6), + datasetName: faker.string.sample(), type: "derived", }, From 79b1ac6c3d47ba66ee343371ee8e216cfa347263 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 18 Sep 2024 15:00:32 +0200 Subject: [PATCH 219/258] all test passing --- src/datasets/datasets.controller.ts | 1 - test/DatasetLifecycle.js | 3 ++- test/OrigDatablockForRawDataset.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 741c41e79..11cbc7b69 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -556,7 +556,6 @@ export class DatasetsController { const datasetDto = this.convertObsoleteToCurrentSchema( obsoleteDatasetDto, ) as CreateDatasetDto; - console.log(datasetDto); const createdDataset = await this.datasetsService.create(datasetDto); const outputObsoleteDatasetDto = diff --git a/test/DatasetLifecycle.js b/test/DatasetLifecycle.js index 3b26585de..0611be077 100644 --- a/test/DatasetLifecycle.js +++ b/test/DatasetLifecycle.js @@ -15,8 +15,9 @@ const raw2 = { ...TestData.RawCorrect }; describe("0500: DatasetLifecycle: Test facet and filter queries", () => { before(() => { db.collection("Dataset").deleteMany({}); + db.collection("Policy").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index 859b49333..d329d5867 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -304,7 +304,6 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { - console.log(res.body); res.body["pid"].should.be.equal(decodeURIComponent(datasetPid1)); res.body.origdatablocks.should.be .instanceof(Array) From df92c608c75e85aa3bdc7ae15cce13b02bd87911 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 2 Sep 2024 13:37:50 +0200 Subject: [PATCH 220/258] refacor: separate search ui logic from frontend --- src/config/default-filters.config.json | 11 ---- src/config/frontend.config.json | 17 ++++++- .../create-user-settings.interceptor.ts | 50 ------------------- .../default-user-settings.interceptor.ts | 33 ------------ src/users/schemas/user-settings.schema.ts | 7 +-- src/users/users.controller.ts | 27 +--------- 6 files changed, 19 insertions(+), 126 deletions(-) delete mode 100644 src/config/default-filters.config.json delete mode 100644 src/users/interceptors/create-user-settings.interceptor.ts delete mode 100644 src/users/interceptors/default-user-settings.interceptor.ts diff --git a/src/config/default-filters.config.json b/src/config/default-filters.config.json deleted file mode 100644 index 848bb1970..000000000 --- a/src/config/default-filters.config.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { "type": "LocationFilterComponent", "visible": true }, - { "type": "PidFilterComponent", "visible": true }, - { "type": "PidFilterContainsComponent", "visible": false }, - { "type": "PidFilterStartsWithComponent", "visible": false }, - { "type": "GroupFilterComponent", "visible": true }, - { "type": "TypeFilterComponent", "visible": true }, - { "type": "KeywordFilterComponent", "visible": true }, - { "type": "DateRangeFilterComponent", "visible": true }, - { "type": "TextFilterComponent", "visible": true } -] \ No newline at end of file diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 39ec77d8b..5dc093125 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -180,5 +180,20 @@ "enabled": "#Selected", "authorization": ["#datasetAccess", "#datasetPublic"] } - ] + ], + "defaultSearchInterfaceSettings": { + "columns": [], + "filters": [ + { "type": "LocationFilterComponent", "visible": true }, + { "type": "PidFilterComponent", "visible": true }, + { "type": "PidFilterContainsComponent", "visible": false }, + { "type": "PidFilterStartsWithComponent", "visible": false }, + { "type": "GroupFilterComponent", "visible": true }, + { "type": "TypeFilterComponent", "visible": true }, + { "type": "KeywordFilterComponent", "visible": true }, + { "type": "DateRangeFilterComponent", "visible": true }, + { "type": "TextFilterComponent", "visible": true } + ], + "conditions": [] + } } diff --git a/src/users/interceptors/create-user-settings.interceptor.ts b/src/users/interceptors/create-user-settings.interceptor.ts deleted file mode 100644 index e22d4f881..000000000 --- a/src/users/interceptors/create-user-settings.interceptor.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - CallHandler, - ExecutionContext, - Injectable, - Logger, - NestInterceptor, -} from "@nestjs/common"; -import { Observable, tap } from "rxjs"; -import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; -import { UsersService } from "../users.service"; -import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; - -@Injectable() -export class CreateUserSettingsInterceptor implements NestInterceptor { - constructor(private usersService: UsersService) {} - async intercept( - context: ExecutionContext, - next: CallHandler, - ): Promise> { - return next.handle().pipe( - tap(async () => { - const res = context.switchToHttp().getResponse(); - const user = res.req.user; - if (!user) { - return; - } - const userId = user._id; - const userSettings = - await this.usersService.findByIdUserSettings(userId); - if (!userSettings) { - Logger.log( - `Adding default settings to user ${user.username}`, - "CreateUserSettingsInterceptor", - ); - const createUserSettingsDto: CreateUserSettingsDto = { - userId, - columns: [], - filters: FILTER_CONFIGS, - conditions: [], - }; - return this.usersService.createUserSettings( - userId, - createUserSettingsDto, - ); - } - return; - }), - ); - } -} diff --git a/src/users/interceptors/default-user-settings.interceptor.ts b/src/users/interceptors/default-user-settings.interceptor.ts deleted file mode 100644 index 61b8049e9..000000000 --- a/src/users/interceptors/default-user-settings.interceptor.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - CallHandler, - ExecutionContext, - Injectable, - Logger, - NestInterceptor, -} from "@nestjs/common"; -import { map, Observable } from "rxjs"; -import { UsersService } from "../users.service"; -import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; -import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; - -@Injectable() -export class DefaultUserSettingsInterceptor implements NestInterceptor { - constructor(private usersService: UsersService) {} - async intercept( - context: ExecutionContext, - next: CallHandler, - ): Promise> { - return next.handle().pipe( - map(async () => { - Logger.log("DefaultUserSettingsInterceptor"); - const defaultUserSettings: UpdateUserSettingsDto = { - columns: [], - filters: FILTER_CONFIGS, - conditions: [], - }; - console.log(defaultUserSettings); - return defaultUserSettings; - }), - ); - } -} diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index 9cfe2cae2..59f4aea5a 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -2,7 +2,6 @@ import * as mongoose from "mongoose"; import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; import { ApiProperty } from "@nestjs/swagger"; import { Document } from "mongoose"; -import filterConfigs from "../../config/default-filters.config.json"; export type UserSettingsDocument = UserSettings & Document; @@ -31,8 +30,6 @@ export interface ScientificCondition { operator: string; } -export const FILTER_CONFIGS: FilterConfig[] = filterConfigs as FilterConfig[]; - @Schema({ collection: "UserSetting", toJSON: { @@ -74,12 +71,12 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: FILTER_CONFIGS, + default: [], description: "Array of filters the user has set", }) @Prop({ type: [{ type: Object }], - default: FILTER_CONFIGS, + default: [], }) filters: FilterConfig[]; diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 1e1dcceed..d894ef955 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -7,12 +7,10 @@ import { Req, Patch, Delete, - UseInterceptors, Put, Body, ForbiddenException, HttpCode, - CanActivate, } from "@nestjs/common"; import { ApiBearerAuth, @@ -32,12 +30,8 @@ import { Request } from "express"; import { JWTUser } from "../auth/interfaces/jwt-user.interface"; import { UserSettings } from "./schemas/user-settings.schema"; import { CreateUserSettingsDto } from "./dto/create-user-settings.dto"; -import { - PartialUpdateUserSettingsDto, - UpdateUserSettingsDto, -} from "./dto/update-user-settings.dto"; +import { PartialUpdateUserSettingsDto } from "./dto/update-user-settings.dto"; import { User } from "./schemas/user.schema"; -import { CreateUserSettingsInterceptor } from "./interceptors/create-user-settings.interceptor"; import { AuthService } from "src/auth/auth.service"; import { CredentialsDto } from "src/auth/dto/credentials.dto"; import { LocalAuthGuard } from "src/auth/guards/local-auth.guard"; @@ -49,7 +43,6 @@ import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; import { PoliciesGuard } from "src/casl/guards/policies.guard"; -import { DefaultUserSettingsInterceptor } from "./interceptors/default-user-settings.interceptor"; @ApiBearerAuth() @ApiTags("users") @@ -122,7 +115,6 @@ export class UsersController { @CheckPolicies("users", (ability: AppAbility) => ability.can(Action.UserReadOwn, User), ) - @UseInterceptors(CreateUserSettingsInterceptor) @Get("/my/self") @ApiOperation({ summary: "Returns the information of the user currently logged in.", @@ -184,7 +176,6 @@ export class UsersController { ability.can(Action.UserReadOwn, User) || ability.can(Action.UserReadAny, User), ) - @UseInterceptors(CreateUserSettingsInterceptor) @Get("/:id") async findById( @Req() request: Request, @@ -327,22 +318,6 @@ export class UsersController { return this.usersService.findOneAndDeleteUserSettings(id); } - @UseInterceptors(DefaultUserSettingsInterceptor) - @UseGuards( - class ByPassAuthenticatedPoliciesGuard - extends PoliciesGuard - implements CanActivate - { - async canActivate(): Promise { - return Promise.resolve(true); - } - }, - ) - @Get("/settings/default") - async getDefaultSettings(): Promise { - return Promise.resolve(new UserSettings()); - } - @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies("users", (ability: AppAbility) => { return ( From 8e1903a7ab897189d92908b7c43440a04d9975a1 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 09:42:25 +0200 Subject: [PATCH 221/258] refactor: separate search UI logic from frontend --- src/config/frontend.config.json | 190 +++++++++++----------- src/users/schemas/user-settings.schema.ts | 32 ++-- src/users/users.controller.ts | 1 - src/users/users.service.ts | 40 ++++- 4 files changed, 152 insertions(+), 111 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 5dc093125..437e0a8cd 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -27,86 +27,6 @@ "jupyterHubUrl": "", "landingPage": "doi.ess.eu/detail/", "lbBaseURL": "http://127.0.0.1:3000", - "localColumns": [ - { - "name": "select", - "order": 0, - "type": "standard", - "enabled": true - }, - { - "name": "pid", - "order": 1, - "type": "standard", - "enabled": true - }, - { - "name": "datasetName", - "order": 2, - "type": "standard", - "enabled": true - }, - { - "name": "runNumber", - "order": 3, - "type": "standard", - "enabled": true - }, - { - "name": "sourceFolder", - "order": 4, - "type": "standard", - "enabled": true - }, - { - "name": "size", - "order": 5, - "type": "standard", - "enabled": true - }, - { - "name": "creationTime", - "order": 6, - "type": "standard", - "enabled": true - }, - { - "name": "type", - "order": 7, - "type": "standard", - "enabled": true - }, - { - "name": "image", - "order": 8, - "type": "standard", - "enabled": true - }, - { - "name": "metadata", - "order": 9, - "type": "standard", - "enabled": false - }, - { - "name": "proposalId", - "order": 10, - "type": "standard", - "enabled": true - }, - { - "name": "ownerGroup", - "order": 11, - "type": "standard", - "enabled": false - }, - { - "name": "dataStatus", - "order": 12, - "type": "standard", - "enabled": false - } - ], "logbookEnabled": true, "loginFormEnabled": true, "maxDirectDownloadSize": 5000000000, @@ -181,18 +101,106 @@ "authorization": ["#datasetAccess", "#datasetPublic"] } ], - "defaultSearchInterfaceSettings": { - "columns": [], + "labelMaps": { + "filters": { + "LocationFilter": "asdasd", + "PidFilter": "asdasdsad identifiler", + "GroupFilter": "fff", + "TypeFilter": "Typfggge", + "KeywordFilter": "ggg", + "DateRangeFilter": "Start Date - End Date", + "TextFilter": "Text" + } + }, + "defaultDatasetsListSettings": { + "columns": [ + { + "name": "select", + "order": 0, + "type": "standard", + "enabled": true + }, + { + "name": "pid", + "order": 1, + "type": "standard", + "enabled": true + }, + { + "name": "datasetName", + "order": 2, + "type": "standard", + "enabled": true + }, + { + "name": "runNumber", + "order": 3, + "type": "standard", + "enabled": true + }, + { + "name": "sourceFolder", + "order": 4, + "type": "standard", + "enabled": true + }, + { + "name": "size", + "order": 5, + "type": "standard", + "enabled": true + }, + { + "name": "creationTime", + "order": 6, + "type": "standard", + "enabled": true + }, + { + "name": "type", + "order": 7, + "type": "standard", + "enabled": true + }, + { + "name": "image", + "order": 8, + "type": "standard", + "enabled": true + }, + { + "name": "metadata", + "order": 9, + "type": "standard", + "enabled": false + }, + { + "name": "proposalId", + "order": 10, + "type": "standard", + "enabled": true + }, + { + "name": "ownerGroup", + "order": 11, + "type": "standard", + "enabled": false + }, + { + "name": "dataStatus", + "order": 12, + "type": "standard", + "enabled": false + } + ], "filters": [ - { "type": "LocationFilterComponent", "visible": true }, - { "type": "PidFilterComponent", "visible": true }, - { "type": "PidFilterContainsComponent", "visible": false }, - { "type": "PidFilterStartsWithComponent", "visible": false }, - { "type": "GroupFilterComponent", "visible": true }, - { "type": "TypeFilterComponent", "visible": true }, - { "type": "KeywordFilterComponent", "visible": true }, - { "type": "DateRangeFilterComponent", "visible": true }, - { "type": "TextFilterComponent", "visible": true } + { "LocationFilter": true }, + { "PidFilter": true }, + { "GroupFilter": true }, + { "TypeFilter": true }, + { "KeywordFilter": true }, + { "DateRangeFilter": true }, + { "TextFilter": true } ], "conditions": [] } diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index 59f4aea5a..ad9d9b564 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -5,24 +5,24 @@ import { Document } from "mongoose"; export type UserSettingsDocument = UserSettings & Document; -// Define possible filter component types as a union of string literals -export type FilterComponentType = - | "LocationFilterComponent" - | "PidFilterComponent" - | "PidFilterContainsComponent" - | "PidFilterStartsWithComponent" - | "GroupFilterComponent" - | "TypeFilterComponent" - | "KeywordFilterComponent" - | "DateRangeFilterComponent" - | "TextFilterComponent"; - -// Define the Filter interface -export interface FilterConfig { - type: FilterComponentType; - visible: boolean; +// NOTE: PidFilterContains and PidFilterStartsWith filters are not implemented +export enum FilterComponentType { + LocationFilter = "LocationFilter", + PidFilter = "PidFilter", + PidFilterContains = "PidFilterContains", + PidFilterStartsWith = "PidFilterStartsWith", + GroupFilter = "GroupFilter", + TypeFilter = "TypeFilter", + KeywordFilter = "KeywordFilter", + DateRangeFilter = "DateRangeFilter", + TextFilter = "TextFilter", } +// NOTE: The key is one of FilterComponentType, and the value is a string +export type FilterConfig = Partial<{ + [K in FilterComponentType]: boolean; +}>; + // Define the Condition interface export interface ScientificCondition { field: string; diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index d894ef955..687ae6544 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -42,7 +42,6 @@ import { CreateCustomJwt } from "./dto/create-custom-jwt.dto"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; -import { PoliciesGuard } from "src/casl/guards/policies.guard"; @ApiBearerAuth() @ApiTags("users") diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 7369730d7..09c5fab21 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -18,6 +18,7 @@ import { JwtService, JwtSignOptions } from "@nestjs/jwt"; import { JWTUser } from "../auth/interfaces/jwt-user.interface"; import * as fs from "fs"; import { + FilterComponentType, UserSettings, UserSettingsDocument, } from "./schemas/user-settings.schema"; @@ -273,16 +274,39 @@ export class UsersService implements OnModuleInit { } async findByIdUserSettings(userId: string): Promise { - return this.userSettingsModel.findOne({ userId }).exec(); + const result = await this.userSettingsModel.findOne({ userId }).exec(); + + if (!result) { + return null; + } + + // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. + // If not, reset the user settings to maintain consistency. + const validFilters = result.filters.some((filter) => { + const [key, value] = Object.entries(filter)[0]; + return this.isValidFilterComponentType(key, value); + }); + + if (!validFilters) { + return this.findOneAndUpdateUserSettings(userId, { filters: [] }); + } + + return result; } async findOneAndUpdateUserSettings( userId: string, updateUserSettingsDto: UpdateUserSettingsDto | PartialUpdateUserSettingsDto, ): Promise { - return this.userSettingsModel - .findOneAndUpdate({ userId }, updateUserSettingsDto, { new: true }) + const result = await this.userSettingsModel + .findOneAndUpdate({ userId }, updateUserSettingsDto, { + new: true, + upsert: true, + setDefaultsOnInsert: true, + }) .exec(); + + return result; } async findOneAndDeleteUserSettings(userId: string): Promise { @@ -339,4 +363,14 @@ export class UsersService implements OnModuleInit { const jwtString = this.jwtService.sign(user, signAndVerifyOptions); return { jwt: jwtString }; } + + private isValidFilterComponentType( + key: string, + value: unknown, + ): key is FilterComponentType { + return ( + Object.keys(FilterComponentType).includes(key) && + typeof value === "boolean" + ); + } } From e0ec9f273f06b51ad3f77c74b6b700647804fc3a Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 10:34:50 +0200 Subject: [PATCH 222/258] fix for failing test --- src/users/users.service.ts | 14 ++++++++------ test/UserAuthorization.js | 12 ++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 09c5fab21..fdc7cf9f4 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -276,19 +276,21 @@ export class UsersService implements OnModuleInit { async findByIdUserSettings(userId: string): Promise { const result = await this.userSettingsModel.findOne({ userId }).exec(); - if (!result) { - return null; - } - // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. // If not, reset the user settings to maintain consistency. - const validFilters = result.filters.some((filter) => { + const validFilters = result?.filters.some((filter) => { const [key, value] = Object.entries(filter)[0]; return this.isValidFilterComponentType(key, value); }); if (!validFilters) { - return this.findOneAndUpdateUserSettings(userId, { filters: [] }); + const updatedUsersFilter = await this.findOneAndUpdateUserSettings( + userId, + { + filters: [], + }, + ); + return updatedUsersFilter; } return result; diff --git a/test/UserAuthorization.js b/test/UserAuthorization.js index a8fb227f0..012b09d1f 100644 --- a/test/UserAuthorization.js +++ b/test/UserAuthorization.js @@ -21,7 +21,7 @@ let accessTokenAdminIngestor = null, userIdArchiveManager = null; describe("2300: User Authorization: test that user authorization are correct", () => { - beforeEach(async() => { + beforeEach(async () => { const loginResponseIngestor = await utils.getIdAndToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -34,7 +34,7 @@ describe("2300: User Authorization: test that user authorization are correct", ( password: TestData.Accounts["user1"]["password"], }); userIdUser1 = loginResponseUser1.userId; - accessTokenUser1 = loginResponseUser1.token; + accessTokenUser1 = loginResponseUser1.token; const loginResponseUser2 = await utils.getIdAndToken(appUrl, { username: "user2", @@ -47,8 +47,8 @@ describe("2300: User Authorization: test that user authorization are correct", ( username: "user3", password: TestData.Accounts["user3"]["password"], }); - userIdUser3 = loginResponseUser3.userId - accessTokenUser3 = loginResponseUser3.token + userIdUser3 = loginResponseUser3.userId; + accessTokenUser3 = loginResponseUser3.token; const loginResponseUser4 = await utils.getIdAndToken(appUrl, { username: "user4", @@ -56,7 +56,7 @@ describe("2300: User Authorization: test that user authorization are correct", ( }); userIdUser4 = loginResponseUser4.userId; accessTokenUser4 = loginResponseUser4.token; - + const loginResponseAdmin = await utils.getIdAndToken(appUrl, { username: "admin", password: TestData.Accounts["admin"]["password"], @@ -71,7 +71,7 @@ describe("2300: User Authorization: test that user authorization are correct", ( userIdArchiveManager = loginResponseArchiveManager.userId; accessTokenArchiveManager = loginResponseArchiveManager.token; }); - + afterEach((done) => { sandbox.restore(); done(); From d6a1d71c71ad674efa077f751cf463e128df39be Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 10:44:59 +0200 Subject: [PATCH 223/258] fix default filter labelmaps --- src/config/frontend.config.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index 437e0a8cd..cb9c5394f 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -103,11 +103,11 @@ ], "labelMaps": { "filters": { - "LocationFilter": "asdasd", - "PidFilter": "asdasdsad identifiler", - "GroupFilter": "fff", - "TypeFilter": "Typfggge", - "KeywordFilter": "ggg", + "LocationFilter": "Location", + "PidFilter": "Pid", + "GroupFilter": "Group", + "TypeFilter": "Type", + "KeywordFilter": "Keyword", "DateRangeFilter": "Start Date - End Date", "TextFilter": "Text" } From 4ea9ff3dbadf6509a27d70c48a1efa8481fe0125 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 11:12:55 +0200 Subject: [PATCH 224/258] minor fixes --- src/users/schemas/user-settings.schema.ts | 2 +- src/users/users.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index ad9d9b564..25703460c 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -18,7 +18,7 @@ export enum FilterComponentType { TextFilter = "TextFilter", } -// NOTE: The key is one of FilterComponentType, and the value is a string +// NOTE: The key is one of FilterComponentType export type FilterConfig = Partial<{ [K in FilterComponentType]: boolean; }>; diff --git a/src/users/users.service.ts b/src/users/users.service.ts index fdc7cf9f4..9b60d7faf 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -283,7 +283,7 @@ export class UsersService implements OnModuleInit { return this.isValidFilterComponentType(key, value); }); - if (!validFilters) { + if (result && !validFilters) { const updatedUsersFilter = await this.findOneAndUpdateUserSettings( userId, { From c32b2165c41ccb5745876a582b00f0368278bfd5 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 14:23:41 +0200 Subject: [PATCH 225/258] revert user settings interceptor and added reset user setting function --- .../interceptors/user-settings.interceptor.ts | 93 +++++++++++++++++++ src/users/users.controller.ts | 3 + src/users/users.service.ts | 32 +------ 3 files changed, 100 insertions(+), 28 deletions(-) create mode 100644 src/users/interceptors/user-settings.interceptor.ts diff --git a/src/users/interceptors/user-settings.interceptor.ts b/src/users/interceptors/user-settings.interceptor.ts new file mode 100644 index 000000000..fbdba49bc --- /dev/null +++ b/src/users/interceptors/user-settings.interceptor.ts @@ -0,0 +1,93 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + Logger, + NestInterceptor, +} from "@nestjs/common"; +import { Observable, tap } from "rxjs"; +import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; +import { UsersService } from "../users.service"; +import { + FilterComponentType, + UserSettings, +} from "../schemas/user-settings.schema"; +import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; + +@Injectable() +export class UserSettingsInterceptor implements NestInterceptor { + constructor(private usersService: UsersService) {} + async intercept( + context: ExecutionContext, + next: CallHandler, + ): Promise> { + return next.handle().pipe( + tap(async () => { + const res = context.switchToHttp().getResponse(); + const user = res.req.user; + if (!user) { + return; + } + const userId = user._id; + const userSettings = + await this.usersService.findByIdUserSettings(userId); + if (!userSettings) { + Logger.log( + `Adding default settings to user ${user.username}`, + "UserSettingsInterceptor", + ); + const createUserSettingsDto: CreateUserSettingsDto = { + userId, + filters: [], + conditions: [], + columns: [], + }; + return this.usersService.createUserSettings( + userId, + createUserSettingsDto, + ); + } else { + const isValidFilters = this.isValidFilterComponentType(userSettings); + + if (!isValidFilters) { + Logger.log( + `Reset default settings to user ${user.username}`, + "UserSettingsInterceptor", + ); + return await this.resetUserSettings(userId, userSettings); + } + } + + return; + }), + ); + } + + private async resetUserSettings(userId: string, userSettings: UserSettings) { + // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. + // If not, reset the user settings to maintain consistency. + const updateUserSettingsDto: UpdateUserSettingsDto = { + ...userSettings, + filters: [], + }; + const updatedUsersFilter = + await this.usersService.findOneAndUpdateUserSettings( + userId, + updateUserSettingsDto, + ); + return updatedUsersFilter; + } + + private isValidFilterComponentType(userSettings: UserSettings): boolean { + if (userSettings.filters.length === 0) { + return true; + } + return userSettings.filters.every((filter) => { + const [key, value] = Object.entries(filter)[0]; + return ( + Object.keys(FilterComponentType).includes(key) && + typeof value === "boolean" + ); + }); + } +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 687ae6544..170fe20d3 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -11,6 +11,7 @@ import { Body, ForbiddenException, HttpCode, + UseInterceptors, } from "@nestjs/common"; import { ApiBearerAuth, @@ -42,6 +43,7 @@ import { CreateCustomJwt } from "./dto/create-custom-jwt.dto"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; +import { UserSettingsInterceptor } from "./interceptors/user-settings.interceptor"; @ApiBearerAuth() @ApiTags("users") @@ -230,6 +232,7 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) + @UseInterceptors(UserSettingsInterceptor) @CheckPolicies( "users", (ability: AppAbility) => diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 9b60d7faf..639385517 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -274,24 +274,10 @@ export class UsersService implements OnModuleInit { } async findByIdUserSettings(userId: string): Promise { - const result = await this.userSettingsModel.findOne({ userId }).exec(); - - // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. - // If not, reset the user settings to maintain consistency. - const validFilters = result?.filters.some((filter) => { - const [key, value] = Object.entries(filter)[0]; - return this.isValidFilterComponentType(key, value); - }); - - if (result && !validFilters) { - const updatedUsersFilter = await this.findOneAndUpdateUserSettings( - userId, - { - filters: [], - }, - ); - return updatedUsersFilter; - } + const result = await this.userSettingsModel + .findOne({ userId }) + .lean() + .exec(); return result; } @@ -365,14 +351,4 @@ export class UsersService implements OnModuleInit { const jwtString = this.jwtService.sign(user, signAndVerifyOptions); return { jwt: jwtString }; } - - private isValidFilterComponentType( - key: string, - value: unknown, - ): key is FilterComponentType { - return ( - Object.keys(FilterComponentType).includes(key) && - typeof value === "boolean" - ); - } } From e476c409acfe4b1a97420f9b8ab724528930f9c2 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 5 Sep 2024 15:18:01 +0200 Subject: [PATCH 226/258] changed tap to swtichMap for asynchronous events for user-settings interceptor. moved user-settings interceptor to login endpoint --- .../interceptors/user-settings.interceptor.ts | 34 +++++++++---------- src/users/users.controller.ts | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/users/interceptors/user-settings.interceptor.ts b/src/users/interceptors/user-settings.interceptor.ts index fbdba49bc..1f5426e14 100644 --- a/src/users/interceptors/user-settings.interceptor.ts +++ b/src/users/interceptors/user-settings.interceptor.ts @@ -5,7 +5,7 @@ import { Logger, NestInterceptor, } from "@nestjs/common"; -import { Observable, tap } from "rxjs"; +import { Observable, switchMap } from "rxjs"; import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; import { UsersService } from "../users.service"; import { @@ -17,20 +17,22 @@ import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; @Injectable() export class UserSettingsInterceptor implements NestInterceptor { constructor(private usersService: UsersService) {} - async intercept( - context: ExecutionContext, - next: CallHandler, - ): Promise> { + + intercept(context: ExecutionContext, next: CallHandler): Observable { + const res = context.switchToHttp().getResponse(); + const user = res.req.user; + + if (!user) { + return next.handle(); + } + + const userId = user._id; + return next.handle().pipe( - tap(async () => { - const res = context.switchToHttp().getResponse(); - const user = res.req.user; - if (!user) { - return; - } - const userId = user._id; + switchMap(async (payload) => { const userSettings = await this.usersService.findByIdUserSettings(userId); + if (!userSettings) { Logger.log( `Adding default settings to user ${user.username}`, @@ -42,7 +44,7 @@ export class UserSettingsInterceptor implements NestInterceptor { conditions: [], columns: [], }; - return this.usersService.createUserSettings( + await this.usersService.createUserSettings( userId, createUserSettingsDto, ); @@ -54,15 +56,13 @@ export class UserSettingsInterceptor implements NestInterceptor { `Reset default settings to user ${user.username}`, "UserSettingsInterceptor", ); - return await this.resetUserSettings(userId, userSettings); + await this.resetUserSettings(userId, userSettings); } } - - return; + return payload; }), ); } - private async resetUserSettings(userId: string, userSettings: UserSettings) { // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. // If not, reset the user settings to maintain consistency. diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 170fe20d3..142dff0f4 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -94,6 +94,7 @@ export class UsersController { @ApiBody({ type: CredentialsDto }) @AllowAny() + @UseInterceptors(UserSettingsInterceptor) @UseGuards(LocalAuthGuard) @Post("login") @ApiOperation({ @@ -232,7 +233,6 @@ export class UsersController { } @UseGuards(AuthenticatedPoliciesGuard) - @UseInterceptors(UserSettingsInterceptor) @CheckPolicies( "users", (ability: AppAbility) => From f0afcaa409c9a740a59eb5a4e134b2a4b0c24b50 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 16 Sep 2024 13:15:36 +0200 Subject: [PATCH 227/258] refactor(auth): implement post-login tasks for user settings management and remove UserSettingsInterceptor --- src/auth/auth.service.ts | 65 +++++++++++++ src/config/frontend.config.json | 2 +- .../interceptors/user-settings.interceptor.ts | 93 ------------------- src/users/users.controller.spec.ts | 58 +++++++----- src/users/users.controller.ts | 17 ++-- 5 files changed, 106 insertions(+), 129 deletions(-) delete mode 100644 src/users/interceptors/user-settings.interceptor.ts diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 3ee2933ae..c36dde925 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -10,6 +10,12 @@ import { flattenObject, parseBoolean } from "src/common/utils"; import { Issuer } from "openid-client"; import { ReturnedAuthLoginDto } from "./dto/returnedLogin.dto"; import { ReturnedUserDto } from "src/users/dto/returned-user.dto"; +import { CreateUserSettingsDto } from "src/users/dto/create-user-settings.dto"; +import { + FilterComponentType, + UserSettings, +} from "src/users/schemas/user-settings.schema"; +import { UpdateUserSettingsDto } from "src/users/dto/update-user-settings.dto"; @Injectable() export class AuthService { @@ -43,6 +49,7 @@ export class AuthService { async login(user: Omit): Promise { const expiresIn = this.configService.get("jwt.expiresIn"); const accessToken = this.jwtService.sign(user, { expiresIn }); + await this.postLoginTasks(user); return { access_token: accessToken, id: accessToken, @@ -122,4 +129,62 @@ export class AuthService { return { logout: "successful" }; } + /** + * postLoginTasks: Executes additional tasks after user login. + * + * - Checks if the user has userSettings record. + * - If user has no userSetting, it creates default userSetting for the user. + * - If userSetting exist but are invalid (filters does not belong to FilterComponentType), it resets the filters to default - empty array. + * + * @param user - The logged-in user (without password). + */ + async postLoginTasks(user: Omit) { + if (!user) return; + + const userId = user._id; + + const userSettings = await this.usersService.findByIdUserSettings(userId); + + if (!userSettings) { + Logger.log( + `Adding default settings to user ${user.username}`, + "UserSettingsInterceptor", + ); + const createUserSettingsDto: CreateUserSettingsDto = { + userId, + filters: [], + conditions: [], + columns: [], + }; + await this.usersService.createUserSettings(userId, createUserSettingsDto); + } else { + const isValidFilters = (userSettings: UserSettings): boolean => { + if (userSettings.filters.length === 0) { + return true; + } + return userSettings.filters.every((filter) => { + const [key, value] = Object.entries(filter)[0]; + return ( + Object.keys(FilterComponentType).includes(key) && + typeof value === "boolean" + ); + }); + }; + + if (!isValidFilters) { + Logger.log( + `Reset default settings to user ${user.username}`, + "UserSettingsInterceptor", + ); + const updateUserSettingsDto: UpdateUserSettingsDto = { + ...userSettings, + filters: [], + }; + await this.usersService.findOneAndUpdateUserSettings( + userId, + updateUserSettingsDto, + ); + } + } + } } diff --git a/src/config/frontend.config.json b/src/config/frontend.config.json index cb9c5394f..213c69a5e 100644 --- a/src/config/frontend.config.json +++ b/src/config/frontend.config.json @@ -26,7 +26,7 @@ "jsonMetadataEnabled": true, "jupyterHubUrl": "", "landingPage": "doi.ess.eu/detail/", - "lbBaseURL": "http://127.0.0.1:3000", + "lbBaseURL": "http://localhost:3000", "logbookEnabled": true, "loginFormEnabled": true, "maxDirectDownloadSize": 5000000000, diff --git a/src/users/interceptors/user-settings.interceptor.ts b/src/users/interceptors/user-settings.interceptor.ts deleted file mode 100644 index 1f5426e14..000000000 --- a/src/users/interceptors/user-settings.interceptor.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { - CallHandler, - ExecutionContext, - Injectable, - Logger, - NestInterceptor, -} from "@nestjs/common"; -import { Observable, switchMap } from "rxjs"; -import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; -import { UsersService } from "../users.service"; -import { - FilterComponentType, - UserSettings, -} from "../schemas/user-settings.schema"; -import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; - -@Injectable() -export class UserSettingsInterceptor implements NestInterceptor { - constructor(private usersService: UsersService) {} - - intercept(context: ExecutionContext, next: CallHandler): Observable { - const res = context.switchToHttp().getResponse(); - const user = res.req.user; - - if (!user) { - return next.handle(); - } - - const userId = user._id; - - return next.handle().pipe( - switchMap(async (payload) => { - const userSettings = - await this.usersService.findByIdUserSettings(userId); - - if (!userSettings) { - Logger.log( - `Adding default settings to user ${user.username}`, - "UserSettingsInterceptor", - ); - const createUserSettingsDto: CreateUserSettingsDto = { - userId, - filters: [], - conditions: [], - columns: [], - }; - await this.usersService.createUserSettings( - userId, - createUserSettingsDto, - ); - } else { - const isValidFilters = this.isValidFilterComponentType(userSettings); - - if (!isValidFilters) { - Logger.log( - `Reset default settings to user ${user.username}`, - "UserSettingsInterceptor", - ); - await this.resetUserSettings(userId, userSettings); - } - } - return payload; - }), - ); - } - private async resetUserSettings(userId: string, userSettings: UserSettings) { - // NOTE: The extra functions ensure filters in user setting record match the FilterComponentType format. - // If not, reset the user settings to maintain consistency. - const updateUserSettingsDto: UpdateUserSettingsDto = { - ...userSettings, - filters: [], - }; - const updatedUsersFilter = - await this.usersService.findOneAndUpdateUserSettings( - userId, - updateUserSettingsDto, - ); - return updatedUsersFilter; - } - - private isValidFilterComponentType(userSettings: UserSettings): boolean { - if (userSettings.filters.length === 0) { - return true; - } - return userSettings.filters.every((filter) => { - const [key, value] = Object.entries(filter)[0]; - return ( - Object.keys(FilterComponentType).includes(key) && - typeof value === "boolean" - ); - }); - } -} diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 6bedb6203..1d8f16b33 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -4,6 +4,7 @@ import { CaslModule } from "src/casl/casl.module"; import { UsersController } from "./users.controller"; import { UsersService } from "./users.service"; import { UpdateUserSettingsDto } from "./dto/update-user-settings.dto"; +import { Request } from "express"; class UsersServiceMock { findByIdUserIdentity(id: string) { @@ -28,10 +29,7 @@ const mockUserSettings = { columns: [], datasetCount: 25, jobCount: 25, - filters: [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - ], + filters: [{ LocationFilter: true }, { PidFilter: true }], conditions: [{ field: "status", value: "active", operator: "equals" }], }; @@ -54,7 +52,6 @@ describe("UsersController", () => { controller = module.get(UsersController); usersService = module.get(UsersService); - // bypass authorization jest .spyOn(controller as UsersController, "checkUserAuthorization") .mockImplementation(() => Promise.resolve()); @@ -65,45 +62,56 @@ describe("UsersController", () => { }); it("should return user settings with filters and conditions", async () => { - jest - .spyOn(usersService, "findByIdUserSettings") - .mockResolvedValue(mockUserSettings); - const userId = "user1"; - const result = await controller.getSettings( - { user: { _id: userId } }, - userId, - ); + mockUserSettings._id = userId; + + const mockRequest: Partial = { + user: { _id: userId }, + }; + + const result = await controller.getSettings(mockRequest as Request, userId); + // Assert expect(result).toEqual(mockUserSettings); - expect(result.filters).toBeDefined(); - expect(result.filters.length).toBeGreaterThan(0); - expect(result.conditions).toBeDefined(); - expect(result.conditions.length).toBeGreaterThan(0); + expect(result?.filters).toBeDefined(); + expect(result?.filters.length).toBeGreaterThan(0); + expect(result?.conditions).toBeDefined(); + expect(result?.conditions.length).toBeGreaterThan(0); }); it("should update user settings with filters and conditions", async () => { + const userId = "user-id"; + mockUserSettings._id = userId; + const updatedSettings = { ...mockUserSettings, - filters: [{ type: "PidFilterContainsComponent", visible: false }], + filters: [{ PidFilter: true }], conditions: [{ field: "status", value: "inactive", operator: "equals" }], }; + const mockRequest: Partial = { + user: { _id: userId }, + }; + + const expectedResponse = { + ...updatedSettings, + _id: userId, + }; + jest .spyOn(usersService, "findOneAndUpdateUserSettings") - .mockResolvedValue(updatedSettings); + .mockResolvedValue(expectedResponse); - const userId = "user-id"; const result = await controller.updateSettings( - { user: { _id: userId } }, + mockRequest as Request, userId, updatedSettings, ); expect(result).toEqual(updatedSettings); - expect(result.filters).toBeDefined(); - expect(result.filters.length).toBe(1); - expect(result.conditions).toBeDefined(); - expect(result.conditions.length).toBe(1); + expect(result?.filters).toBeDefined(); + expect(result?.filters.length).toBe(1); + expect(result?.conditions).toBeDefined(); + expect(result?.conditions.length).toBe(1); }); }); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 142dff0f4..2822c28c7 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -11,7 +11,6 @@ import { Body, ForbiddenException, HttpCode, - UseInterceptors, } from "@nestjs/common"; import { ApiBearerAuth, @@ -43,7 +42,6 @@ import { CreateCustomJwt } from "./dto/create-custom-jwt.dto"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; -import { UserSettingsInterceptor } from "./interceptors/user-settings.interceptor"; @ApiBearerAuth() @ApiTags("users") @@ -94,23 +92,22 @@ export class UsersController { @ApiBody({ type: CredentialsDto }) @AllowAny() - @UseInterceptors(UserSettingsInterceptor) @UseGuards(LocalAuthGuard) @Post("login") @ApiOperation({ - summary: "Functional accounts login.", - description: "It allows to login with functional (local) accounts.", + summary: + "This endpoint is deprecated and will be removed soon. Use /auth/login instead", + description: + "This endpoint is deprecated and will be removed soon. Use /auth/login instead", }) @ApiResponse({ status: 201, type: ReturnedAuthLoginDto, description: - "Create a new JWT token for anonymous or the user that is currently logged in", + "This endpoint is deprecated and will be removed soon. Use /auth/login instead", }) - async login( - @Req() req: Record, - ): Promise { - return await this.authService.login(req.user as Omit); + async login(@Req() req: Record): Promise { + return null; } @UseGuards(AuthenticatedPoliciesGuard) From b1d47bd61fa6b15a395d5f6a6855055992b5b02c Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 16 Sep 2024 15:04:46 +0200 Subject: [PATCH 228/258] removed all user filter settings related logic --- src/auth/auth.service.ts | 35 ----------------------- src/users/dto/update-user-settings.dto.ts | 7 ++--- src/users/schemas/user-settings.schema.ts | 20 +------------ src/users/users.service.ts | 1 - 4 files changed, 3 insertions(+), 60 deletions(-) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index c36dde925..2acdbccc8 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -11,11 +11,6 @@ import { Issuer } from "openid-client"; import { ReturnedAuthLoginDto } from "./dto/returnedLogin.dto"; import { ReturnedUserDto } from "src/users/dto/returned-user.dto"; import { CreateUserSettingsDto } from "src/users/dto/create-user-settings.dto"; -import { - FilterComponentType, - UserSettings, -} from "src/users/schemas/user-settings.schema"; -import { UpdateUserSettingsDto } from "src/users/dto/update-user-settings.dto"; @Injectable() export class AuthService { @@ -134,8 +129,6 @@ export class AuthService { * * - Checks if the user has userSettings record. * - If user has no userSetting, it creates default userSetting for the user. - * - If userSetting exist but are invalid (filters does not belong to FilterComponentType), it resets the filters to default - empty array. - * * @param user - The logged-in user (without password). */ async postLoginTasks(user: Omit) { @@ -157,34 +150,6 @@ export class AuthService { columns: [], }; await this.usersService.createUserSettings(userId, createUserSettingsDto); - } else { - const isValidFilters = (userSettings: UserSettings): boolean => { - if (userSettings.filters.length === 0) { - return true; - } - return userSettings.filters.every((filter) => { - const [key, value] = Object.entries(filter)[0]; - return ( - Object.keys(FilterComponentType).includes(key) && - typeof value === "boolean" - ); - }); - }; - - if (!isValidFilters) { - Logger.log( - `Reset default settings to user ${user.username}`, - "UserSettingsInterceptor", - ); - const updateUserSettingsDto: UpdateUserSettingsDto = { - ...userSettings, - filters: [], - }; - await this.usersService.findOneAndUpdateUserSettings( - userId, - updateUserSettingsDto, - ); - } } } } diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index 8458e4e84..d0159c39b 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -1,8 +1,5 @@ import { ApiProperty, PartialType } from "@nestjs/swagger"; -import { - FilterConfig, - ScientificCondition, -} from "../schemas/user-settings.schema"; +import { ScientificCondition } from "../schemas/user-settings.schema"; import { IsArray, IsNumber } from "class-validator"; export class UpdateUserSettingsDto { @@ -20,7 +17,7 @@ export class UpdateUserSettingsDto { @ApiProperty() @IsArray() - readonly filters: FilterConfig[]; + readonly filters: Record[]; @ApiProperty() @IsArray() diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index 25703460c..b6ebf6a7d 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -5,24 +5,6 @@ import { Document } from "mongoose"; export type UserSettingsDocument = UserSettings & Document; -// NOTE: PidFilterContains and PidFilterStartsWith filters are not implemented -export enum FilterComponentType { - LocationFilter = "LocationFilter", - PidFilter = "PidFilter", - PidFilterContains = "PidFilterContains", - PidFilterStartsWith = "PidFilterStartsWith", - GroupFilter = "GroupFilter", - TypeFilter = "TypeFilter", - KeywordFilter = "KeywordFilter", - DateRangeFilter = "DateRangeFilter", - TextFilter = "TextFilter", -} - -// NOTE: The key is one of FilterComponentType -export type FilterConfig = Partial<{ - [K in FilterComponentType]: boolean; -}>; - // Define the Condition interface export interface ScientificCondition { field: string; @@ -78,7 +60,7 @@ export class UserSettings { type: [{ type: Object }], default: [], }) - filters: FilterConfig[]; + filters: Record[]; @ApiProperty({ type: [Object], diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 639385517..4c479c1b3 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -18,7 +18,6 @@ import { JwtService, JwtSignOptions } from "@nestjs/jwt"; import { JWTUser } from "../auth/interfaces/jwt-user.interface"; import * as fs from "fs"; import { - FilterComponentType, UserSettings, UserSettingsDocument, } from "./schemas/user-settings.schema"; From 53daa02b2c247a3b58da54dc0c28e6593ab83435 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Tue, 17 Sep 2024 12:31:56 +0200 Subject: [PATCH 229/258] refactor(user-settings): consolidate user settings structure and remove deprecated fields --- src/auth/auth.service.ts | 8 ++--- src/users/dto/update-user-settings.dto.ts | 22 +++++------- src/users/schemas/user-settings.schema.ts | 30 ++++------------ src/users/users.controller.spec.ts | 44 ++++++++++++++--------- 4 files changed, 46 insertions(+), 58 deletions(-) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 2acdbccc8..fa201b7b5 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -140,14 +140,12 @@ export class AuthService { if (!userSettings) { Logger.log( - `Adding default settings to user ${user.username}`, - "UserSettingsInterceptor", + `Adding default settings to user ${user.username} with userId: ${user._id}`, + "postLoginTasks", ); const createUserSettingsDto: CreateUserSettingsDto = { userId, - filters: [], - conditions: [], - columns: [], + frontendSettings: {}, }; await this.usersService.createUserSettings(userId, createUserSettingsDto); } diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index d0159c39b..a9cca316e 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -1,12 +1,7 @@ import { ApiProperty, PartialType } from "@nestjs/swagger"; -import { ScientificCondition } from "../schemas/user-settings.schema"; -import { IsArray, IsNumber } from "class-validator"; +import { IsNumber, IsObject, IsOptional } from "class-validator"; export class UpdateUserSettingsDto { - @ApiProperty() - @IsArray() - readonly columns: Record[]; - @ApiProperty({ type: Number, required: false, default: 25 }) @IsNumber() readonly datasetCount?: number; @@ -15,13 +10,14 @@ export class UpdateUserSettingsDto { @IsNumber() readonly jobCount?: number; - @ApiProperty() - @IsArray() - readonly filters: Record[]; - - @ApiProperty() - @IsArray() - readonly conditions: ScientificCondition[]; + @ApiProperty({ + type: "object", + additionalProperties: { type: "array", items: {} }, + required: false, + }) + @IsOptional() + @IsObject() + readonly frontendSettings?: Record; } export class PartialUpdateUserSettingsDto extends PartialType( diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index b6ebf6a7d..9a629abe7 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -23,14 +23,6 @@ export class UserSettings { id?: string; - @ApiProperty({ - type: [Object], - default: [], - description: "Array of the users preferred columns in dataset table", - }) - @Prop({ type: [Object], default: [] }) - columns: Record[]; - @ApiProperty({ type: Number, default: 25, @@ -52,23 +44,13 @@ export class UserSettings { userId: string; @ApiProperty({ - type: [Object], - default: [], - description: "Array of filters the user has set", - }) - @Prop({ - type: [{ type: Object }], - default: [], - }) - filters: Record[]; - - @ApiProperty({ - type: [Object], - default: [], - description: "Array of conditions the user has set", + type: "object", + additionalProperties: { type: "array", items: {} }, + default: {}, + description: "users preferred ui settings in dataset table", }) - @Prop({ type: [{ type: Object }], default: [] }) - conditions: ScientificCondition[]; + @Prop({ type: Object, default: {}, required: false }) + frontendSettings?: Record; } export const UserSettingsSchema = SchemaFactory.createForClass(UserSettings); diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 1d8f16b33..580e154cb 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -5,6 +5,7 @@ import { UsersController } from "./users.controller"; import { UsersService } from "./users.service"; import { UpdateUserSettingsDto } from "./dto/update-user-settings.dto"; import { Request } from "express"; +import { UserSettings } from "./schemas/user-settings.schema"; class UsersServiceMock { findByIdUserIdentity(id: string) { @@ -26,11 +27,13 @@ class UsersServiceMock { const mockUserSettings = { _id: "user1", userId: "user1", - columns: [], datasetCount: 25, jobCount: 25, - filters: [{ LocationFilter: true }, { PidFilter: true }], - conditions: [{ field: "status", value: "active", operator: "equals" }], + frontendSettings: { + filters: [{ LocationFilter: true }, { PidFilter: true }], + conditions: [{ field: "status", value: "active", operator: "equals" }], + columns: [], + }, }; class AuthServiceMock {} @@ -72,11 +75,11 @@ describe("UsersController", () => { const result = await controller.getSettings(mockRequest as Request, userId); // Assert - expect(result).toEqual(mockUserSettings); - expect(result?.filters).toBeDefined(); - expect(result?.filters.length).toBeGreaterThan(0); - expect(result?.conditions).toBeDefined(); - expect(result?.conditions.length).toBeGreaterThan(0); + expect(result?.frontendSettings).toEqual(mockUserSettings); + expect(result?.frontendSettings?.filters).toBeDefined(); + expect(result?.frontendSettings?.filters.length).toBeGreaterThan(0); + expect(result?.frontendSettings?.conditions).toBeDefined(); + expect(result?.frontendSettings?.conditions.length).toBeGreaterThan(0); }); it("should update user settings with filters and conditions", async () => { @@ -85,17 +88,26 @@ describe("UsersController", () => { const updatedSettings = { ...mockUserSettings, - filters: [{ PidFilter: true }], - conditions: [{ field: "status", value: "inactive", operator: "equals" }], + frontendSettings: { + filters: [{ PidFilter: true }], + conditions: [ + { field: "status", value: "inactive", operator: "equals" }, + ], + columns: [], + }, }; const mockRequest: Partial = { user: { _id: userId }, }; - const expectedResponse = { + const expectedResponse: UserSettings = { ...updatedSettings, _id: userId, + userId: userId, // Ensure all required properties are included + datasetCount: updatedSettings.datasetCount, + jobCount: updatedSettings.jobCount, + frontendSettings: updatedSettings.frontendSettings, }; jest @@ -108,10 +120,10 @@ describe("UsersController", () => { updatedSettings, ); - expect(result).toEqual(updatedSettings); - expect(result?.filters).toBeDefined(); - expect(result?.filters.length).toBe(1); - expect(result?.conditions).toBeDefined(); - expect(result?.conditions.length).toBe(1); + expect(result?.frontendSettings).toEqual(updatedSettings); + expect(result?.frontendSettings?.filters).toBeDefined(); + expect(result?.frontendSettings?.filters.length).toBe(1); + expect(result?.frontendSettings?.conditions).toBeDefined(); + expect(result?.frontendSettings?.conditions.length).toBe(1); }); }); From 0e73c70f29bd36b7c558b2705d7b1f8a0b074be5 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Sep 2024 14:48:44 +0200 Subject: [PATCH 230/258] refactor(user-settings): update user settings structure and remove deprecated fields This commit refactors the user settings structure by updating the field names and removing deprecated fields. The `frontendSettings` field has been renamed to `externalSettings` to better reflect its purpose. Additionally, the deprecated fields have been removed from the user settings schema. --- src/auth/auth.service.ts | 2 +- src/users/dto/update-user-settings.dto.ts | 6 ++-- src/users/schemas/user-settings.schema.ts | 6 ++-- src/users/users.controller.spec.ts | 35 ++++++++++++++--------- src/users/users.controller.ts | 28 ++++++++++++++++-- src/users/users.service.ts | 28 ++++++++++++++++++ 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index fa201b7b5..4d77c2461 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -145,7 +145,7 @@ export class AuthService { ); const createUserSettingsDto: CreateUserSettingsDto = { userId, - frontendSettings: {}, + externalSettings: {}, }; await this.usersService.createUserSettings(userId, createUserSettingsDto); } diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index a9cca316e..63794c6ea 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -11,13 +11,13 @@ export class UpdateUserSettingsDto { readonly jobCount?: number; @ApiProperty({ - type: "object", - additionalProperties: { type: "array", items: {} }, + type: Object, required: false, + default: {}, }) @IsOptional() @IsObject() - readonly frontendSettings?: Record; + readonly externalSettings?: Record; } export class PartialUpdateUserSettingsDto extends PartialType( diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index 9a629abe7..9aa9a9f08 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -45,12 +45,12 @@ export class UserSettings { @ApiProperty({ type: "object", - additionalProperties: { type: "array", items: {} }, default: {}, - description: "users preferred ui settings in dataset table", + description: + "A customizable object for storing the user's external settings, which can contain various nested properties and configurations.", }) @Prop({ type: Object, default: {}, required: false }) - frontendSettings?: Record; + externalSettings?: Record; } export const UserSettingsSchema = SchemaFactory.createForClass(UserSettings); diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 580e154cb..40ac85311 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -29,7 +29,7 @@ const mockUserSettings = { userId: "user1", datasetCount: 25, jobCount: 25, - frontendSettings: { + externalSettings: { filters: [{ LocationFilter: true }, { PidFilter: true }], conditions: [{ field: "status", value: "active", operator: "equals" }], columns: [], @@ -75,11 +75,15 @@ describe("UsersController", () => { const result = await controller.getSettings(mockRequest as Request, userId); // Assert - expect(result?.frontendSettings).toEqual(mockUserSettings); - expect(result?.frontendSettings?.filters).toBeDefined(); - expect(result?.frontendSettings?.filters.length).toBeGreaterThan(0); - expect(result?.frontendSettings?.conditions).toBeDefined(); - expect(result?.frontendSettings?.conditions.length).toBeGreaterThan(0); + expect(result?.externalSettings).toEqual(mockUserSettings); + expect(result?.externalSettings?.filters).toBeDefined(); + expect( + (result?.externalSettings?.filters as Record).length, + ).toBeGreaterThan(0); + expect(result?.externalSettings?.conditions).toBeDefined(); + expect( + (result?.externalSettings?.conditions as Record).length, + ).toBeGreaterThan(0); }); it("should update user settings with filters and conditions", async () => { @@ -88,7 +92,7 @@ describe("UsersController", () => { const updatedSettings = { ...mockUserSettings, - frontendSettings: { + externalSettings: { filters: [{ PidFilter: true }], conditions: [ { field: "status", value: "inactive", operator: "equals" }, @@ -107,7 +111,7 @@ describe("UsersController", () => { userId: userId, // Ensure all required properties are included datasetCount: updatedSettings.datasetCount, jobCount: updatedSettings.jobCount, - frontendSettings: updatedSettings.frontendSettings, + externalSettings: updatedSettings.externalSettings, }; jest @@ -120,10 +124,15 @@ describe("UsersController", () => { updatedSettings, ); - expect(result?.frontendSettings).toEqual(updatedSettings); - expect(result?.frontendSettings?.filters).toBeDefined(); - expect(result?.frontendSettings?.filters.length).toBe(1); - expect(result?.frontendSettings?.conditions).toBeDefined(); - expect(result?.frontendSettings?.conditions.length).toBe(1); + expect(result?.externalSettings).toEqual(updatedSettings); + expect(result?.externalSettings?.filters).toBeDefined(); + expect( + (result?.externalSettings?.filters as Record).length, + ).toBe(1); + expect(result?.externalSettings?.conditions).toBeDefined(); + expect( + (result?.externalSettings?.conditions as Record) + .length, + ).toBe(1); }); }); diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 2822c28c7..0747b450c 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -284,19 +284,43 @@ export class UsersController { async patchSettings( @Req() request: Request, @Param("id") id: string, - updateUserSettingsDto: PartialUpdateUserSettingsDto, + @Body() updateUserSettingsDto: PartialUpdateUserSettingsDto, ): Promise { await this.checkUserAuthorization( request, [Action.UserUpdateAny, Action.UserUpdateOwn], id, ); - return this.usersService.findOneAndUpdateUserSettings( + return this.usersService.findOneAndPatchUserSettings( id, updateUserSettingsDto, ); } + @UseGuards(AuthenticatedPoliciesGuard) + @CheckPolicies( + "users", + (ability: AppAbility) => + ability.can(Action.UserUpdateOwn, User) || + ability.can(Action.UserUpdateAny, User), + ) + @Patch("/:id/settings/external") + async patchExternalSettings( + @Req() request: Request, + @Param("id") id: string, + @Body() externalSettings: Record, + ): Promise { + await this.checkUserAuthorization( + request, + [Action.UserUpdateAny, Action.UserUpdateOwn], + id, + ); + return this.usersService.findOneAndPatchUserExternalSettings( + id, + externalSettings, + ); + } + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies( "users", diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 4c479c1b3..c94394aa0 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -296,6 +296,34 @@ export class UsersService implements OnModuleInit { return result; } + async findOneAndPatchUserSettings( + userId: string, + updateUserSettingsDto: UpdateUserSettingsDto | PartialUpdateUserSettingsDto, + ): Promise { + const result = await this.userSettingsModel + .findOneAndUpdate( + { userId }, + { $set: updateUserSettingsDto }, + { new: true }, + ) + .exec(); + return result; + } + + async findOneAndPatchUserExternalSettings( + userId: string, + externalSettings: Record, + ): Promise { + const updateQuery: Record = {}; + + for (const [key, value] of Object.entries(externalSettings)) { + updateQuery[`externalSettings.${key}`] = value; + } + const result = await this.userSettingsModel + .findOneAndUpdate({ userId }, { $set: updateQuery }, { new: true }) + .exec(); + return result; + } async findOneAndDeleteUserSettings(userId: string): Promise { return this.userSettingsModel.findOneAndDelete({ userId }).exec(); } From f891727644a62db1677900eb279e63e66b03ade5 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Sep 2024 14:59:35 +0200 Subject: [PATCH 231/258] fix unit test for users controller --- src/users/users.controller.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 40ac85311..5c111e716 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -75,7 +75,7 @@ describe("UsersController", () => { const result = await controller.getSettings(mockRequest as Request, userId); // Assert - expect(result?.externalSettings).toEqual(mockUserSettings); + expect(result).toEqual(mockUserSettings); expect(result?.externalSettings?.filters).toBeDefined(); expect( (result?.externalSettings?.filters as Record).length, @@ -108,7 +108,7 @@ describe("UsersController", () => { const expectedResponse: UserSettings = { ...updatedSettings, _id: userId, - userId: userId, // Ensure all required properties are included + userId: userId, datasetCount: updatedSettings.datasetCount, jobCount: updatedSettings.jobCount, externalSettings: updatedSettings.externalSettings, @@ -124,7 +124,7 @@ describe("UsersController", () => { updatedSettings, ); - expect(result?.externalSettings).toEqual(updatedSettings); + expect(result).toEqual(expectedResponse); expect(result?.externalSettings?.filters).toBeDefined(); expect( (result?.externalSettings?.filters as Record).length, From 5da55445154582a71aa929ab9105e2d2a84965c0 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 18 Sep 2024 15:03:17 +0200 Subject: [PATCH 232/258] latest packages.json local version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 748681b4c..788025822 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start\"", "test:api:jest": "jest --config ./test/config/jest-e2e.json --maxWorkers=50%", - "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js ", + "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js", "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.json.test functionalAccounts.json" }, "dependencies": { From 678c890864858b22d0391b40e5fbfaae0d0b7683 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Sep 2024 15:13:46 +0200 Subject: [PATCH 233/258] changed login endpoint from userService to authService --- test/LoginUtils.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/LoginUtils.js b/test/LoginUtils.js index 0a1cb950e..d5694d7ff 100644 --- a/test/LoginUtils.js +++ b/test/LoginUtils.js @@ -4,7 +4,7 @@ var request = require("supertest"); exports.getToken = function (appUrl, user) { return new Promise((resolve, reject) => { request(appUrl) - .post("/api/v3/Users/Login?include=user") + .post("/api/v3/auth/Login?include=user") .send(user) .set("Accept", "application/json") .end((err, res) => { @@ -20,17 +20,17 @@ exports.getToken = function (appUrl, user) { exports.getIdAndToken = function (appUrl, user) { return new Promise((resolve, reject) => { request(appUrl) - .post("/api/v3/Users/Login?include=user") + .post("/api/v3/auth/Login?include=user") .send(user) .set("Accept", "application/json") .end((err, res) => { if (err) { reject(err); } else { - resolve({userId:res.body.userId, token:res.body.id}); + resolve({ userId: res.body.userId, token: res.body.id }); } }); - }); + }); }; exports.getTokenAD = function (appUrl, user, cb) { From cc779858f775a2fdc82f8a4c7665824df878932f Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 18 Sep 2024 15:26:58 +0200 Subject: [PATCH 234/258] Renamed current dataset dtos to osbolete --- .../create-derived-dataset-obsolete.dto.ts | 27 +++++ .../dto/create-raw-dataset-obsolete.dto.ts | 27 +++++ .../update-derived-dataset-obsolete.dto.ts | 60 +++++++++++ .../dto/update-raw-dataset-obsolete.dto.ts | 100 ++++++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 src/datasets/dto/create-derived-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/create-raw-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/update-derived-dataset-obsolete.dto.ts create mode 100644 src/datasets/dto/update-raw-dataset-obsolete.dto.ts diff --git a/src/datasets/dto/create-derived-dataset-obsolete.dto.ts b/src/datasets/dto/create-derived-dataset-obsolete.dto.ts new file mode 100644 index 000000000..f6fcc180f --- /dev/null +++ b/src/datasets/dto/create-derived-dataset-obsolete.dto.ts @@ -0,0 +1,27 @@ +import { UpdateDerivedDatasetObsoleteDto } from "./update-derived-dataset-obsolete.dto"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsEnum, IsOptional, IsString } from "class-validator"; +import { DatasetType } from "../dataset-type.enum"; + +export class CreateDerivedDatasetObsoleteDto extends UpdateDerivedDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsOptional() + @IsString() + pid?: string; + + @IsEnum(DatasetType) + readonly type: string = DatasetType.Derived; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; +} diff --git a/src/datasets/dto/create-raw-dataset-obsolete.dto.ts b/src/datasets/dto/create-raw-dataset-obsolete.dto.ts new file mode 100644 index 000000000..57f7d6ba9 --- /dev/null +++ b/src/datasets/dto/create-raw-dataset-obsolete.dto.ts @@ -0,0 +1,27 @@ +import { UpdateRawDatasetObsoleteDto } from "./update-raw-dataset-obsolete.dto"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsEnum, IsOptional, IsString } from "class-validator"; +import { DatasetType } from "../dataset-type.enum"; + +export class CreateRawDatasetObsoleteDto extends UpdateRawDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: false, + description: "Persistent identifier of the dataset.", + }) + @IsOptional() + @IsString() + pid?: string; + + @IsEnum(DatasetType) + readonly type: string = DatasetType.Raw; + + @ApiProperty({ + type: String, + required: false, + description: "Version of the API used in creation of the dataset.", + }) + @IsOptional() + @IsString() + readonly version?: string; +} diff --git a/src/datasets/dto/update-derived-dataset-obsolete.dto.ts b/src/datasets/dto/update-derived-dataset-obsolete.dto.ts new file mode 100644 index 000000000..b6ec0bf4c --- /dev/null +++ b/src/datasets/dto/update-derived-dataset-obsolete.dto.ts @@ -0,0 +1,60 @@ +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; +import { ApiProperty, PartialType } from "@nestjs/swagger"; +import { IsObject, IsOptional, IsString } from "class-validator"; + +export class UpdateDerivedDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of the person or people pursuing the data analysis. The string may contain a list of names, which should then be separated by semicolons.", + }) + @IsString() + readonly investigator: string; + + @ApiProperty({ + type: [String], + required: true, + description: + "Array of input dataset identifiers used in producing the derived dataset. Ideally these are the global identifier to existing datasets inside this or federated data catalogs.", + }) + @IsString({ + each: true, + }) + readonly inputDatasets: string[]; + + @ApiProperty({ + type: [String], + required: true, + description: + "A list of links to software repositories which uniquely identifies the pieces of software, including versions, used for yielding the derived data.", + }) + @IsString({ + each: true, + }) + readonly usedSoftware: string[]; + + @ApiProperty({ + type: Object, + required: false, + description: + "The creation process of the derived data will usually depend on input job parameters. The full structure of these input parameters are stored here.", + }) + @IsOptional() + @IsObject() + readonly jobParameters?: Record; + + @ApiProperty({ + type: String, + required: false, + description: + "The output job logfile. Keep the size of this log data well below 15 MB.", + }) + @IsOptional() + @IsString() + readonly jobLogData?: string; +} + +export class PartialUpdateDerivedDatasetObsoleteDto extends PartialType( + UpdateDerivedDatasetObsoleteDto, +) {} diff --git a/src/datasets/dto/update-raw-dataset-obsolete.dto.ts b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts new file mode 100644 index 000000000..020cbcf70 --- /dev/null +++ b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts @@ -0,0 +1,100 @@ +import { IsDateString, IsOptional, IsString } from "class-validator"; +import { UpdateDatasetObsoleteDto } from "./update-dataset-obsolete.dto"; +import { ApiProperty, PartialType } from "@nestjs/swagger"; + +export class UpdateRawDatasetObsoleteDto extends UpdateDatasetObsoleteDto { + /* we need to discuss if the naming is adequate. */ + @ApiProperty({ + type: String, + required: true, + description: + "First name and last name of principal investigator(s). If multiple PIs are present, use a semicolon separated list. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + readonly principalInvestigator: string; + + @ApiProperty({ + type: Date, + required: false, + description: + "Start time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly startTime?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: + "End time of data acquisition for the current dataset.
It is expected to be in ISO8601 format according to specifications for internet date/time format in RFC 3339, chapter 5.6 (https://www.rfc-editor.org/rfc/rfc3339#section-5).
Local times without timezone/offset info are automatically transformed to UTC using the timezone of the API server.", + }) + @IsOptional() + @IsDateString() + readonly endTime?: Date; + + @ApiProperty({ + type: String, + required: true, + description: + "Unique location identifier where data was taken, usually in the form /Site-name/facility-name/instrumentOrBeamline-name. This field is required if the dataset is a Raw dataset.", + }) + @IsString() + readonly creationLocation: string; + + @ApiProperty({ + type: String, + required: false, + description: + "Defines the format of the data files in this dataset, e.g Nexus Version x.y.", + }) + @IsOptional() + @IsString() + readonly dataFormat?: string; + + @ApiProperty({ + type: String, + required: false, + description: "The ID of the proposal to which the dataset belongs.", + }) + @IsOptional() + @IsString() + readonly proposalId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the sample used when collecting the data.", + }) + @IsOptional() + @IsString() + readonly sampleId?: string; + + @ApiProperty({ + type: String, + required: false, + description: "ID of the instrument where the data was created.", + }) + @IsOptional() + @IsString() + readonly instrumentId: string; + + @IsOptional() + investigator?: string; + + @IsOptional() + inputDatasets?: string[]; + + @IsOptional() + usedSoftware?: string[]; + + @IsOptional() + jobParameters?: Record; + + @IsOptional() + jobLogData?: string; +} + +export class PartialUpdateRawDatasetObsoleteDto extends PartialType( + UpdateRawDatasetObsoleteDto, +) {} From e97ec50641b73110019883084973cf62ab138537 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Sep 2024 16:12:11 +0200 Subject: [PATCH 235/258] added test for user settings patch --- src/users/schemas/user-settings.schema.ts | 2 +- test/TestData.js | 31 +++++++++++++++ test/Users.js | 46 +++++++++++++++++++---- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index 9aa9a9f08..e5d524936 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -50,7 +50,7 @@ export class UserSettings { "A customizable object for storing the user's external settings, which can contain various nested properties and configurations.", }) @Prop({ type: Object, default: {}, required: false }) - externalSettings?: Record; + externalSettings: Record; } export const UserSettingsSchema = SchemaFactory.createForClass(UserSettings); diff --git a/test/TestData.js b/test/TestData.js index 538f657bf..2f5f0a22e 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -43,6 +43,37 @@ const TestData = { accessGroups: [], }, + userSettingsCorrect: { + datasetCount: 10, + jobCount: 25, + externalSettings: { + columns: [ + { + name: "select", + order: 0, + type: "standard", + enabled: true, + }, + ], + filters: [ + { + LocationFilter: true, + }, + ], + conditions: [ + { + condition: { + lhs: "test", + relation: "GREATER_THAN", + rhs: 1, + unit: "", + }, + enabled: true, + }, + ], + }, + }, + ProposalCorrectComplete: { proposalId: "20170267", pi_email: "pi@uni.edu", diff --git a/test/Users.js b/test/Users.js index c4f8d7f66..a6e81ec91 100644 --- a/test/Users.js +++ b/test/Users.js @@ -10,7 +10,7 @@ let userIdUser1 = null, describe("2350: Users: Login with functional accounts", () => { it("0010: Admin ingestor login fails with incorrect credentials", async () => { return request(appUrl) - .post("/api/v3/Users/Login?include=user") + .post("/api/v3/auth/Login?include=user") .send({ username: "adminIngestor", password: TestData.Accounts["user1"]["password"], @@ -23,7 +23,7 @@ describe("2350: Users: Login with functional accounts", () => { it("0020: Login should succeed with correct credentials", async () => { return request(appUrl) - .post("/api/v3/Users/Login?include=user") + .post("/api/v3/auth/Login?include=user") .send({ username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], @@ -38,18 +38,19 @@ describe("2350: Users: Login with functional accounts", () => { }); describe("2360: Users settings", () => { - beforeEach(async() => { + beforeEach(async () => { const loginResponseUser1 = await utils.getIdAndToken(appUrl, { username: "user1", password: TestData.Accounts["user1"]["password"], }); userIdUser1 = loginResponseUser1.userId; - accessTokenUser1 = loginResponseUser1.token; + accessTokenUser1 = loginResponseUser1.token; }); - it("0010: Update users settings with valid value should success ", async () => { + it("0020: Update users settings with valid value should success ", async () => { return request(appUrl) .put(`/api/v3/Users/${userIdUser1}/settings`) + .send(TestData.userSettingsCorrect) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulPatchStatusCode) @@ -58,8 +59,39 @@ describe("2360: Users settings", () => { res.body.should.have.property("userId", userIdUser1); res.body.should.have.property("datasetCount"); res.body.should.have.property("jobCount"); - res.body.should.have.property("filters"); - res.body.should.have.property("conditions"); + res.body.should.have.property("externalSettings"); + }); + }); + + it("0030: Patch users settings with valid value should success ", async () => { + return request(appUrl) + .patch(`/api/v3/Users/${userIdUser1}/settings`) + .send(TestData.userSettingsCorrect) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("userId", userIdUser1); + res.body.should.have.property("datasetCount"); + res.body.should.have.property("jobCount"); + res.body.should.have.property("externalSettings"); + }); + }); + + it("0040: Patch users external settings with valid value should success ", async () => { + return request(appUrl) + .patch(`/api/v3/Users/${userIdUser1}/settings/external`) + .send(TestData.userSettingsCorrect.externalSettings) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("userId", userIdUser1); + res.body.should.have.property("datasetCount"); + res.body.should.have.property("jobCount"); + res.body.should.have.property("externalSettings"); }); }); }); From 22abb54e4ad6d53cb0a66ea275c70c3776fc9cf8 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 18 Sep 2024 16:28:17 +0200 Subject: [PATCH 236/258] fixed test dataset used in elasticsearch tests --- test/ElasticSearch.js | 4 ++-- test/TestData.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js index cfec71f29..35ee5cb19 100644 --- a/test/ElasticSearch.js +++ b/test/ElasticSearch.js @@ -45,12 +45,12 @@ const scientificMetadata = (values) => { before(() => { db.collection("Dataset").deleteMany({}); }); - beforeEach(async() => { + beforeEach(async () => { accessTokenAdminIngestor = await utils.getToken(appUrl, { username: "adminIngestor", password: TestData.Accounts["adminIngestor"]["password"], }); - + accessTokenArchiveManager = await utils.getToken(appUrl, { username: "archiveManager", password: TestData.Accounts["archiveManager"]["password"], diff --git a/test/TestData.js b/test/TestData.js index bee14fe4c..7347a06aa 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -818,6 +818,7 @@ const TestData = { creationLocation: faker.location.city(), principalInvestigator: faker.internet.userName(), type: "raw", + datasetName: faker.string.sample(), creationTime: faker.date.past(), sourceFolder: faker.system.directoryPath(), owner: faker.internet.userName(), From dc3ff8dcf9692f389145c14d473717aa7cf86f36 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 19 Sep 2024 11:52:46 +0200 Subject: [PATCH 237/258] Updated datasets dto according to PR review --- src/datasets/dto/output-dataset.dto.ts | 6 +++--- src/datasets/dto/update-dataset.dto.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/datasets/dto/output-dataset.dto.ts b/src/datasets/dto/output-dataset.dto.ts index 8809e3756..6c070a73c 100644 --- a/src/datasets/dto/output-dataset.dto.ts +++ b/src/datasets/dto/output-dataset.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from "@nestjs/swagger"; import { CreateDatasetDto } from "./create-dataset.dto"; -import { IsString } from "class-validator"; +import { IsDateString, IsString } from "class-validator"; export class OutputDatasetDto extends CreateDatasetDto { @ApiProperty({ @@ -27,7 +27,7 @@ export class OutputDatasetDto extends CreateDatasetDto { description: "Date and time when this record was created. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", }) - @IsString() + @IsDateString() createdAt: Date; @ApiProperty({ @@ -36,6 +36,6 @@ export class OutputDatasetDto extends CreateDatasetDto { description: "Date and time when this record was updated last. This field is managed by mongoose with through the timestamp settings. The field should be a string containing a date in ISO 8601 format (2024-02-27T12:26:57.313Z)", }) - @IsString() + @IsDateString() updatedAt: Date; } diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index 26866705d..6592e57ec 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -209,7 +209,7 @@ export class UpdateDatasetDto extends OwnableDto { }) @IsOptional() @IsBoolean() - readonly isPublished?: boolean = false; + readonly isPublished?: boolean; @ApiProperty({ type: "array", @@ -371,7 +371,7 @@ export class UpdateDatasetDto extends OwnableDto { }) @IsOptional() @IsString({ - each: false, + each: true, }) readonly instrumentIds?: string[]; From 2a450ad0c6d18a953ca6b93df7a9f97fbb87bdb5 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 19 Sep 2024 12:12:59 +0200 Subject: [PATCH 238/258] fix: resolved ApiParam inconsistencies and corrected TypeScript-Angular generator name in openapi-generator (#1426) --- ...fig.json => typescript-angular-config.json} | 0 .github/workflows/release-and-publish-sdk.yml | 10 +++++----- .github/workflows/upload-sdk-artifact.yml | 4 ++-- src/samples/samples.controller.ts | 18 +++++++++--------- 4 files changed, 16 insertions(+), 16 deletions(-) rename .github/openapi/{typescript-config.json => typescript-angular-config.json} (100%) diff --git a/.github/openapi/typescript-config.json b/.github/openapi/typescript-angular-config.json similarity index 100% rename from .github/openapi/typescript-config.json rename to .github/openapi/typescript-angular-config.json diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 4228642e6..9a79e592f 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -131,7 +131,7 @@ jobs: - start-backend-export-swagger strategy: matrix: - generator: [python, python-pydantic-v1, typescript] + generator: [python, python-pydantic-v1, typescript-angular] steps: - name: Checkout repository @@ -152,7 +152,7 @@ jobs: --git-repo-id scicat-backend-next \ --git-user-id SciCatProject \ -o ./sdk/${{ matrix.generator }} $( - if [ "${{ matrix.generator }}" == "typescript" ]; then + if [ "${{ matrix.generator }}" == "typescript-angular" ]; then echo "--additional-properties=npmVersion=${{ needs.build-release.outputs.new_tag}}"; elif [ "${{ matrix.generator }}" == "python" ]; then echo "--additional-properties=packageVersion=${{ needs.build-release.outputs.new_tag}}"; @@ -183,10 +183,10 @@ jobs: node-version: ${{ env.NODE_VERSION }} registry-url: "https://registry.npmjs.org/" - - name: Download TypeScript SDK Artifact + - name: Download TypeScript Angular SDK Artifact uses: actions/download-artifact@v4 with: - name: sdk-typescript-${{github.sha}} + name: sdk-typescript-angular-${{github.sha}} path: ./sdk - name: Publish package @@ -194,7 +194,7 @@ jobs: npm install npm run build npm publish --access public - working-directory: ./sdk/typescript/ + working-directory: ./sdk/typescript-angular/ env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml index cbce35fc4..369426a08 100644 --- a/.github/workflows/upload-sdk-artifact.yml +++ b/.github/workflows/upload-sdk-artifact.yml @@ -48,7 +48,7 @@ jobs: - start-backend-and-upload-swagger-schema strategy: matrix: - generator: [python, typescript, python-pydantic-v1] + generator: [python, typescript-angular, python-pydantic-v1] steps: - name: Checkout repository @@ -67,7 +67,7 @@ jobs: config-file: .github/openapi/${{ matrix.generator }}-config.json command-args: | -o ./sdk/${{ matrix.generator }} $( - if [ "${{ matrix.generator }}" == "typescript" ]; then + if [ "${{ matrix.generator }}" == "typescript-angular" ]; then echo "--additional-properties=npmVersion=${{env.SDK_VERSION}}"; elif [ "${{ matrix.generator }}" == "python" ]; then echo "--additional-properties=packageVersion=${{env.SDK_VERSION}}"; diff --git a/src/samples/samples.controller.ts b/src/samples/samples.controller.ts index 030960896..e5c5feaf7 100644 --- a/src/samples/samples.controller.ts +++ b/src/samples/samples.controller.ts @@ -566,7 +566,7 @@ export class SamplesController { "Returns a boolean indicating whether the user has access to the sample with the specified ID.", }) @ApiParam({ - name: "pid", + name: "id", description: "ID of the sample to check access for", type: String, }) @@ -774,17 +774,17 @@ export class SamplesController { }) async findOneAttachment( @Req() request: Request, - @Param("id") sampleId: string, + @Param("id") id: string, @Param("fk") attachmentId: string, ): Promise { await this.checkPermissionsForSample( request, - sampleId, + id, Action.SampleAttachmentRead, ); return this.attachmentsService.findOne({ id: attachmentId, - sampleId: sampleId, + sampleId: id, }); } @@ -816,17 +816,17 @@ export class SamplesController { }) async findOneAttachmentAndRemove( @Req() request: Request, - @Param("id") sampleId: string, + @Param("id") id: string, @Param("fk") attachmentId: string, ): Promise { await this.checkPermissionsForSample( request, - sampleId, + id, Action.SampleAttachmentDelete, ); return this.attachmentsService.findOneAndDelete({ _id: attachmentId, - sampleId: sampleId, + sampleId: id, }); } @@ -867,7 +867,7 @@ export class SamplesController { }) async findAllDatasets( @Req() request: Request, - @Param("id") sampleId: string, + @Param("id") id: string, ): Promise { const user: JWTUser = request.user as JWTUser; const ability = this.caslAbilityFactory.samplesInstanceAccess(user); @@ -900,7 +900,7 @@ export class SamplesController { } const dataset = await this.datasetsService.fullquery({ - where: { sampleId }, + where: { sampleId: id }, fields: fields, }); return dataset; From 2778acfd126132ff829b1580851494011a2753db Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 13:54:08 +0200 Subject: [PATCH 239/258] fix elastic search test fail --- .../configuration/datasetFieldMapping.ts | 4 ++-- test/ElasticSearch.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index 429555ee8..c0d4a9213 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -42,11 +42,11 @@ export const datasetMappings: MappingObject = { type: "nested", dynamic: false, }, - proposalId: { + proposalIds: { type: "keyword", ignore_above: 256, }, - sampleId: { + sampleIds: { type: "keyword", ignore_above: 256, }, diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js index 35ee5cb19..a027564cb 100644 --- a/test/ElasticSearch.js +++ b/test/ElasticSearch.js @@ -178,11 +178,11 @@ const scientificMetadata = (values) => { }); }); - it("0030: should fetching dataset with correct proposalId and size", async () => { + it("0030: should fetching dataset with correct proposalIds and size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send({ - proposalId: TestData.ScientificMetadataForElasticSearch.proposalId, + proposalIds: TestData.ScientificMetadataForElasticSearch.proposalId, size: TestData.ScientificMetadataForElasticSearch.size, }) .set("Accept", "application/json") @@ -194,11 +194,11 @@ const scientificMetadata = (values) => { }); }); - it("0031: should fail fetching dataset with correct proposalId but wrong size", async () => { + it("0031: should fail fetching dataset with correct proposalIds but wrong size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send({ - proposalId: TestData.ScientificMetadataForElasticSearch.proposalId, + proposalIds: [TestData.ScientificMetadataForElasticSearch.proposalId], size: faker.number.int({ min: 100000001, max: 100400000 }), }) .set("Accept", "application/json") @@ -209,11 +209,11 @@ const scientificMetadata = (values) => { res.body.data.should.be.length(0); }); }); - it("0032: should fail fetching dataset with wrong proposalId but correct size", async () => { + it("0032: should fail fetching dataset with wrong proposalIds but correct size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send({ - proposalId: "wrongProposalId", + proposalIds: ["wrongProposalId"], size: TestData.ScientificMetadataForElasticSearch.size, }) .set("Accept", "application/json") @@ -225,11 +225,11 @@ const scientificMetadata = (values) => { }); }); - it("0033: should fail fetching dataset with incorrect proposalId and size", async () => { + it("0033: should fail fetching dataset with incorrect proposalIds and size", async () => { return request(appUrl) .post("/api/v3/elastic-search/search") .send({ - proposalId: "wrongProposalId", + proposalIds: ["wrongProposalId"], size: faker.number.int({ min: 100000001, max: 100400000 }), }) .set("Accept", "application/json") From ef4854926503176dd192b0466eb2047da131d78d Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 14:09:24 +0200 Subject: [PATCH 240/258] added instrumentIds to ES datasetFieldMapping --- src/elastic-search/configuration/datasetFieldMapping.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/elastic-search/configuration/datasetFieldMapping.ts b/src/elastic-search/configuration/datasetFieldMapping.ts index c0d4a9213..629d5f80f 100644 --- a/src/elastic-search/configuration/datasetFieldMapping.ts +++ b/src/elastic-search/configuration/datasetFieldMapping.ts @@ -50,6 +50,10 @@ export const datasetMappings: MappingObject = { type: "keyword", ignore_above: 256, }, + instrumentIds: { + type: "keyword", + ignore_above: 256, + }, sourceFolder: { type: "keyword", ignore_above: 256, From 1d2f8c60646ba2f7b00dfbe9e2072927c31a59dd Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 18 Sep 2024 16:31:28 +0200 Subject: [PATCH 241/258] feat: allow the swagger path to be configurable --- README.md | 1 + src/main.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 50e87e5d3..103b8c3fd 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,7 @@ Valid environment variables for the .env file. See [.env.example](/.env.example) | `ES_FIELDS_LIMIT` | number | | The total number of fields in an index. | 1000 | | `ES_REFRESH` | string | | If set to `wait_for`, Elasticsearch will wait till data is inserted into the specified index before returning a response. | false | | `LOGGERS_CONFIG_FILE` | string | | The file name for loggers configuration, located in the project root directory. | "loggers.json" | +| `SWAGGER_PATH` | string | Yes | swaggerPath is the path where the swagger UI will be available| "explorer"| ## Migrating from the old SciCat Backend diff --git a/src/main.ts b/src/main.ts index a8c8aaec8..a499e5ac1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -36,8 +36,9 @@ async function bootstrap() { docExpansion: "none", }, }; + const swaggerPath = process.env.SWAGGER_PATH || "explorer"; - SwaggerModule.setup("explorer", app, document, swaggerOptions); + SwaggerModule.setup(swaggerPath, app, document, swaggerOptions); app.useGlobalPipes( /** From 59aea01e16f483052f1578f15f03587f1ef9d72f Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 10:13:17 +0200 Subject: [PATCH 242/258] Update the version in package.json from 4.0.0 to 4.5.0. In configuration.ts, add a new property "versions.api" with a default value of "v3". Also, add a new property "swaggerPath" with a default value of "explorer". --- package.json | 2 +- src/config/configuration.ts | 4 ++++ src/main.ts | 16 +++++++++------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 5e0a998b7..c2d233fcf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scicat-backend-next", - "version": "4.0.0", + "version": "4.5.0", "description": "scicat-backend-next", "author": "", "private": true, diff --git a/src/config/configuration.ts b/src/config/configuration.ts index e73d42a72..a8c6527e6 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -58,6 +58,10 @@ const configuration = () => { }); const config = { + versions: { + api: process.env.API_VERSION || "v3", + }, + swaggerPath: process.env.SWAGGER_PATH || "explorer", loggerConfigs: jsonConfigMap.loggers || [defaultLogger], adminGroups: adminGroups.split(",").map((v) => v.trim()) ?? [], deleteGroups: deleteGroups.split(",").map((v) => v.trim()) ?? [], diff --git a/src/main.ts b/src/main.ts index a499e5ac1..06a6f82cb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,6 +15,11 @@ async function bootstrap() { const app = await NestFactory.create(AppModule, { bufferLogs: true, }); + const configService: ConfigService, false> = app.get( + ConfigService, + ); + const apiVersion = configService.get("versions.api") ?? "v3"; + const swaggerPath = `${configService.get("swaggerPath")}`; const scicatLogger = app.get(ScicatLogger); @@ -23,20 +28,21 @@ async function bootstrap() { app.useGlobalFilters(new AllExceptionsFilter(scicatLogger)); app.enableCors(); - app.setGlobalPrefix("api/v3"); + + app.setGlobalPrefix(`api/${apiVersion}`); const config = new DocumentBuilder() .setTitle("SciCat backend API") .setDescription("This is the API for the SciCat Backend") - .setVersion("" + process.env.npm_package_version) + .setVersion(`api/${apiVersion}`) .addBearerAuth() .build(); + const document = SwaggerModule.createDocument(app, config); const swaggerOptions: SwaggerCustomOptions = { swaggerOptions: { docExpansion: "none", }, }; - const swaggerPath = process.env.SWAGGER_PATH || "explorer"; SwaggerModule.setup(swaggerPath, app, document, swaggerOptions); @@ -71,10 +77,6 @@ async function bootstrap() { app.use(json({ limit: "16mb" })); - const configService: ConfigService, false> = app.get( - ConfigService, - ); - const expressSessionSecret = configService.get( "expressSessionSecret", ); From 75ed50318ea50627adefcd8013ac2754d08da162 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 10:16:05 +0200 Subject: [PATCH 243/258] make api version not configurable. --- src/config/configuration.ts | 4 ++-- src/main.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config/configuration.ts b/src/config/configuration.ts index a8c6527e6..97af54dfb 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -58,8 +58,8 @@ const configuration = () => { }); const config = { - versions: { - api: process.env.API_VERSION || "v3", + VERSIONS: { + API: "v3", }, swaggerPath: process.env.SWAGGER_PATH || "explorer", loggerConfigs: jsonConfigMap.loggers || [defaultLogger], diff --git a/src/main.ts b/src/main.ts index 06a6f82cb..96b2f84e6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,7 @@ async function bootstrap() { const configService: ConfigService, false> = app.get( ConfigService, ); - const apiVersion = configService.get("versions.api") ?? "v3"; + const apiVersion = configService.get("VERSIONS.API"); const swaggerPath = `${configService.get("swaggerPath")}`; const scicatLogger = app.get(ScicatLogger); From 55329e75881a2fcea97721a99c5133ec8f16ddf2 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 15:10:21 +0200 Subject: [PATCH 244/258] converting api version vars naming to lower case --- src/config/configuration.ts | 4 ++-- src/main.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 97af54dfb..96e9e9bbd 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -58,8 +58,8 @@ const configuration = () => { }); const config = { - VERSIONS: { - API: "v3", + versions: { + api: "v3", }, swaggerPath: process.env.SWAGGER_PATH || "explorer", loggerConfigs: jsonConfigMap.loggers || [defaultLogger], diff --git a/src/main.ts b/src/main.ts index 96b2f84e6..980dc66a8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,7 @@ async function bootstrap() { const configService: ConfigService, false> = app.get( ConfigService, ); - const apiVersion = configService.get("VERSIONS.API"); + const apiVersion = configService.get("versions.api"); const swaggerPath = `${configService.get("swaggerPath")}`; const scicatLogger = app.get(ScicatLogger); From 2f55a3558f79673b8abdaa789194fea932102376 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 15:14:25 +0200 Subject: [PATCH 245/258] fix: swagger-schema artifact is missing commit ID --- .github/workflows/release-and-publish-sdk.yml | 4 ++-- .github/workflows/upload-sdk-artifact.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index 9a79e592f..c46b76036 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -121,7 +121,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: swagger-schema + name: swagger-schema-${{ github.sha }} path: ./swagger-schema.json generate-upload-sdk: @@ -139,7 +139,7 @@ jobs: - uses: actions/download-artifact@v4 with: - name: swagger-schema + name: swagger-schema-${{ github.sha }} path: . - name: Generate Client diff --git a/.github/workflows/upload-sdk-artifact.yml b/.github/workflows/upload-sdk-artifact.yml index 369426a08..a33c50a09 100644 --- a/.github/workflows/upload-sdk-artifact.yml +++ b/.github/workflows/upload-sdk-artifact.yml @@ -39,7 +39,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: swagger-schema + name: swagger-schema-${{ github.sha }} path: ./swagger-schema.json generate-and-upload-sdk: @@ -56,7 +56,7 @@ jobs: - uses: actions/download-artifact@v4 with: - name: swagger-schema + name: swagger-schema-${{ github.sha }} path: . - name: Generate Client From 72ccf7f2e87be6816157b35dde37f7063fd741f4 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Thu, 19 Sep 2024 15:35:24 +0200 Subject: [PATCH 246/258] added sdk badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 103b8c3fd..b1ffe56a3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![Test](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/test.yml/badge.svg)](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/test.yml) [![Deploy](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/deploy.yml/badge.svg)](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/deploy.yml) +[![Generate and upload latest SDK artifacts](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/upload-sdk-artifact.yml/badge.svg?branch=master)](https://github.com/SciCatProject/scicat-backend-next/actions/workflows/upload-sdk-artifact.yml) [![DeepScan grade](https://deepscan.io/api/teams/8394/projects/19251/branches/494247/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=8394&pid=19251&bid=494247) [![Known Vulnerabilities](https://snyk.io/test/github/SciCatProject/scicat-backend-next/master/badge.svg?targetFile=package.json)](https://snyk.io/test/github/SciCatProject/scicat-backend-next/master?targetFile=package.json) From 4ef5b9fbf0eaef67424f5a299c1bd79e98bc6b2f Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Thu, 19 Sep 2024 21:02:55 +0200 Subject: [PATCH 247/258] implemented requested changes and fixed linting --- src/datasets/datasets.controller.ts | 2 +- src/datasets/datasets.service.ts | 1 - src/datasets/dto/update-dataset-obsolete.dto.ts | 3 --- src/datasets/dto/update-dataset.dto.ts | 2 +- src/datasets/schemas/dataset.schema.ts | 12 ------------ 5 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 11cbc7b69..bfc9dd843 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -61,7 +61,7 @@ import { DatablocksService } from "src/datablocks/datablocks.service"; import { Datablock } from "src/datablocks/schemas/datablock.schema"; import { CreateDatablockDto } from "src/datablocks/dto/create-datablock.dto"; import { PartialUpdateDatablockDto } from "src/datablocks/dto/update-datablock.dto"; -import { Document, UpdateQuery } from "mongoose"; +import { UpdateQuery } from "mongoose"; import { FilterPipe } from "src/common/pipes/filter.pipe"; import { UTCTimeInterceptor } from "src/common/interceptors/utc-time.interceptor"; import { DataFile } from "src/common/schemas/datafile.schema"; diff --git a/src/datasets/datasets.service.ts b/src/datasets/datasets.service.ts index 723552172..b43385a3f 100644 --- a/src/datasets/datasets.service.ts +++ b/src/datasets/datasets.service.ts @@ -23,7 +23,6 @@ import { import { ElasticSearchService } from "src/elastic-search/elastic-search.service"; import { InitialDatasetsService } from "src/initial-datasets/initial-datasets.service"; import { LogbooksService } from "src/logbooks/logbooks.service"; -import { DatasetType } from "./dataset-type.enum"; import { CreateDatasetDto } from "./dto/create-dataset.dto"; import { IDatasetFields } from "./interfaces/dataset-filters.interface"; import { DatasetClass, DatasetDocument } from "./schemas/dataset.schema"; diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts index f2be1c2d2..ac0e996c8 100644 --- a/src/datasets/dto/update-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -24,9 +24,6 @@ import { CreateTechniqueDto } from "./create-technique.dto"; import { RelationshipClass } from "../schemas/relationship.schema"; import { CreateRelationshipDto } from "./create-relationship.dto"; import { LifecycleClass } from "../schemas/lifecycle.schema"; -import { Attachment } from "../../attachments/schemas/attachment.schema"; -import { OrigDatablock } from "../../origdatablocks/schemas/origdatablock.schema"; -import { Datablock } from "../../datablocks/schemas/datablock.schema"; @ApiTags("datasets") export class UpdateDatasetObsoleteDto extends OwnableDto { diff --git a/src/datasets/dto/update-dataset.dto.ts b/src/datasets/dto/update-dataset.dto.ts index 6592e57ec..99c6c3eaf 100644 --- a/src/datasets/dto/update-dataset.dto.ts +++ b/src/datasets/dto/update-dataset.dto.ts @@ -383,7 +383,7 @@ export class UpdateDatasetDto extends OwnableDto { }) @IsOptional() @IsString({ - each: false, + each: true, }) readonly inputDatasets?: string[]; diff --git a/src/datasets/schemas/dataset.schema.ts b/src/datasets/schemas/dataset.schema.ts index 9b3d7f7e2..a3fb81086 100644 --- a/src/datasets/schemas/dataset.schema.ts +++ b/src/datasets/schemas/dataset.schema.ts @@ -1,19 +1,7 @@ import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; import { ApiProperty, getSchemaPath } from "@nestjs/swagger"; import { Document } from "mongoose"; -import { - Attachment, - AttachmentSchema, -} from "src/attachments/schemas/attachment.schema"; import { OwnableClass } from "src/common/schemas/ownable.schema"; -import { - Datablock, - DatablockSchema, -} from "src/datablocks/schemas/datablock.schema"; -import { - OrigDatablock, - OrigDatablockSchema, -} from "src/origdatablocks/schemas/origdatablock.schema"; import { v4 as uuidv4 } from "uuid"; import { DatasetType } from "../dataset-type.enum"; import { HistoryClass, HistorySchema } from "./history.schema"; From a3b02f9d8e17e3bfcc63c38930ae257a326e921e Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 20 Sep 2024 13:29:02 +0200 Subject: [PATCH 248/258] added database migration --- .../20240920111733-dataset-unified-schema.js | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 migrations/20240920111733-dataset-unified-schema.js diff --git a/migrations/20240920111733-dataset-unified-schema.js b/migrations/20240920111733-dataset-unified-schema.js new file mode 100644 index 000000000..9a70776b5 --- /dev/null +++ b/migrations/20240920111733-dataset-unified-schema.js @@ -0,0 +1,51 @@ +module.exports = { + async up(db, client) { + // TODO write your migration here. + // See https://github.com/seppevs/migrate-mongo/#creating-a-new-migration-script + // Example: + // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: true}}); + await db.collection("Dataset").updateMany( + {}, + { + $set: { + proposalIds: "$proposalId", + instrumentIds: "$instrumentId", + sampleIds: "$sampleId", + }, + }, + ); + await db.collection("Dataset").updateMany( + { type: "derived" }, + { + $set: { + principalInvestigator: "$investigator", + }, + }, + ); + }, + + async down(db, client) { + // TODO write the statements to rollback your migration (if possible) + // Example: + // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: false}}); + + await db.collection("Dataset").updateMany( + {}, + { + $set: { + proposalId: "$proposalIds[0]", + instrumentId: "$instrumentId[0]", + sampleId: "$sampleId[0]", + }, + }, + ); + await db.collection("Dataset").updateMany( + { type: "derived" }, + { + $set: { + investigator: "$principalInvestigator", + }, + }, + ); + }, +}; From c5e1040a0d59f52e9a03a9666ceabd479858100a Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 20 Sep 2024 13:54:22 +0200 Subject: [PATCH 249/258] Fixed mongo migrate script for dataset unified schema --- .../20240920111733-dataset-unified-schema.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/migrations/20240920111733-dataset-unified-schema.js b/migrations/20240920111733-dataset-unified-schema.js index 9a70776b5..598d6db6c 100644 --- a/migrations/20240920111733-dataset-unified-schema.js +++ b/migrations/20240920111733-dataset-unified-schema.js @@ -4,24 +4,22 @@ module.exports = { // See https://github.com/seppevs/migrate-mongo/#creating-a-new-migration-script // Example: // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: true}}); - await db.collection("Dataset").updateMany( - {}, + await db.collection("Dataset").updateMany({}, [ { $set: { - proposalIds: "$proposalId", - instrumentIds: "$instrumentId", - sampleIds: "$sampleId", + proposalIds: ["$proposalId"], + instrumentIds: ["$instrumentId"], + sampleIds: ["$sampleId"], }, }, - ); - await db.collection("Dataset").updateMany( - { type: "derived" }, + ]); + await db.collection("Dataset").updateMany({ type: "derived" }, [ { $set: { principalInvestigator: "$investigator", }, }, - ); + ]); }, async down(db, client) { @@ -29,8 +27,7 @@ module.exports = { // Example: // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: false}}); - await db.collection("Dataset").updateMany( - {}, + await db.collection("Dataset").updateMany({}, [ { $set: { proposalId: "$proposalIds[0]", @@ -38,14 +35,13 @@ module.exports = { sampleId: "$sampleId[0]", }, }, - ); - await db.collection("Dataset").updateMany( - { type: "derived" }, + ]); + await db.collection("Dataset").updateMany({ type: "derived" }, [ { $set: { investigator: "$principalInvestigator", }, }, - ); + ]); }, }; From 9ab8db2ef3f0988ad570ba399ee520bee13ebf83 Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 23 Sep 2024 14:21:37 +0200 Subject: [PATCH 250/258] fix: renamed instrumentIds key to instrumentId key in convertObsoleteToCurrentSchema function --- src/datasets/datasets.controller.ts | 4 ++-- src/datasets/dto/update-raw-dataset-obsolete.dto.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index bfc9dd843..920ba0aee 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -424,7 +424,7 @@ export class DatasetsController { (inputObsoleteDataset as CreateRawDatasetObsoleteDto).sampleId, ]; } - if ("instrumentIds" in inputObsoleteDataset) { + if ("instrumentId" in inputObsoleteDataset) { propertiesModifier.instrumentIds = [ (inputObsoleteDataset as CreateRawDatasetObsoleteDto).instrumentId, ]; @@ -557,7 +557,7 @@ export class DatasetsController { obsoleteDatasetDto, ) as CreateDatasetDto; const createdDataset = await this.datasetsService.create(datasetDto); - + console.log("====createdDataset====", createdDataset); const outputObsoleteDatasetDto = this.convertCurrentToObsoleteSchema(createdDataset); diff --git a/src/datasets/dto/update-raw-dataset-obsolete.dto.ts b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts index 020cbcf70..50096b914 100644 --- a/src/datasets/dto/update-raw-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts @@ -77,7 +77,7 @@ export class UpdateRawDatasetObsoleteDto extends UpdateDatasetObsoleteDto { }) @IsOptional() @IsString() - readonly instrumentId: string; + readonly instrumentId?: string; @IsOptional() investigator?: string; From bdde868767e546ab13b792ab38714298fbf1a6bb Mon Sep 17 00:00:00 2001 From: junjiequan Date: Mon, 23 Sep 2024 14:24:48 +0200 Subject: [PATCH 251/258] remove consolel.log --- src/datasets/datasets.controller.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index 920ba0aee..f0ee5977c 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -557,7 +557,6 @@ export class DatasetsController { obsoleteDatasetDto, ) as CreateDatasetDto; const createdDataset = await this.datasetsService.create(datasetDto); - console.log("====createdDataset====", createdDataset); const outputObsoleteDatasetDto = this.convertCurrentToObsoleteSchema(createdDataset); From d1420aa558a34a3fc3ee21dea2274c68dc6dc14f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:54:33 +0000 Subject: [PATCH 252/258] build(deps): bump actions/setup-python from 4 to 5 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release-and-publish-sdk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-and-publish-sdk.yml b/.github/workflows/release-and-publish-sdk.yml index c46b76036..980cbe8d6 100644 --- a/.github/workflows/release-and-publish-sdk.yml +++ b/.github/workflows/release-and-publish-sdk.yml @@ -215,7 +215,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} From 1d381be302c36df93877e962e6b9abc1f151723a Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 24 Sep 2024 14:40:13 +0200 Subject: [PATCH 253/258] fixing the dataset output dto --- src/datasets/datasets.controller.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index f0ee5977c..ba6faa208 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -746,7 +746,8 @@ export class DatasetsController { const includeFilters = mergedFilters.include ?? []; await Promise.all( datasets.map(async (dataset) => { - if (includeFilters) { + dataset = this.convertCurrentToObsoleteSchema(dataset); + if (includeFilters) { await Promise.all( includeFilters.map(async ({ relation }) => { switch (relation) { @@ -1169,7 +1170,7 @@ export class DatasetsController { await this.checkPermissionsForDatasetObsolete(request, id), ); - return dataset as OutputDatasetObsoleteDto; + return this.convertCurrentToObsoleteSchema(dataset) as OutputDatasetObsoleteDto; } // PATCH /datasets/:id From 441374fd0bfc52e321011b814172773057fb5319 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Tue, 24 Sep 2024 14:48:32 +0200 Subject: [PATCH 254/258] updated raw datasets to include instrument and sample id --- test/RawDataset.js | 3 +++ test/TestData.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/test/RawDataset.js b/test/RawDataset.js index c150faa40..6e9fcd748 100644 --- a/test/RawDataset.js +++ b/test/RawDataset.js @@ -93,6 +93,9 @@ describe("1900: RawDataset: Raw Datasets", () => { res.body.should.have.property("owner").and.be.string; res.body.should.have.property("type").and.equal("raw"); res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("instrumentId").and.be.string; + res.body.should.have.property("proposalId").and.be.string; + res.body.should.have.property("sampleId").and.be.string; pid = encodeURIComponent(res.body["pid"]); }); }); diff --git a/test/TestData.js b/test/TestData.js index 84a7090cb..09c806577 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -232,6 +232,8 @@ const TestData = { ownerGroup: "p13388", accessGroups: [], proposalId: "10.540.16635/20110123", + instrumentId: "1f016ec4-7a73-11ef-ae3e-439013069377", + sampleId: "20c32b4e-7a73-11ef-9aec-5b9688aa3791i", type: "raw", keywords: ["sls", "protein"], }, From 6ac5cc6ac0bd74e56bd2e471c49957500a8a33fb Mon Sep 17 00:00:00 2001 From: junjiequan Date: Wed, 25 Sep 2024 13:20:56 +0200 Subject: [PATCH 255/258] refactor: enable versioing for routes --- src/config/configuration.ts | 2 +- src/main.ts | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/config/configuration.ts b/src/config/configuration.ts index 96e9e9bbd..94a190d89 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -59,7 +59,7 @@ const configuration = () => { const config = { versions: { - api: "v3", + api: "3", }, swaggerPath: process.env.SWAGGER_PATH || "explorer", loggerConfigs: jsonConfigMap.loggers || [defaultLogger], diff --git a/src/main.ts b/src/main.ts index 980dc66a8..3af41b802 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,7 +7,7 @@ import { SwaggerModule, } from "@nestjs/swagger"; import { AppModule } from "./app.module"; -import { Logger, ValidationPipe } from "@nestjs/common"; +import { Logger, ValidationPipe, VersioningType } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { AllExceptionsFilter, ScicatLogger } from "./loggers/logger.service"; @@ -29,11 +29,20 @@ async function bootstrap() { app.enableCors(); - app.setGlobalPrefix(`api/${apiVersion}`); + app.setGlobalPrefix("api"); + + // NOTE: This is a workaround to enable versioning for individual routes + // Version decorator can be used to specify the version for a route + // Read more on https://docs.nestjs.com/techniques/versioning + app.enableVersioning({ + type: VersioningType.URI, + defaultVersion: apiVersion, + }); + const config = new DocumentBuilder() .setTitle("SciCat backend API") .setDescription("This is the API for the SciCat Backend") - .setVersion(`api/${apiVersion}`) + .setVersion(`api/v${apiVersion}`) .addBearerAuth() .build(); From 2e9763b4a6fccfef9c24a32f1ddea161327f2d67 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Wed, 25 Sep 2024 16:34:40 +0200 Subject: [PATCH 256/258] fixed obsolete dataset dtos --- src/datasets/datasets.controller.ts | 37 ++++++++++--------- .../dto/output-dataset-obsolete.dto.ts | 16 ++++---- .../dto/update-dataset-obsolete.dto.ts | 9 +++++ .../dto/update-raw-dataset-obsolete.dto.ts | 16 ++++---- test/DerivedDataset.js | 3 ++ test/OrigDatablockForRawDataset.js | 1 - test/TestData.js | 3 ++ 7 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/datasets/datasets.controller.ts b/src/datasets/datasets.controller.ts index ba6faa208..2f9491244 100644 --- a/src/datasets/datasets.controller.ts +++ b/src/datasets/datasets.controller.ts @@ -409,16 +409,16 @@ export class DatasetsController { version: "v3", }; + if ("proposalId" in inputObsoleteDataset) { + propertiesModifier.proposalIds = [ + (inputObsoleteDataset as CreateRawDatasetObsoleteDto).proposalId, + ]; + } if ( inputObsoleteDataset instanceof CreateRawDatasetObsoleteDto || inputObsoleteDataset instanceof UpdateRawDatasetObsoleteDto || inputObsoleteDataset instanceof PartialUpdateRawDatasetObsoleteDto ) { - if ("proposalId" in inputObsoleteDataset) { - propertiesModifier.proposalIds = [ - (inputObsoleteDataset as CreateRawDatasetObsoleteDto).proposalId, - ]; - } if ("sampleId" in inputObsoleteDataset) { propertiesModifier.sampleIds = [ (inputObsoleteDataset as CreateRawDatasetObsoleteDto).sampleId, @@ -476,15 +476,15 @@ export class DatasetsController { const propertiesModifier: Record = {}; if (inputDataset) { if ("proposalIds" in inputDataset) { - propertiesModifier.proposalIds = inputDataset.proposalIds![0]; + propertiesModifier.proposalId = inputDataset.proposalIds![0]; } if ("sampleIds" in inputDataset) { - propertiesModifier.sampleIds = inputDataset.sampleIds![0]; + propertiesModifier.sampleId = inputDataset.sampleIds![0]; } if ("instrumentIds" in inputDataset) { - propertiesModifier.instrumentIds = inputDataset.instrumentIds![0]; + propertiesModifier.instrumentId = inputDataset.instrumentIds![0]; } - if (inputDataset.type == "raw") { + if (inputDataset.type == "derived") { if ("investigator" in inputDataset) { propertiesModifier.investigator = inputDataset.principalInvestigator; } @@ -499,7 +499,7 @@ export class DatasetsController { return outputDataset; } - // POST /datasets + // POST https://scicat.ess.eu/api/v3/datasets @UseGuards(PoliciesGuard) @CheckPolicies("datasets", (ability: AppAbility) => ability.can(Action.DatasetCreate, DatasetClass), @@ -739,15 +739,16 @@ export class DatasetsController { ) as IFilters; // this should be implemented at database level - const datasets = (await this.datasetsService.findAll( - mergedFilters, - )) as OutputDatasetObsoleteDto[]; + const datasets = await this.datasetsService.findAll(mergedFilters); + let outputDatasets: OutputDatasetObsoleteDto[] = []; if (datasets && datasets.length > 0) { const includeFilters = mergedFilters.include ?? []; + outputDatasets = datasets.map((dataset) => + this.convertCurrentToObsoleteSchema(dataset), + ); await Promise.all( - datasets.map(async (dataset) => { - dataset = this.convertCurrentToObsoleteSchema(dataset); - if (includeFilters) { + outputDatasets.map(async (dataset) => { + if (includeFilters) { await Promise.all( includeFilters.map(async ({ relation }) => { switch (relation) { @@ -781,7 +782,7 @@ export class DatasetsController { }), ); } - return datasets; + return outputDatasets; } // GET /datasets/fullquery @@ -1170,7 +1171,7 @@ export class DatasetsController { await this.checkPermissionsForDatasetObsolete(request, id), ); - return this.convertCurrentToObsoleteSchema(dataset) as OutputDatasetObsoleteDto; + return dataset as OutputDatasetObsoleteDto; } // PATCH /datasets/:id diff --git a/src/datasets/dto/output-dataset-obsolete.dto.ts b/src/datasets/dto/output-dataset-obsolete.dto.ts index dced6bc31..bb511edcd 100644 --- a/src/datasets/dto/output-dataset-obsolete.dto.ts +++ b/src/datasets/dto/output-dataset-obsolete.dto.ts @@ -92,14 +92,14 @@ export class OutputDatasetObsoleteDto extends UpdateDatasetObsoleteDto { @IsString() readonly dataFormat?: string; - @ApiProperty({ - type: String, - required: false, - description: "The ID of the proposal to which the dataset belongs.", - }) - @IsOptional() - @IsString() - readonly proposalId?: string; + // @ApiProperty({ + // type: String, + // required: false, + // description: "The ID of the proposal to which the dataset belongs.", + // }) + // @IsOptional() + // @IsString() + // readonly proposalId?: string; @ApiProperty({ type: String, diff --git a/src/datasets/dto/update-dataset-obsolete.dto.ts b/src/datasets/dto/update-dataset-obsolete.dto.ts index ac0e996c8..73f4b34bd 100644 --- a/src/datasets/dto/update-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-dataset-obsolete.dto.ts @@ -288,6 +288,15 @@ export class UpdateDatasetObsoleteDto extends OwnableDto { @IsOptional() @IsNumber() readonly dataQualityMetrics?: number; + + @ApiProperty({ + type: String, + required: false, + description: "The ID of the proposal to which the dataset belongs.", + }) + @IsOptional() + @IsString() + readonly proposalId?: string; } export class PartialUpdateDatasetObsoleteDto extends PartialType( diff --git a/src/datasets/dto/update-raw-dataset-obsolete.dto.ts b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts index 50096b914..075406908 100644 --- a/src/datasets/dto/update-raw-dataset-obsolete.dto.ts +++ b/src/datasets/dto/update-raw-dataset-obsolete.dto.ts @@ -52,14 +52,14 @@ export class UpdateRawDatasetObsoleteDto extends UpdateDatasetObsoleteDto { @IsString() readonly dataFormat?: string; - @ApiProperty({ - type: String, - required: false, - description: "The ID of the proposal to which the dataset belongs.", - }) - @IsOptional() - @IsString() - readonly proposalId?: string; + // @ApiProperty({ + // type: String, + // required: false, + // description: "The ID of the proposal to which the dataset belongs.", + // }) + // @IsOptional() + // @IsString() + // readonly proposalId?: string; @ApiProperty({ type: String, diff --git a/test/DerivedDataset.js b/test/DerivedDataset.js index 1ccadc9ce..7e4c2e6ce 100644 --- a/test/DerivedDataset.js +++ b/test/DerivedDataset.js @@ -99,6 +99,9 @@ describe("0700: DerivedDataset: Derived Datasets", () => { .and.be.equal(TestData.DerivedCorrect.owner); res.body.should.have.property("type").and.be.equal("derived"); res.body.should.have.property("pid").and.be.string; + res.body.should.have.property("proposalId").and.be.string; + //res.body.should.have.property("sampleId").and.be.string; + //res.body.should.have.property("instrumentId").and.be.string; pid = res.body["pid"]; }); }); diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index 859b49333..d329d5867 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -304,7 +304,6 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) .then((res) => { - console.log(res.body); res.body["pid"].should.be.equal(decodeURIComponent(datasetPid1)); res.body.origdatablocks.should.be .instanceof(Array) diff --git a/test/TestData.js b/test/TestData.js index 09c806577..801a45768 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -453,6 +453,9 @@ const TestData = { ownerGroup: "p34123", accessGroups: [], type: "derived", + proposalId: "10.540.16635/20110123", + //instrumentId: "1f016ec4-7a73-11ef-ae3e-439013069377", + //sampleId: "20c32b4e-7a73-11ef-9aec-5b9688aa3791i", }, DerivedWrong: { From dc9929248db2f56d62f5c56773ac19cd2ff0d662 Mon Sep 17 00:00:00 2001 From: Max Novelli Date: Fri, 27 Sep 2024 11:51:31 +0200 Subject: [PATCH 257/258] removed commented field from dataset dto --- src/datasets/dto/output-dataset-obsolete.dto.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/datasets/dto/output-dataset-obsolete.dto.ts b/src/datasets/dto/output-dataset-obsolete.dto.ts index bb511edcd..f99a7fe94 100644 --- a/src/datasets/dto/output-dataset-obsolete.dto.ts +++ b/src/datasets/dto/output-dataset-obsolete.dto.ts @@ -92,15 +92,6 @@ export class OutputDatasetObsoleteDto extends UpdateDatasetObsoleteDto { @IsString() readonly dataFormat?: string; - // @ApiProperty({ - // type: String, - // required: false, - // description: "The ID of the proposal to which the dataset belongs.", - // }) - // @IsOptional() - // @IsString() - // readonly proposalId?: string; - @ApiProperty({ type: String, required: false, From 707e9e85c379f2880bb0e6610ebd7322a7d3bcfc Mon Sep 17 00:00:00 2001 From: Jay Date: Fri, 4 Oct 2024 07:44:11 +0200 Subject: [PATCH 258/258] fix: handle logbook room not found without throwing an error. (#1434) --- src/logbooks/logbooks.service.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/logbooks/logbooks.service.ts b/src/logbooks/logbooks.service.ts index 133c0a784..344596c5a 100644 --- a/src/logbooks/logbooks.service.ts +++ b/src/logbooks/logbooks.service.ts @@ -66,6 +66,11 @@ export class LogbooksService { ), ); + if (!res.data) { + Logger.log("Logbook not found", { name }); + return null; + } + Logger.log("Found logbook " + name, "LogbooksService.findByName"); const { skip, limit, sortField } = JSON.parse(filters); Logger.log(