Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 23-a-valider-avec-erwan-check-plus-precis-du-cnfs-id-ainsi-que-des-plages-de-rdv-ouvertes
  • 484-statistiques-requete
  • 50-exception-handling
  • V2.5
  • client-476-add-localization-filter
  • dependencies/nestjs
  • dev
  • master
  • openshift-test-deploy
  • pnpm
  • renovate/bitnami-mongodb-4.x
  • renovate/bitnami-mongodb-8.x
  • renovate/devdependencies-(non-major)
  • renovate/elasticsearch-7.x
  • renovate/eslint-9.x
  • renovate/eslint-plugin-jsdoc-50.x
  • renovate/express-5.x
  • renovate/ghost-5.x
  • renovate/gouvfr-anct-timetable-to-osm-opening-hours-2.x
  • renovate/jest-29.x
  • renovate/jest-junit-16.x
  • renovate/luxon-3.x
  • renovate/major-jest-monorepo
  • renovate/major-nest-monorepo
  • renovate/major-typescript-eslint-monorepo
  • renovate/mongo-express-1.x
  • renovate/mysql-9.x
  • renovate/nestjs-schematics-11.x
  • renovate/npm-11.x
  • renovate/tsconfig-paths-4.x
  • send-mail-to-structure-after-orientation
  • tests/users-controllers
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.13.0
  • v1.15.0
  • v1.15.1
  • v1.16.0
  • v1.17.0
  • v1.2.0
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.6.0
  • v1.6.1
  • v1.7.0
  • v1.8.0
  • v1.9.0
  • v1.9.1
  • v2.0.0
  • v2.0.0-beta1
  • v2.0.0-beta1.1
  • v2.0.0-beta2
  • v2.0.0-beta3
  • v2.0.0-beta4
  • v2.0.0-beta5
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.1.0
  • v2.1.1
  • v2.1.2
  • v2.1.3
  • v2.2.0
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.5.0
  • v3.0.0
  • v3.0.1
  • v3.1.0
  • v3.2.0
  • v3.3.0
  • v3.3.1
  • v3.4.0
  • v3.4.1
  • v3.4.2
  • v3.4.3
  • v4.0.0
84 results

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server
1 result
Select Git revision
  • 23-a-valider-avec-erwan-check-plus-precis-du-cnfs-id-ainsi-que-des-plages-de-rdv-ouvertes
  • 484-statistiques-requete
  • 50-exception-handling
  • V2.5
  • client-476-add-localization-filter
  • dependencies/nestjs
  • dev
  • master
  • openshift-test-deploy
  • pnpm
  • renovate/bitnami-mongodb-4.x
  • renovate/bitnami-mongodb-8.x
  • renovate/devdependencies-(non-major)
  • renovate/elasticsearch-7.x
  • renovate/eslint-9.x
  • renovate/eslint-plugin-jsdoc-50.x
  • renovate/express-5.x
  • renovate/ghost-5.x
  • renovate/gouvfr-anct-timetable-to-osm-opening-hours-2.x
  • renovate/jest-29.x
  • renovate/jest-junit-16.x
  • renovate/luxon-3.x
  • renovate/major-jest-monorepo
  • renovate/major-nest-monorepo
  • renovate/major-typescript-eslint-monorepo
  • renovate/mongo-express-1.x
  • renovate/mysql-9.x
  • renovate/nestjs-schematics-11.x
  • renovate/npm-11.x
  • renovate/tsconfig-paths-4.x
  • send-mail-to-structure-after-orientation
  • tests/users-controllers
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.13.0
  • v1.15.0
  • v1.15.1
  • v1.16.0
  • v1.17.0
  • v1.2.0
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.6.0
  • v1.6.1
  • v1.7.0
  • v1.8.0
  • v1.9.0
  • v1.9.1
  • v2.0.0
  • v2.0.0-beta1
  • v2.0.0-beta1.1
  • v2.0.0-beta2
  • v2.0.0-beta3
  • v2.0.0-beta4
  • v2.0.0-beta5
  • v2.0.1
  • v2.0.2
  • v2.0.3
  • v2.1.0
  • v2.1.1
  • v2.1.2
  • v2.1.3
  • v2.2.0
  • v2.3.0
  • v2.3.1
  • v2.3.2
  • v2.4.0
  • v2.4.1
  • v2.4.2
  • v2.5.0
  • v3.0.0
  • v3.0.1
  • v3.1.0
  • v3.2.0
  • v3.3.0
  • v3.3.1
  • v3.4.0
  • v3.4.1
  • v3.4.2
  • v3.4.3
  • v4.0.0
84 results
Show changes
Commits on Source (87)
Showing
with 3544 additions and 5434 deletions
stages: stages:
- quality
- test - test
- quality
- build - build
- deploy - deploy
...@@ -8,9 +8,6 @@ default: ...@@ -8,9 +8,6 @@ default:
services: services:
- name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09-dind - name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09-dind
alias: docker alias: docker
- name: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/elasticsearch:7.16.2
alias: elasticsearch
command: ['bin/elasticsearch', '-Expack.security.enabled=false', '-Ediscovery.type=single-node']
variables: variables:
DEPENDENCY_PROXY: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/ DEPENDENCY_PROXY: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/
...@@ -39,6 +36,7 @@ build_branch: ...@@ -39,6 +36,7 @@ build_branch:
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09 image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09
stage: build stage: build
only: only:
- V2.0
- merge_requests - merge_requests
script: script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
...@@ -51,8 +49,6 @@ build-release: ...@@ -51,8 +49,6 @@ build-release:
DOCKER_HOST: tcp://docker:2375/ DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09 image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/docker:18.09
services:
- ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/:18.09-dind
stage: build stage: build
only: only:
- tags - tags
...@@ -67,6 +63,7 @@ deploy_dev: ...@@ -67,6 +63,7 @@ deploy_dev:
- deploy - deploy
only: only:
- dev - dev
- V2.0
script: script:
- cd /home/mps/ram - cd /home/mps/ram
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
......
## Description du problème
_Donnez une briève description du problème_
## L'environnement
#### Utilisez vous l'application sur :
- [ ] Mobile
- [ ] Ordinateur
##### En cas de mobile
###### Quel type de mobile utilisez-vous?
- [ ] Android
- [ ] Iphone
###### Quel navigateur utilisez-vous?
- [ ] Chrome
- [ ] Safari
- [ ] Autre
##### En cas d'ordinateur
###### Quel navigateur utilisez-vous?
- [ ] Chrome
- [ ] Firefox
- [ ] Safari
- [ ] Autre
## Le bug
#### Quelles sont les étapes qui ont menées au problème?
_Donnez une description des étapes, il est fortemment conseillé de l'accompagner par des captures d'écran_
#### Quel est le comportement obtenu?
_Donnez une description du comportement obtenu, il est fortemment conseillé de l'accompagner par des captures d'écran_
#### Quel est le comportement attendu?
_Donnez une description du comportement attendu_
| :triangular_flag_on_post: Give your MR the same name that the desired squash commit. In doubt, check the conventional commit [doc](https://www.conventionalcommits.org/en/v1.0.0/).|
| --- |
## What does this MR do and why? ## What does this MR do and why?
_Describe in detail what your merge request does and why._ _Describe in detail what your merge request does and why._
| :warning: Keep an up to date checklist based on your icescrum tasks during all the draft phase to help any other developer who would take the job after you to finish it. | | :warning: Keep an up to date checklist based on your icescrum tasks during all the draft phase of the MR to help any other developer who would take the job after you to finish it.|
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --- |
## Screenshots or screen recordings ## Screenshots or screen recordings
_These are strongly recommended to assist reviewers and reduce the time to merge your change._ _These are strongly recommended to assist reviewers and reduce the time to merge your change._
## How to set up and validate locally (or on alpha) ## How to set up and validate locally (or on alpha)
_List all steps to set up and validate the changes on local environment._ _List all steps to set up and validate the changes on local environment._
## MR acceptance checklist ## MR acceptance checklist
_To be completed by the chosen reviewer._ _To be completed by the chosen reviewer._
<!--- <!---
...@@ -25,11 +27,12 @@ More reading on checklists can be found in the "Checklist Manifesto": http://atu ...@@ -25,11 +27,12 @@ More reading on checklists can be found in the "Checklist Manifesto": http://atu
"It is common to misconceive how checklists function in complex lines of work. They are not comprehensive how-to guides, whether for building a skyscraper or getting a plane out of trouble. They are quick and simple tools aimed to buttress the skills of expert professionals." - Gawande, Atul. The Checklist Manifesto "It is common to misconceive how checklists function in complex lines of work. They are not comprehensive how-to guides, whether for building a skyscraper or getting a plane out of trouble. They are quick and simple tools aimed to buttress the skills of expert professionals." - Gawande, Atul. The Checklist Manifesto
---> --->
### Quality
- [ ] Confirmed ### Quality [![Bugs](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=ram_server&metric=bugs&token=ac7a374a553a3aa458e5b538ce1a85c4fba146fb)](https://sonarqube.forge.grandlyon.com/dashboard?id=ram_server) - [![Code Smells](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=ram_server&metric=code_smells&token=ac7a374a553a3aa458e5b538ce1a85c4fba146fb)](https://sonarqube.forge.grandlyon.com/dashboard?id=ram_server)
* [ ] Confirmed
1. For the code that this change impacts, I believe that the automated tests validate functionality that is highly important to users. If the existing automated tests do not cover this functionality, I have added the necessary additional tests or I have added an issue to describe the automation testing gap and linked it to this MR. 1. For the code that this change impacts, I believe that the automated tests validate functionality that is highly important to users. If the existing automated tests do not cover this functionality, I have added the necessary additional tests or I have added an issue to describe the automation testing gap and linked it to this MR.
1. I have made sure that the sonar quality coverage is up to standards. 1. I have made sure that the sonar quality coverage is up to standards.
1. I have considered the impact of this change on the front-end, back-end, and database portions of the system where appropriate and applied. 1. I have considered the impact of this change on the front-end, back-end, and database portions of the system where appropriate and applied.
1. I have tested this MR in all supported browsers or determined that this testing is not needed. 1. I have tested this MR in all supported browsers or determined that this testing is not needed.
...@@ -37,26 +40,26 @@ More reading on checklists can be found in the "Checklist Manifesto": http://atu ...@@ -37,26 +40,26 @@ More reading on checklists can be found in the "Checklist Manifesto": http://atu
### Performance, reliability and availability ### Performance, reliability and availability
- [ ] Confirmed * [ ] Confirmed
1. I am confident that this MR does not harm performance, or I have asked a reviewer to help assess the performance impact. 1. I am confident that this MR does not harm performance, or I have asked a reviewer to help assess the performance impact.
1. I have considered the scalability risk based on future predicted growth. 1. I have considered the scalability risk based on future predicted growth.
### Documentation ### Documentation
- [ ] Confirmed * [ ] Confirmed
1. I have prepared a squash commit to feed the changelog linked to the current milestone. 1. The MR is named after the desired squash commit to feed the changelog linked to the current milestone.
1. I have added/updated documentation (also updated if the changes feature a deprecation) or I have decided that documentation changes are not needed for this MR. 1. I have added/updated documentation (also updated if the changes feature a deprecation) or I have decided that documentation changes are not needed for this MR.
### Security ### Security [![Security Rating](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=ram_server&metric=security_rating&token=ac7a374a553a3aa458e5b538ce1a85c4fba146fb)](https://sonarqube.forge.grandlyon.com/dashboard?id=ram_server)
- [ ] Confirmed * [ ] Confirmed
1. I have confirmed that if this MR does not contains any sensitive informations hidden in the changes. 1. I have confirmed that if this MR does not contains any sensitive informations hidden in the changes.
### Deployment ### Deployment
- [ ] Confirmed * [ ] Confirmed
1. When featured on a self-data project release, i have made sure my app version in the manifest and package.json is incremented and any relative changes to the permissions are clearly written and transmitted to Cozy. 1. When featured on a self-data project release, i have made sure my app version in the manifest and package.json is incremented and any relative changes to the permissions are clearly written and transmitted to Cozy.
...@@ -2,6 +2,112 @@ ...@@ -2,6 +2,112 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [2.0.0-beta3](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.17.0...v2.0.0-beta3) (2022-10-03)
### Features
* **annuaire:** Add userRegistry endpoint for research ([b19bbf3](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/b19bbf3dcb1e1dc699b023642ed243e62b74dd6c))
* **newsletter:** implementation of mailchimp ([b7f300f](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/b7f300fd8c108ad9205d446d960694c52872b328))
* patch unique property of a structure US162 ([c01dca0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/c01dca0992f3d982b6037cce6b930b9711917ba3))
* **profile:** add structure owners screen ([5d4002d](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/5d4002dd3d8b1f1557fc42dac8d4283723821399))
* **profile:** logged in users can access the profile of other users ([e717cdc](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/e717cdcae246e7af56e9602a23c3390807e6097b))
* structure mail notification reset and new handling ([a039487](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/a039487316c7af1e4a57d4f3417bc59637d55993))
* **structure:** remove useless await ([f657205](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f65720593f6657036f07530aa0dcbccd98ec1547))
* **structure:** remove useless server lockdown filter ([41a5d80](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/41a5d8024e5a3f957a271625208bb9c481a5a6e8))
### Bug Fixes
* **annuaire:** Fix case one job an no employer for user ([9600225](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/9600225645b2b6ccfeb5aa487e58a38c6e7cd93d))
* **annuaire:** Remove unverified users from list ([c234fe0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/c234fe09f2c73d566a50b886d38c1a094f0774a5))
* **cicd:** update V2.0 job ([b18cb37](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/b18cb376f25acff6cef26e88bb8c0b7c9656b4e7))
* **deps:** update dependency passport to ^0.6.0 ([cfd143c](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/cfd143c813d800166637ff7f375eca4d5aff1ec4))
* **init:** accompanements order ([9c2efce](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/9c2efce483b02d322cec26630459029526c587c7))
* release build issue ([1d551d8](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/1d551d8618c74d0c9ece8f0613df280cf6586927))
* **search:** add java option to limit es ram use ([25b2529](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/25b2529a056427744352521c5e026ad2c45ef0dd))
* **structureDto:** phone number is now optional ([36a32ad](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/36a32adfb0157eab551ec47b5fda48e04b49d86e))
## [2.0.0-beta2](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v2.0.0-beta1.1...v2.0.0-beta2) (2022-05-24)
### Features
* **admin:** administration panel for jobs and employers ([7ed53e7](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/7ed53e756546b424248f004cf7af9da558a1a434))
* **edit-profile:** edit profile page ([23bde5d](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/23bde5dbcd50620fc946c7663518040b92ee8c48))
* **structure:** Get more info about structure owner details ([08f9c75](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/08f9c7539af7dc93d25fb7c97f8320b95f62b618))
### Bug Fixes
* auth issue with reading env var ([f46b600](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f46b6003f87ad808a15bf174ff22059b9c9c52f3))
* **dependencies:** update minor version to fix vulnerabilities ([629eeab](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/629eeabd8e3f7ddbdf503027059ad69282a2f925))
* **deps:** update dependency class-validator to ^0.13.0 ([95f7189](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/95f71895ff46ea8bfb2f98f55e4753159a504239))
* elastic unit test ([641e484](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/641e4849ccf324efaa64ba0e164753709361b2d2))
## [2.0.0-beta1.1](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v2.0.0-beta1...v2.0.0-beta1.1) (2022-04-04)
### Bug Fixes
* **structures:** fix structure création issue for equipments and userverification ([f46d545](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f46d54551a34476e2d320492c58347bb4cb3c90c))
## [2.0.0-beta1](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.16.0...v2.0.0-beta1) (2022-03-29)
### Features
* **jobs:** add filtering of unvalidated jobs ([2d98fc6](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/2d98fc6689d5759c8affda3183a7fffe10c3be55))
* **onboarding:** add structure search by name with improved french analyzer ([b0d2e9b](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/b0d2e9b555409a5c07857939ab2bab969354c90b))
* **personalOffers:** create personal offers endpoints ([ba6f7db](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/ba6f7dbd7faf31ebb00177cc6ed78f02fa1d387f))
### Bug Fixes
* **gitlab-ci:** update V2.0 autodeploy ([17b77c7](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/17b77c72541b2932b37658e232dd9dc631728e30))
* **swagger:** routing definition ([d264a4e](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/d264a4eedda9253e46300ba2fee8bcb9289be086))
## [2.0.0-beta2](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v2.0.0-beta1.1...v2.0.0-beta2) (2022-05-24)
### Features
* **admin:** administration panel for jobs and employers ([7ed53e7](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/7ed53e756546b424248f004cf7af9da558a1a434))
* **admin:** now display last update date next to structure names ([01d5665](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/01d56659ebd323105dcfa46a9bbb929e482fc05c))
* **digital helps:** rename "Accompagnement CAF" to "CAF" ([90e106f](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/90e106f572ea52d990a67b49f00fe434965cc083))
* **edit-profile:** edit profile page ([23bde5d](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/23bde5dbcd50620fc946c7663518040b92ee8c48))
* **structure:** Get more info about structure owner details ([08f9c75](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/08f9c7539af7dc93d25fb7c97f8320b95f62b618))
### Bug Fixes
* auth issue with reading env var ([f46b600](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f46b6003f87ad808a15bf174ff22059b9c9c52f3))
* **dependencies:** update minor version to fix vulnerabilities ([629eeab](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/629eeabd8e3f7ddbdf503027059ad69282a2f925))
* **deps:** update dependency class-validator to ^0.13.0 ([95f7189](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/95f71895ff46ea8bfb2f98f55e4753159a504239))
* elastic unit test ([641e484](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/641e4849ccf324efaa64ba0e164753709361b2d2))
* Resolve "Join validation issue for admin" and refactor of string to date for structure updatedAt and createdAt ([df74738](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/df747380f58b5f093265c185b357e666792c04a9))
* sonar ([a222df2](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/a222df249f85d780e31f24e79d52431f4eada6b4))
## [2.0.0-beta1.1](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v2.0.0-beta1...v2.0.0-beta1.1) (2022-04-04)
### Bug Fixes
* **structures:** fix structure création issue for equipments and userverification ([f46d545](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/f46d54551a34476e2d320492c58347bb4cb3c90c))
## [2.0.0-beta1](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.16.0...v2.0.0-beta1) (2022-03-29)
### Features
* **jobs:** add filtering of unvalidated jobs ([2d98fc6](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/2d98fc6689d5759c8affda3183a7fffe10c3be55))
* **onboarding:** add structure search by name with improved french analyzer ([b0d2e9b](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/b0d2e9b555409a5c07857939ab2bab969354c90b))
* **personalOffers:** create personal offers endpoints ([ba6f7db](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/ba6f7dbd7faf31ebb00177cc6ed78f02fa1d387f))
### Bug Fixes
* **gitlab-ci:** update V2.0 autodeploy ([17b77c7](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/17b77c72541b2932b37658e232dd9dc631728e30))
* **swagger:** routing definition ([d264a4e](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/d264a4eedda9253e46300ba2fee8bcb9289be086))
## [1.17.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.16.0...v1.17.0) (2022-05-30) ## [1.17.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.16.0...v1.17.0) (2022-05-30)
......
FROM node:12.13-slim FROM node:14.20-slim
# Create app directory # Create app directory
WORKDIR /app WORKDIR /app
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest [circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p> <p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center"> <p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a> <a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
...@@ -47,7 +47,6 @@ $ npm install ...@@ -47,7 +47,6 @@ $ npm install
### Base de donnée ### Base de donnée
```bash ```bash
$ docker-compose up -d database-ram $ docker-compose up -d database-ram
$ docker-compose up -d mongo-express $ docker-compose up -d mongo-express
...@@ -70,17 +69,20 @@ $ npm run start:prod ...@@ -70,17 +69,20 @@ $ npm run start:prod
```bash ```bash
# Lien vers le swagger # Lien vers le swagger
$ http://localhost:3000/api $ http://localhost:3000/doc
# Lien vers le mongo-express # Lien vers le mongo-express
$ http://localhost:8081 $ http://localhost:8081
``` ```
## Documentation ## Documentation
A documentation is generated with compodoc in addition of the existing documentation on the wiki. A documentation is generated with compodoc in addition of the existing documentation on the wiki.
```sh ```sh
npm run doc:serve npm run doc:serve
``` ```
You can now visualize it at : `localhost:8080` You can now visualize it at : `localhost:8080`
## Test ## Test
......
...@@ -106,6 +106,7 @@ services: ...@@ -106,6 +106,7 @@ services:
discovery.type: single-node discovery.type: single-node
xpack.security.enabled: ${ELASTIC_SECURITY} xpack.security.enabled: ${ELASTIC_SECURITY}
ELASTIC_PASSWORD: ${ELASTICSEARCH_PASSWORD} ELASTIC_PASSWORD: ${ELASTICSEARCH_PASSWORD}
ES_JAVA_OPTS: '-Xms512m -Xmx512m'
volumes: volumes:
- db-elastic:/usr/share/elasticsearch/data - db-elastic:/usr/share/elasticsearch/data
networks: networks:
...@@ -113,22 +114,6 @@ services: ...@@ -113,22 +114,6 @@ services:
ports: ports:
- ${ELASTICSEARCH_PORT}:9200 - ${ELASTICSEARCH_PORT}:9200
kib01:
image: docker.elastic.co/kibana/kibana:7.6.1
restart: unless-stopped
container_name: resin-kib
ports:
- ${KIBANA_PORT}:5601
environment:
ELASTICSEARCH_URL: http://es01:9200
ELASTICSEARCH_HOSTS: '["http://es01:9200"]'
ELASTICSEARCH_USERNAME: elastic
ELASTICSEARCH_PASSWORD: ${ELASTICSEARCH_PASSWORD}
depends_on:
- es01
networks:
- elastic
volumes: volumes:
db-ram: db-ram:
driver: local driver: local
......
This diff is collapsed.
{ {
"name": "ram_server", "name": "ram_server",
"private": true, "private": true,
"version": "1.17.0", "version": "2.0.0-beta3",
"description": "Nest TypeScript starter repository", "description": "Nest TypeScript starter repository",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"release": "standard-version", "release": "standard-version",
"init-db": "node ./scripts/init-db.js", "init-db": "node ./scripts/init-db.js",
"test": "jest", "test": "jest --config ./test/jest.json --coverage",
"test:watch": "jest --config ./test/jest.json --watch", "test:watch": "jest --config ./test/jest.json --watch --coverage",
"test:cov": "jest --config ./test/jest.json --coverage --ci --reporters=default --reporters=jest-junit", "test:cov": "jest --config ./test/jest.json --coverage --ci --reporters=default --reporters=jest-junit",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json", "test:e2e": "jest --config ./test/jest-e2e.json",
...@@ -28,28 +28,31 @@ ...@@ -28,28 +28,31 @@
}, },
"dependencies": { "dependencies": {
"@elastic/elasticsearch": "^7.12.0", "@elastic/elasticsearch": "^7.12.0",
"@nestjs/common": "^7.6.13", "@mailchimp/mailchimp_marketing": "^3.0.78",
"@nestjs/axios": "^0.1.0",
"@nestjs/common": "^9.0.11",
"@nestjs/config": "^0.6.3", "@nestjs/config": "^0.6.3",
"@nestjs/core": "^7.5.1", "@nestjs/core": "^9.0.11",
"@nestjs/elasticsearch": "^7.1.0", "@nestjs/elasticsearch": "^7.1.0",
"@nestjs/jwt": "^7.2.0", "@nestjs/jwt": "^7.2.0",
"@nestjs/mongoose": "^7.1.0", "@nestjs/mongoose": "^7.1.0",
"@nestjs/passport": "^7.1.5", "@nestjs/passport": "^7.1.5",
"@nestjs/platform-express": "^7.5.1", "@nestjs/platform-express": "^9.0.11",
"@nestjs/schedule": "^0.4.1", "@nestjs/schedule": "^0.4.1",
"@nestjs/swagger": "^4.7.5", "@nestjs/swagger": "^6.1.2",
"@tryghost/admin-api": "^1.4.4", "@tryghost/admin-api": "^1.4.4",
"@types/bcrypt": "^3.0.0", "@types/bcrypt": "^3.0.0",
"axios": "^0.27.2",
"bcrypt": "^5.0.1", "bcrypt": "^5.0.1",
"class-transformer": "^0.3.1", "class-transformer": "^0.3.1",
"class-validator": "^0.12.2", "class-validator": "^0.13.0",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"ejs": "^3.1.6", "ejs": "^3.1.7",
"form-data": "^3.0.0", "form-data": "^3.0.0",
"luxon": "^1.25.0", "luxon": "^1.25.0",
"migrate": "^1.7.0", "migrate": "^1.7.0",
"mongoose": "^5.10.15", "mongoose": "^5.10.15",
"passport": "^0.4.1", "passport": "^0.6.0",
"passport-jwt": "^4.0.0", "passport-jwt": "^4.0.0",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
...@@ -62,28 +65,28 @@ ...@@ -62,28 +65,28 @@
"devDependencies": { "devDependencies": {
"@compodoc/compodoc": "^1.1.16", "@compodoc/compodoc": "^1.1.16",
"@golevelup/ts-jest": "^0.3.2", "@golevelup/ts-jest": "^0.3.2",
"@nestjs/cli": "^7.5.1", "@nestjs/cli": "^9.1.3",
"@nestjs/schematics": "^7.1.3", "@nestjs/schematics": "^9.0.3",
"@nestjs/testing": "^7.5.1", "@nestjs/testing": "^9.0.11",
"@types/express": "^4.17.8", "@types/express": "^4.17.8",
"@types/jest": "^26.0.15", "@types/jest": "^26.0.15",
"@types/mongoose": "^5.10.1", "@types/mongoose": "^5.10.1",
"@types/node": "^14.14.6", "@types/node": "^14.14.6",
"@types/passport-local": "^1.0.33", "@types/passport-local": "^1.0.33",
"@types/supertest": "^2.0.10", "@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.6.1", "@typescript-eslint/eslint-plugin": "^5.37",
"@typescript-eslint/parser": "^4.6.1", "@typescript-eslint/parser": "^5.37",
"eslint": "^7.12.1", "eslint": "^8.0.0",
"eslint-config-prettier": "^6.15.0", "eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4", "eslint-plugin-prettier": "^4.0.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"jest-junit": "^12.0.0", "jest-junit": "^14.0.0",
"nodemon": "^2.0.6", "nodemon": "^2.0.6",
"prettier": "^2.1.2", "prettier": "^2.1.2",
"supertest": "^6.0.0", "supertest": "^6.0.0",
"ts-jest": "^26.4.3", "ts-jest": "^26.4.3",
"ts-loader": "^8.0.8", "ts-loader": "^8.0.8",
"ts-node": "^9.0.0", "ts-node": "^10.9.1",
"tsconfig-paths": "^3.9.0", "tsconfig-paths": "^3.9.0",
"typescript": "^4.0.5" "typescript": "^4.0.5"
}, },
......
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>systemes-dinformation/renovate/renovate-config"
]
}
...@@ -8,16 +8,20 @@ module.exports = { ...@@ -8,16 +8,20 @@ module.exports = {
modules: [ modules: [
{ {
id: 'accompagnantCaf', id: 'accompagnantCaf',
text: 'Accompagnant CAF', text: 'CAF',
}, },
{ {
id: 'poleEmploi', id: 'carsat',
text: 'Pôle Emploi', text: 'CARSAT',
}, },
{ {
id: 'cpam', id: 'cpam',
text: 'CPAM', text: 'CPAM',
}, },
{
id: 'demarcheMetropolitaine',
text: 'Démarches Métropolitaines',
},
{ {
id: 'impots', id: 'impots',
text: 'Impôts', text: 'Impôts',
...@@ -27,12 +31,8 @@ module.exports = { ...@@ -27,12 +31,8 @@ module.exports = {
text: 'Logement', text: 'Logement',
}, },
{ {
id: 'carsat', id: 'poleEmploi',
text: 'CARSAT', text: 'Pôle Emploi',
},
{
id: 'demarcheMetropolitaine',
text: 'Démarches Métropolitaines',
}, },
{ {
id: 'autres', id: 'autres',
......
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mongoose = require('mongoose');
module.exports = {
data: [
{
_id: mongoose.Types.ObjectId('6285289d02c9259438c802d3'),
name: 'Association',
validated: true,
},
{
_id: mongoose.Types.ObjectId('62867faf7a5b13480c22b2fc'),
name: 'CAF',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac3'),
name: 'CARSAT',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac4'),
name: 'CCAS',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac5'),
name: 'CPAM',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac6'),
name: 'Centre socio-culturel',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac7'),
name: 'Cyberbase',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac8'),
name: 'Espace de coworking',
validated: true,
},
{
_id: mongoose.Types.ObjectId('628dfc353a0f370acc450ac9'),
name: 'Fablab',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca830'),
name: 'MJC',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca831'),
name: 'Mairie',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca832'),
name: 'Maison France Service',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca833'),
name: 'Missions locales',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca834'),
name: 'Médiathèque / Bibliothèque',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca835'),
name: 'Métropole de Lyon',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca836'),
name: 'Pimms',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca837'),
name: 'Pôle emploi',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca838'),
name: 'Ressourcerie',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca839'),
name: "Structure d'insertion",
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca83a'),
name: 'Structure de formation',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca83b'),
name: 'Structure information jeunesse (SIJ)',
validated: true,
},
],
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
const mongoose = require('mongoose');
module.exports = {
data: [
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca845'),
hasPersonalOffer: true,
name: 'Formateur',
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca846'),
name: 'CNFS',
hasPersonalOffer: true,
validated: true,
},
{
_id: mongoose.Types.ObjectId('627b6ca899862168705ca847'),
hasPersonalOffer: true,
name: 'Médiateur numérique',
validated: true,
},
{
hasPersonalOffer: false,
_id: mongoose.Types.ObjectId('627b6ca899862168705ca848'),
name: 'Travailleur social',
validated: true,
},
{
hasPersonalOffer: false,
_id: mongoose.Types.ObjectId('627b6ca899862168705ca849'),
name: 'Conseiller',
validated: true,
},
{
hasPersonalOffer: false,
_id: mongoose.Types.ObjectId('627b6ca899862168705ca84a'),
name: 'Chef de projet',
validated: true,
},
{
hasPersonalOffer: false,
_id: mongoose.Types.ObjectId('6283603c51d1098fd4a8facf'),
name: 'Élu',
validated: true,
},
],
};
...@@ -45,7 +45,7 @@ module.exports = { ...@@ -45,7 +45,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:00', closing: '12:00',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:30', closing: '17:30',
...@@ -71,7 +71,7 @@ module.exports = { ...@@ -71,7 +71,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:00', closing: '12:00',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:30', closing: '17:30',
...@@ -84,7 +84,7 @@ module.exports = { ...@@ -84,7 +84,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:00', closing: '12:00',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:30', closing: '17:30',
...@@ -97,7 +97,7 @@ module.exports = { ...@@ -97,7 +97,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:00', closing: '12:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -367,7 +367,7 @@ module.exports = { ...@@ -367,7 +367,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:30', closing: '12:30',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:00', closing: '17:00',
...@@ -380,7 +380,7 @@ module.exports = { ...@@ -380,7 +380,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:30', closing: '12:30',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:00', closing: '17:00',
...@@ -393,7 +393,7 @@ module.exports = { ...@@ -393,7 +393,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:30', closing: '12:30',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:00', closing: '17:00',
...@@ -406,7 +406,7 @@ module.exports = { ...@@ -406,7 +406,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:30', closing: '12:30',
opening: '9:00', opening: '09:00',
}, },
{ {
closing: '17:00', closing: '17:00',
...@@ -419,7 +419,7 @@ module.exports = { ...@@ -419,7 +419,7 @@ module.exports = {
time: [ time: [
{ {
closing: '12:30', closing: '12:30',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -698,7 +698,7 @@ module.exports = { ...@@ -698,7 +698,7 @@ module.exports = {
time: [ time: [
{ {
closing: '17:00', closing: '17:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -707,7 +707,7 @@ module.exports = { ...@@ -707,7 +707,7 @@ module.exports = {
time: [ time: [
{ {
closing: '17:00', closing: '17:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -716,7 +716,7 @@ module.exports = { ...@@ -716,7 +716,7 @@ module.exports = {
time: [ time: [
{ {
closing: '17:00', closing: '17:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -725,7 +725,7 @@ module.exports = { ...@@ -725,7 +725,7 @@ module.exports = {
time: [ time: [
{ {
closing: '17:00', closing: '17:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
...@@ -734,7 +734,7 @@ module.exports = { ...@@ -734,7 +734,7 @@ module.exports = {
time: [ time: [
{ {
closing: '17:00', closing: '17:00',
opening: '9:00', opening: '09:00',
}, },
], ],
}, },
......
...@@ -17,6 +17,8 @@ module.exports = { ...@@ -17,6 +17,8 @@ module.exports = {
emailVerified: true, emailVerified: true,
email: 'admin@admin.com', email: 'admin@admin.com',
structureOutdatedMailSent: [], structureOutdatedMailSent: [],
employer: mongoose.Types.ObjectId('627b6ca899862168705ca836'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca846'),
}, },
{ {
structureOutdatedMailSent: [], structureOutdatedMailSent: [],
...@@ -28,10 +30,12 @@ module.exports = { ...@@ -28,10 +30,12 @@ module.exports = {
resetPasswordToken: null, resetPasswordToken: null,
validationToken: null, validationToken: null,
emailVerified: true, emailVerified: true,
email: 'paula.dubois@mii.com', email: 'paula.dubois@test.com',
name: 'Paula', name: 'Paula',
surname: 'DUBOIS', surname: 'DUBOIS',
phone: '06 07 08 09 10', phone: '06 07 08 09 10',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca836'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca846'),
}, },
{ {
structureOutdatedMailSent: [], structureOutdatedMailSent: [],
...@@ -52,6 +56,128 @@ module.exports = { ...@@ -52,6 +56,128 @@ module.exports = {
name: 'Jean-Paul', name: 'Jean-Paul',
surname: 'DESCHAMPS', surname: 'DESCHAMPS',
phone: '06 11 11 11 11', phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca835'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca848'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'marine.ducanal@test.com',
name: 'Marine',
surname: 'DUCANAL',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca837'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca848'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'hugo.nouts@test.com',
name: 'Hugo',
surname: 'NOUTS',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca833'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca846'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'bastien.dumont@test.com',
name: 'Bastien',
surname: 'DUMONT',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca835'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca849'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'guilhem.carron@test.com',
name: 'Guilhem',
surname: 'CARRON',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca834'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca848'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'hugo.subtil@test.com',
name: 'Hugo',
surname: 'SUBTIL',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca835'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca846'),
},
{
structureOutdatedMailSent: [],
pendingStructuresLink: [],
structuresLink: [
mongoose.Types.ObjectId('61e9260c2ac971550065e262'),
mongoose.Types.ObjectId('61e9260b2ac971550065e261'),
],
newEmail: null,
changeEmailToken: null,
role: 0,
resetPasswordToken: null,
validationToken: null,
emailVerified: true,
email: 'remi.pailharey@test.com',
name: 'Rémi',
surname: 'PAILHAREY',
phone: '06 11 11 11 11',
employer: mongoose.Types.ObjectId('627b6ca899862168705ca835'),
job: mongoose.Types.ObjectId('627b6ca899862168705ca845'),
}, },
], ],
}; };
/* eslint-disable @typescript-eslint/no-var-requires */
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const mongoose = require('mongoose'); const mongoose = require('mongoose');
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
...@@ -7,6 +8,8 @@ const categoriesOthersData = require('./data/categoriesOthers'); ...@@ -7,6 +8,8 @@ const categoriesOthersData = require('./data/categoriesOthers');
const categoriesAccompanementsData = require('./data/categoriesAccompanements'); const categoriesAccompanementsData = require('./data/categoriesAccompanements');
const categoriesFormationData = require('./data/categoriesFormation'); const categoriesFormationData = require('./data/categoriesFormation');
const structuresData = require('./data/structures'); const structuresData = require('./data/structures');
const jobsData = require('./data/jobs');
const employersData = require('./data/employers');
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
...@@ -40,8 +43,9 @@ const handleError = async (name, err) => { ...@@ -40,8 +43,9 @@ const handleError = async (name, err) => {
else throw err; else throw err;
} else console.log(`-- ${name} collection dropped --`); } else console.log(`-- ${name} collection dropped --`);
}; };
// define Schema // define Schema
var usersSchema = mongoose.Schema({ const usersSchema = mongoose.Schema({
name: String, name: String,
surname: String, surname: String,
email: String, email: String,
...@@ -56,30 +60,50 @@ var usersSchema = mongoose.Schema({ ...@@ -56,30 +60,50 @@ var usersSchema = mongoose.Schema({
pendingStructuresLink: [], pendingStructuresLink: [],
password: String, password: String,
phone: String, phone: String,
employer: String,
job: String,
}); });
var structuresTypeSchema = mongoose.Schema(
const jobsSchema = mongoose.Schema(
{
name: String,
hasPersonalOffer: Boolean,
validated: Boolean,
},
{ collection: 'jobs' }
);
const employersSchema = mongoose.Schema(
{
name: String,
validated: Boolean,
},
{ collection: 'employers' }
);
const structuresTypeSchema = mongoose.Schema(
{ {
name: String, name: String,
values: [], values: [],
}, },
{ collection: 'structuretype' } { collection: 'structuretype' }
); );
var categoriesOthersSchema = mongoose.Schema({ const categoriesOthersSchema = mongoose.Schema({
name: String, name: String,
id: String, id: String,
modules: [], modules: [],
}); });
var categoriesAccompanementsSchema = mongoose.Schema({ const categoriesAccompanementsSchema = mongoose.Schema({
name: String, name: String,
id: String, id: String,
modules: [], modules: [],
}); });
var categoriesFormationSchema = mongoose.Schema({ const categoriesFormationSchema = mongoose.Schema({
name: String, name: String,
id: String, id: String,
modules: [], modules: [],
}); });
var structuresSchema = mongoose.Schema({ const structuresSchema = mongoose.Schema({
numero: String, numero: String,
createdAt: String, createdAt: String,
updatedAt: String, updatedAt: String,
...@@ -123,12 +147,14 @@ var structuresSchema = mongoose.Schema({ ...@@ -123,12 +147,14 @@ var structuresSchema = mongoose.Schema({
}); });
// compile schema to model // compile schema to model
var User = mongoose.model('Users', usersSchema); const user = mongoose.model('users', usersSchema);
var structuresType = mongoose.model('structureType', structuresTypeSchema); const structuresType = mongoose.model('structureType', structuresTypeSchema);
var categoriesOthers = mongoose.model('categoriesOthers', categoriesOthersSchema); const categoriesOthers = mongoose.model('categoriesOthers', categoriesOthersSchema);
var categoriesAccompanements = mongoose.model('CategoriesAccompagnement', categoriesAccompanementsSchema); const categoriesAccompanements = mongoose.model('CategoriesAccompagnement', categoriesAccompanementsSchema);
var categoriesFormation = mongoose.model('categoriesFormation', categoriesFormationSchema); const categoriesFormation = mongoose.model('categoriesFormation', categoriesFormationSchema);
var structures = mongoose.model('structures', structuresSchema); const structures = mongoose.model('structures', structuresSchema);
const jobs = mongoose.model('jobs', jobsSchema);
const employers = mongoose.model('employers', employersSchema);
/* drop users collections */ /* drop users collections */
mongoose.connection.dropCollection('users', async (err) => { mongoose.connection.dropCollection('users', async (err) => {
...@@ -140,7 +166,7 @@ mongoose.connection.dropCollection('users', async (err) => { ...@@ -140,7 +166,7 @@ mongoose.connection.dropCollection('users', async (err) => {
user.password = hashPassword(); user.password = hashPassword();
}); });
// save model to database // save model to database
User.create(userData.data, function (error, user) { user.create(userData.data, (error) => {
if (error) return console.error(error); if (error) return console.error(error);
console.log('-- Users collection initialized --'); console.log('-- Users collection initialized --');
}); });
...@@ -180,6 +206,20 @@ mongoose.connection.dropCollection('structures', async (err) => { ...@@ -180,6 +206,20 @@ mongoose.connection.dropCollection('structures', async (err) => {
await handleError('structures', err); await handleError('structures', err);
structures.create(structuresData.data, (error) => { structures.create(structuresData.data, (error) => {
if (error) return console.error(error); if (error) return console.error(error);
});
});
/* Create structures */
mongoose.connection.dropCollection('jobs', async (err) => {
await handleError('jobs', err);
jobs.create(jobsData.data, (error) => {
if (error) return console.error(error);
});
});
/* Create structures */
mongoose.connection.dropCollection('employers', async (err) => {
await handleError('employers', err);
employers.create(employersData.data, (error) => {
if (error) return console.error(error);
process.exit(0); process.exit(0);
}); });
}); });
...@@ -14,7 +14,25 @@ axios ...@@ -14,7 +14,25 @@ axios
axios axios
.post('http://localhost:3000/api/structures/resetSearchIndex', {}, config) .post('http://localhost:3000/api/structures/resetSearchIndex', {}, config)
.then((res) => { .then((res) => {
console.log(`statusCode: ${res.status}`); console.log(`Structures | statusCode: ${res.status}`);
})
.catch((error) => {
console.error('Error in index create');
console.error(error);
});
axios
.post('http://localhost:3000/api/employer/searchIndex', {}, config)
.then((res) => {
console.log(`Employers | statusCode: ${res.status}`);
})
.catch((error) => {
console.error('Error in index create');
console.error(error);
});
axios
.post('http://localhost:3000/api/userRegistry/searchIndex', {}, config)
.then((res) => {
console.log(`Users | statusCode: ${res.status}`);
}) })
.catch((error) => { .catch((error) => {
console.error('Error in index create'); console.error('Error in index create');
......
import { HttpModule } from '@nestjs/common'; import { HttpModule } from '@nestjs/axios';
import { getModelToken } from '@nestjs/mongoose'; import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { Types } from 'mongoose';
import { mockJwtAuthGuard } from '../../test/mock/guards/jwt-auth.mock.guard'; import { mockJwtAuthGuard } from '../../test/mock/guards/jwt-auth.mock.guard';
import { mockRoleGuard } from '../../test/mock/guards/role.mock.guard'; import { mockRoleGuard } from '../../test/mock/guards/role.mock.guard';
import { NewsletterServiceMock } from '../../test/mock/services/newsletter.mock.service'; import { NewsletterServiceMock } from '../../test/mock/services/newsletter.mock.service';
...@@ -17,12 +18,50 @@ import { StructuresSearchService } from '../structures/services/structures-searc ...@@ -17,12 +18,50 @@ import { StructuresSearchService } from '../structures/services/structures-searc
import { StructuresService } from '../structures/services/structures.service'; import { StructuresService } from '../structures/services/structures.service';
import { RolesGuard } from '../users/guards/roles.guard'; import { RolesGuard } from '../users/guards/roles.guard';
import { User } from '../users/schemas/user.schema'; import { User } from '../users/schemas/user.schema';
import { UsersService } from '../users/users.service'; import { EmployerSearchService } from '../users/services/employer-search.service';
import { EmployerService } from '../users/services/employer.service';
import { JobsService } from '../users/services/jobs.service';
import { UsersService } from '../users/services/users.service';
import { AdminController } from './admin.controller'; import { AdminController } from './admin.controller';
import { AdminService } from './admin.service'; import { AdminService } from './admin.service';
describe('AdminController', () => { describe('AdminController', () => {
let controller: AdminController; let controller: AdminController;
let userService: UsersService;
const mockEmployerSearchService = {
indexEmployer: jest.fn(),
search: jest.fn(),
dropIndex: jest.fn(),
createEmployerIndex: jest.fn(),
deleteIndex: jest.fn(),
};
const mockEmployerService = {
findOne: jest.fn(),
deleteOneId: jest.fn(),
findByName: jest.fn(),
findAllValidated: jest.fn(),
findAllUnvalidated: jest.fn(),
createEmployerFromAdmin: jest.fn(),
validate: jest.fn(),
update: jest.fn(),
mergeEmployer: jest.fn(),
deleteInvalidEmployer: jest.fn(),
};
const mockJobService = {
findOne: jest.fn(),
findByName: jest.fn(),
deleteOneId: jest.fn(),
findAll: jest.fn(),
findAllUnvalidated: jest.fn(),
createJobFromAdmin: jest.fn(),
validate: jest.fn(),
update: jest.fn(),
mergeJob: jest.fn(),
deleteInvalidJob: jest.fn(),
};
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
...@@ -46,6 +85,18 @@ describe('AdminController', () => { ...@@ -46,6 +85,18 @@ describe('AdminController', () => {
}, },
StructuresSearchService, StructuresSearchService,
MailerService, MailerService,
{
provide: EmployerService,
useValue: mockEmployerService,
},
{
provide: JobsService,
useValue: mockJobService,
},
{
provide: EmployerSearchService,
useValue: mockEmployerSearchService,
},
{ {
provide: getModelToken('User'), provide: getModelToken('User'),
useValue: User, useValue: User,
...@@ -68,6 +119,7 @@ describe('AdminController', () => { ...@@ -68,6 +119,7 @@ describe('AdminController', () => {
.compile(); .compile();
controller = module.get<AdminController>(AdminController); controller = module.get<AdminController>(AdminController);
userService = module.get<UsersService>(UsersService);
}); });
it('should be defined', () => { it('should be defined', () => {
...@@ -153,6 +205,134 @@ describe('AdminController', () => { ...@@ -153,6 +205,134 @@ describe('AdminController', () => {
}); });
}); });
describe('setUserEmployer', () => {
it('should set a new employer to the user', async () => {
const spyer = jest.spyOn(userService, 'updateUserEmployer');
const mockUserId = '6231aefe76598527c8d0b5bc';
const mockEmployer = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Sopra',
validated: true,
};
mockEmployerService.findOne.mockResolvedValueOnce(mockEmployer);
const reply = await controller.setUserEmployer({
userId: mockUserId,
employerId: String(mockEmployer._id),
});
expect(spyer).toBeCalledTimes(1);
expect(spyer).toBeCalledWith(mockUserId, mockEmployer);
expect(reply).toBeTruthy();
});
it('should not set a new employer to the user if the employer does not exist', async () => {
const spyer = jest.spyOn(userService, 'updateUserEmployer');
const mockUserId = '6231aefe76598527c8d0b5bc';
const mockEmployer = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Sopra',
validated: true,
};
mockEmployerService.findOne.mockResolvedValueOnce(null);
try {
await controller.setUserEmployer({
userId: mockUserId,
employerId: String(mockEmployer._id),
});
expect(true).toBe(false);
} catch (e) {
expect(spyer).toBeCalledTimes(0);
expect(e.message).toBe('Employer does not exist');
expect(e.status).toBe(400);
}
});
it('should not set a new employer to the user if the user does not exist', async () => {
const spyer = jest.spyOn(userService, 'updateUserEmployer');
const mockUserId = 'thisuserdoesnotexist';
const mockEmployer = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Sopra',
validated: true,
};
mockEmployerService.findOne.mockResolvedValueOnce(mockEmployer);
try {
await controller.setUserEmployer({
userId: mockUserId,
employerId: String(mockEmployer._id),
});
expect(true).toBe(false);
} catch (e) {
expect(spyer).toBeCalledTimes(0);
expect(e.message).toBe('User does not exist');
expect(e.status).toBe(400);
}
});
});
describe('setUserJob', () => {
it('should set a new job to the user', async () => {
const spyer = jest.spyOn(userService, 'updateUserJob');
const mockUserId = '6231aefe76598527c8d0b5bc';
const mockJob = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Toto',
validated: true,
};
mockJobService.findOne.mockResolvedValueOnce(mockJob);
const reply = await controller.setUserJob({
userId: mockUserId,
jobId: String(mockJob._id),
});
expect(spyer).toBeCalledTimes(1);
expect(spyer).toBeCalledWith(mockUserId, mockJob);
expect(reply).toBeTruthy();
});
it('should not set a new job to the user if the job does not exist', async () => {
const spyer = jest.spyOn(userService, 'updateUserJob');
const mockUserId = '6231aefe76598527c8d0b5bc';
const mockJob = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Dev',
validated: true,
};
mockJobService.findOne.mockResolvedValueOnce(null);
try {
await controller.setUserJob({
userId: mockUserId,
jobId: String(mockJob._id),
});
expect(true).toBe(false);
} catch (e) {
expect(spyer).toBeCalledTimes(0);
expect(e.message).toBe('Job does not exist');
expect(e.status).toBe(400);
}
});
it('should not set a new job to the user if the user does not exist', async () => {
const spyer = jest.spyOn(userService, 'updateUserJob');
const mockUserId = 'thisuserdoesntexist';
const mockJob = {
_id: Types.ObjectId('6231aefe76598527c8d0b5ba'),
name: 'Dev',
validated: true,
};
mockJobService.findOne.mockResolvedValueOnce(mockJob);
try {
await controller.setUserJob({
userId: mockUserId,
jobId: String(mockJob._id),
});
expect(true).toBe(false);
} catch (e) {
expect(spyer).toBeCalledTimes(0);
expect(e.message).toBe('User does not exist');
expect(e.status).toBe(400);
}
});
});
describe('Search user', () => { describe('Search user', () => {
it('should return all users, empty string', async () => { it('should return all users, empty string', async () => {
expect((await controller.searchUsers({ searchString: '' })).length).toBe(2); expect((await controller.searchUsers({ searchString: '' })).length).toBe(2);
...@@ -169,7 +349,7 @@ describe('AdminController', () => { ...@@ -169,7 +349,7 @@ describe('AdminController', () => {
}); });
}); });
describe('Search user newleetter subscription', () => { describe('Search user newsletter subscription', () => {
it('should return all subscribed users, empty string', async () => { it('should return all subscribed users, empty string', async () => {
expect((await controller.getNewsletterSubscriptions({ searchString: '' })).length).toBe(3); expect((await controller.getNewsletterSubscriptions({ searchString: '' })).length).toBe(3);
}); });
......
...@@ -8,9 +8,10 @@ import { ...@@ -8,9 +8,10 @@ import {
Logger, Logger,
Param, Param,
Post, Post,
Put,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { ApiOperation, ApiParam } from '@nestjs/swagger'; import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { validate } from 'class-validator'; import { validate } from 'class-validator';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { NewsletterSubscription } from '../newsletter/newsletter-subscription.schema'; import { NewsletterSubscription } from '../newsletter/newsletter-subscription.schema';
...@@ -20,16 +21,23 @@ import { StructuresService } from '../structures/services/structures.service'; ...@@ -20,16 +21,23 @@ import { StructuresService } from '../structures/services/structures.service';
import { Roles } from '../users/decorators/roles.decorator'; import { Roles } from '../users/decorators/roles.decorator';
import { RolesGuard } from '../users/guards/roles.guard'; import { RolesGuard } from '../users/guards/roles.guard';
import { IUser } from '../users/interfaces/user.interface'; import { IUser } from '../users/interfaces/user.interface';
import { UsersService } from '../users/users.service'; import { EmployerService } from '../users/services/employer.service';
import { JobsService } from '../users/services/jobs.service';
import { UsersService } from '../users/services/users.service';
import { AdminService } from './admin.service'; import { AdminService } from './admin.service';
import { PendingStructureDto } from './dto/pending-structure.dto'; import { PendingStructureDto } from './dto/pending-structure.dto';
import { SetUserEmployerDto } from './dto/set-user-employer.dto';
import { SetUserJobDto } from './dto/set-user-job.dto';
@ApiTags('admin')
@Controller('admin') @Controller('admin')
export class AdminController { export class AdminController {
private readonly logger = new Logger(AdminController.name); private readonly logger = new Logger(AdminController.name);
constructor( constructor(
private usersService: UsersService, private usersService: UsersService,
private structuresService: StructuresService, private structuresService: StructuresService,
private jobsService: JobsService,
private employerService: EmployerService,
private newsletterService: NewsletterService, private newsletterService: NewsletterService,
private adminService: AdminService private adminService: AdminService
) {} ) {}
...@@ -37,7 +45,7 @@ export class AdminController { ...@@ -37,7 +45,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Get('pendingStructures') @Get('pendingStructures')
@ApiOperation({ description: 'Get pending structre for validation' }) @ApiOperation({ description: 'Get pending structures for validation' })
public async getPendingAttachments(): Promise<PendingStructureDto[]> { public async getPendingAttachments(): Promise<PendingStructureDto[]> {
const pendingStructure = await this.usersService.getPendingStructures(); const pendingStructure = await this.usersService.getPendingStructures();
return Promise.all( return Promise.all(
...@@ -54,7 +62,7 @@ export class AdminController { ...@@ -54,7 +62,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Get('adminStructuresList') @Get('adminStructuresList')
@ApiOperation({ description: 'Get pending structre for validation' }) @ApiOperation({ description: 'Get pending structures for validation' })
public async getAdminStructuresList(): Promise<any> { public async getAdminStructuresList(): Promise<any> {
this.logger.debug('getAdminStructuresList'); this.logger.debug('getAdminStructuresList');
const structuresList = { claimed: [], inClaim: [], toClaim: [], incomplete: [] }; const structuresList = { claimed: [], inClaim: [], toClaim: [], incomplete: [] };
...@@ -177,6 +185,7 @@ export class AdminController { ...@@ -177,6 +185,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Delete('user/:id') @Delete('user/:id')
@ApiBearerAuth('JWT')
@ApiParam({ name: 'id', type: String, required: true }) @ApiParam({ name: 'id', type: String, required: true })
public async deleteUser(@Param() params) { public async deleteUser(@Param() params) {
const user = await this.usersService.deleteOneId(params.id); const user = await this.usersService.deleteOneId(params.id);
...@@ -192,6 +201,7 @@ export class AdminController { ...@@ -192,6 +201,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@ApiBearerAuth('JWT')
@Post('searchUsers') @Post('searchUsers')
public async searchUsers(@Body() searchString: { searchString: string }) { public async searchUsers(@Body() searchString: { searchString: string }) {
if (searchString && searchString.searchString && searchString.searchString.length > 0) if (searchString && searchString.searchString && searchString.searchString.length > 0)
...@@ -201,14 +211,29 @@ export class AdminController { ...@@ -201,14 +211,29 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Get('getUnAttachedUsers') @ApiBearerAuth('JWT')
@Get('unAttachedUsers')
public async findUnattachedUsers() { public async findUnattachedUsers() {
return this.usersService.findAllUnattached(); return this.usersService.findAllUnattached().then((formatUsers) => {
return formatUsers.map((user) => {
return {
id: user._id,
createdAt: user.createdAt ? user.createdAt.toLocaleDateString() : '',
surname: user.surname,
name: user.name,
email: user.email,
phone: user.phone,
job: user.job,
employer: user.employer,
};
});
});
} }
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Get('getAttachedUsers') @ApiBearerAuth('JWT')
@Get('attachedUsers')
public async findAttachedUsers() { public async findAttachedUsers() {
return this.usersService.findAllAttached().then(async (users: IUser[]) => { return this.usersService.findAllAttached().then(async (users: IUser[]) => {
return this.structuresService.getAllUserCompletedStructures(users); return this.structuresService.getAllUserCompletedStructures(users);
...@@ -216,8 +241,9 @@ export class AdminController { ...@@ -216,8 +241,9 @@ export class AdminController {
} }
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth('JWT')
@Roles('admin') @Roles('admin')
@Get('getUnVerifiedUsers') @Get('unVerifiedUsers')
public async findUnVerifiedUsers() { public async findUnVerifiedUsers() {
return this.usersService.findAllUnVerified().then(async (users: IUser[]) => { return this.usersService.findAllUnVerified().then(async (users: IUser[]) => {
return this.structuresService.getAllUserCompletedStructures(users); return this.structuresService.getAllUserCompletedStructures(users);
...@@ -226,6 +252,7 @@ export class AdminController { ...@@ -226,6 +252,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@ApiBearerAuth('JWT')
@Post('searchNewsletterSubscriptions') @Post('searchNewsletterSubscriptions')
public async getNewsletterSubscriptions(@Body() searchString: { searchString: string }) { public async getNewsletterSubscriptions(@Body() searchString: { searchString: string }) {
if (searchString && searchString.searchString && searchString.searchString.length > 0) if (searchString && searchString.searchString && searchString.searchString.length > 0)
...@@ -235,6 +262,7 @@ export class AdminController { ...@@ -235,6 +262,7 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@ApiBearerAuth('JWT')
@Get('countNewsletterSubscriptions') @Get('countNewsletterSubscriptions')
public async countNewsletterSubscriptions(): Promise<number> { public async countNewsletterSubscriptions(): Promise<number> {
return this.newsletterService.countNewsletterSubscriptions(); return this.newsletterService.countNewsletterSubscriptions();
...@@ -242,9 +270,60 @@ export class AdminController { ...@@ -242,9 +270,60 @@ export class AdminController {
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@ApiBearerAuth('JWT')
@Delete('newsletterSubscription/:email') @Delete('newsletterSubscription/:email')
@ApiParam({ name: 'email', type: String, required: true }) @ApiParam({ name: 'email', type: String, required: true })
public async unsubscribeUserFromNewsletter(@Param() params): Promise<NewsletterSubscription> { public async unsubscribeUserFromNewsletter(@Param() params): Promise<NewsletterSubscription> {
return this.newsletterService.newsletterUnsubscribe(params.email); return this.newsletterService.newsletterUnsubscribe(params.email);
} }
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth('JWT')
@ApiOperation({ description: 'Set user job' })
@ApiResponse({ status: HttpStatus.OK, description: 'Return user profile' })
@ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'User does not exist' })
@ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Job does not exist' })
@Put('setUserJob')
public async setUserJob(@Body() setUserJob: SetUserJobDto): Promise<IUser> {
this.logger.debug(`setUserJob`);
const jobDocument = await this.jobsService.findOne(setUserJob.jobId);
if (!jobDocument) {
this.logger.warn(`Job does not exist: ${setUserJob.jobId}`);
throw new HttpException('Job does not exist', HttpStatus.BAD_REQUEST);
}
const userDocument = await this.usersService.findById(setUserJob.userId);
if (!userDocument) {
this.logger.warn(`User does not exist: ${setUserJob.userId}`);
throw new HttpException('User does not exist', HttpStatus.BAD_REQUEST);
}
await this.usersService.updateUserJob(userDocument._id, jobDocument);
return this.usersService.findById(setUserJob.userId);
}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth('JWT')
@ApiOperation({ description: 'Set user employer' })
@ApiResponse({ status: HttpStatus.OK, description: 'Return user profile' })
@ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'User does not exist' })
@ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Employer does not exist' })
@Put('setUserEmployer')
public async setUserEmployer(@Body() setUserEmployer: SetUserEmployerDto): Promise<IUser> {
this.logger.debug(`setUserEmployer`);
const employerDocument = await this.employerService.findOne(setUserEmployer.employerId);
if (!employerDocument) {
this.logger.warn(`Employer does not exist: ${setUserEmployer.employerId}`);
throw new HttpException('Employer does not exist', HttpStatus.BAD_REQUEST);
}
const userDocument = await this.usersService.findById(setUserEmployer.userId);
if (!userDocument) {
this.logger.warn(`User does not exist: ${setUserEmployer.userId}`);
throw new HttpException('User does not exist', HttpStatus.BAD_REQUEST);
}
await this.usersService.updateUserEmployer(userDocument._id, employerDocument);
return this.usersService.findById(setUserEmployer.userId);
}
} }
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';
export class MergeEmployerDto {
@IsNotEmpty()
@ApiProperty({ type: String })
sourceEmployerId: string;
@IsNotEmpty()
@ApiProperty({ type: String })
targetEmployerId: string;
}