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

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server
1 result
Show changes
Commits on Source (18)
Showing
with 292 additions and 41 deletions
...@@ -2,6 +2,25 @@ ...@@ -2,6 +2,25 @@
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.
## [1.12.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.11.0...v1.12.0) (2022-02-01)
### Features
* **contact:** send email ([04438c2](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/04438c2610f5fc75b15bd5314c291ad74dc94c40))
* **structure:** add label alert in mail for duplicate ([c0d0cf7](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/c0d0cf764e6bf4271657078bd1cb6a4079ed08b8))
* **structure:** change addresse api in order to cover the all department. /photon is now used instead of /photon-bal ([ed4e89a](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/ed4e89a8854ba5f882b22a84daffcc8100394cca))
### Bug Fixes
* add of package.json inside build was making app start fail ([0f09089](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/0f09089f59274dd5d7133c6276ab34f01b879a9a))
* **contact:** add MAIL_CONTACT in docker-compose.yml ([1dfb071](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/1dfb071406eb60b31aa4c0306c4fde434bdeca87))
* **contact:** delete labels in email ([68aa6c8](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/68aa6c8e16f647d9faaf2f4d2b4a8d0dda1da319))
* mail configuration and remove unecessary code ([ffac0d1](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/ffac0d136e30052caa768dfa94ef4b0db7b4ee36))
* **post:** refacto of image url replace ([37989bf](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/37989bfa7aa1f21cf19aa7107d364a1826c839fc))
* **structure:** typo duplicate structure email ([0199113](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/commit/0199113b8084a07ccb2af9d063e907718d4fc4fe))
## [1.11.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.10.0...v1.11.0) (2022-01-12) ## [1.11.0](https://forge.grandlyon.com/web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server/compare/v1.10.0...v1.11.0) (2022-01-12)
......
...@@ -17,6 +17,7 @@ services: ...@@ -17,6 +17,7 @@ services:
SALT: ${SALT} SALT: ${SALT}
MAIL_URL: ${MAIL_URL} MAIL_URL: ${MAIL_URL}
MAIL_TOKEN: ${MAIL_TOKEN} MAIL_TOKEN: ${MAIL_TOKEN}
MAIL_CONTACT: ${MAIL_CONTACT}
NODE_ENV: ${NODE_ENV} NODE_ENV: ${NODE_ENV}
APTIC_TOKEN: ${APTIC_TOKEN} APTIC_TOKEN: ${APTIC_TOKEN}
GHOST_HOST_AND_PORT: ${GHOST_HOST_AND_PORT} GHOST_HOST_AND_PORT: ${GHOST_HOST_AND_PORT}
......
{ {
"name": "ram_server", "name": "ram_server",
"version": "1.11.0", "version": "1.12.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
...@@ -8982,8 +8982,7 @@ ...@@ -8982,8 +8982,7 @@
"deepmerge": { "deepmerge": {
"version": "4.2.2", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
"dev": true
}, },
"defaults": { "defaults": {
"version": "1.0.3", "version": "1.0.3",
...@@ -9174,7 +9173,6 @@ ...@@ -9174,7 +9173,6 @@
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"dev": true,
"requires": { "requires": {
"domelementtype": "^2.0.1", "domelementtype": "^2.0.1",
"domhandler": "^4.2.0", "domhandler": "^4.2.0",
...@@ -9190,8 +9188,7 @@ ...@@ -9190,8 +9188,7 @@
"domelementtype": { "domelementtype": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
"dev": true
}, },
"domexception": { "domexception": {
"version": "2.0.1", "version": "2.0.1",
...@@ -9214,7 +9211,6 @@ ...@@ -9214,7 +9211,6 @@
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
"integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
"dev": true,
"requires": { "requires": {
"domelementtype": "^2.2.0" "domelementtype": "^2.2.0"
} }
...@@ -9223,7 +9219,6 @@ ...@@ -9223,7 +9219,6 @@
"version": "2.8.0", "version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"requires": { "requires": {
"dom-serializer": "^1.0.1", "dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0", "domelementtype": "^2.2.0",
...@@ -9374,9 +9369,9 @@ ...@@ -9374,9 +9369,9 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
}, },
"ejs": { "ejs": {
"version": "3.1.5", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"requires": { "requires": {
"jake": "^10.6.1" "jake": "^10.6.1"
} }
...@@ -9469,8 +9464,7 @@ ...@@ -9469,8 +9464,7 @@
"entities": { "entities": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
"dev": true
}, },
"errno": { "errno": {
"version": "0.1.7", "version": "0.1.7",
...@@ -10375,9 +10369,9 @@ ...@@ -10375,9 +10369,9 @@
"optional": true "optional": true
}, },
"filelist": { "filelist": {
"version": "1.0.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
"integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==", "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
"requires": { "requires": {
"minimatch": "^3.0.4" "minimatch": "^3.0.4"
} }
...@@ -11322,7 +11316,6 @@ ...@@ -11322,7 +11316,6 @@
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"dev": true,
"requires": { "requires": {
"domelementtype": "^2.0.1", "domelementtype": "^2.0.1",
"domhandler": "^4.0.0", "domhandler": "^4.0.0",
...@@ -14697,6 +14690,11 @@ ...@@ -14697,6 +14690,11 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"nanoid": {
"version": "3.1.32",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.32.tgz",
"integrity": "sha512-F8mf7R3iT9bvThBoW4tGXhXFHCctyCiUUPrWF8WaTqa3h96d9QybkSeba43XVOOE3oiLfkVDe4bT8MeGmkrTxw=="
},
"nanomatch": { "nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
...@@ -15443,6 +15441,11 @@ ...@@ -15443,6 +15441,11 @@
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
"dev": true "dev": true
}, },
"parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
"integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE="
},
"parse5-htmlparser2-tree-adapter": { "parse5-htmlparser2-tree-adapter": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
...@@ -15600,8 +15603,7 @@ ...@@ -15600,8 +15603,7 @@
"picocolors": { "picocolors": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
"dev": true
}, },
"picomatch": { "picomatch": {
"version": "2.2.2", "version": "2.2.2",
...@@ -15651,6 +15653,16 @@ ...@@ -15651,6 +15653,16 @@
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
"dev": true "dev": true
}, },
"postcss": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"requires": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.1"
}
},
"prelude-ls": { "prelude-ls": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
...@@ -16410,6 +16422,31 @@ ...@@ -16410,6 +16422,31 @@
} }
} }
}, },
"sanitize-html": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.6.1.tgz",
"integrity": "sha512-DzjSz3H5qDntD7s1TcWCSoRPmNR8UmA+y+xZQOvWgjATe2Br9ZW73+vD3Pj6Snrg0RuEuJdXgrKvnYuiuixRkA==",
"requires": {
"deepmerge": "^4.2.2",
"escape-string-regexp": "^4.0.0",
"htmlparser2": "^6.0.0",
"is-plain-object": "^5.0.0",
"parse-srcset": "^1.0.2",
"postcss": "^8.3.11"
},
"dependencies": {
"escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
}
}
},
"saslprep": { "saslprep": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
...@@ -16836,6 +16873,11 @@ ...@@ -16836,6 +16873,11 @@
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true "dev": true
}, },
"source-map-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA=="
},
"source-map-resolve": { "source-map-resolve": {
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
......
{ {
"name": "ram_server", "name": "ram_server",
"private": true, "private": true,
"version": "1.11.0", "version": "1.12.0",
"description": "Nest TypeScript starter repository", "description": "Nest TypeScript starter repository",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
"start": "ts-node -r tsconfig-paths/register src/main.ts", "start": "ts-node -r tsconfig-paths/register src/main.ts",
"start:dev": "nodemon", "start:dev": "nodemon",
"start:debug": "nodemon --config nodemon-debug.json", "start:debug": "nodemon --config nodemon-debug.json",
"start:prod": "npm run migrate:up && node dist/main", "start:prod": "npm run migrate:up && node dist/src/main",
"doc": "./node_modules/.bin/compodoc compodoc -p tsconfig.json -s -n 'Resin api documentation'", "doc": "./node_modules/.bin/compodoc compodoc -p tsconfig.json -s -n 'Resin api documentation'",
"doc:serve": "./node_modules/.bin/compodoc compodoc -s", "doc:serve": "./node_modules/.bin/compodoc compodoc -s",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
"class-transformer": "^0.3.1", "class-transformer": "^0.3.1",
"class-validator": "^0.12.2", "class-validator": "^0.12.2",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"ejs": "^3.1.5", "ejs": "^3.1.6",
"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",
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rxjs": "^6.6.3", "rxjs": "^6.6.3",
"sanitize-html": "^2.6.1",
"standard-version": "^9.3.2", "standard-version": "^9.3.2",
"swagger-ui-express": "^4.3.0" "swagger-ui-express": "^4.3.0"
}, },
......
...@@ -197,4 +197,16 @@ describe('AdminController', () => { ...@@ -197,4 +197,16 @@ describe('AdminController', () => {
expect((await controller.getAdminStructuresList()).claimed.length).toEqual(0); expect((await controller.getAdminStructuresList()).claimed.length).toEqual(0);
expect((await controller.getAdminStructuresList()).incomplete.length).toEqual(2); expect((await controller.getAdminStructuresList()).incomplete.length).toEqual(2);
}); });
it('should find attached users', async () => {
expect((await controller.findAttachedUsers()).length).toBe(0);
});
it('should find unattached users', async () => {
expect((await controller.findUnattachedUsers()).length).toBe(0);
});
it('should find unverified users', async () => {
expect((await controller.findUnVerifiedUsers()).length).toBe(0);
});
}); });
...@@ -21,6 +21,7 @@ import { UsersService } from '../users/users.service'; ...@@ -21,6 +21,7 @@ import { UsersService } from '../users/users.service';
import { PendingStructureDto } from './dto/pending-structure.dto'; import { PendingStructureDto } from './dto/pending-structure.dto';
import { validate } from 'class-validator'; import { validate } from 'class-validator';
import { Structure } from '../structures/schemas/structure.schema'; import { Structure } from '../structures/schemas/structure.schema';
import { IUser } from '../users/interfaces/user.interface';
@Controller('admin') @Controller('admin')
export class AdminController { export class AdminController {
...@@ -162,6 +163,31 @@ export class AdminController { ...@@ -162,6 +163,31 @@ export class AdminController {
else return this.usersService.findAll(); else return this.usersService.findAll();
} }
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Get('getUnAttachedUsers')
public async findUnattachedUsers() {
return this.usersService.findAllUnattached();
}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Get('getAttachedUsers')
public async findAttachedUsers() {
return this.usersService.findAllAttached().then(async (users: IUser[]) => {
return this.structuresService.getAllUserCompletedStructures(users);
});
}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Get('getUnVerifiedUsers')
public async findUnVerifiedUsers() {
return this.usersService.findAllUnVerified().then(async (users: IUser[]) => {
return this.structuresService.getAllUserCompletedStructures(users);
});
}
@UseGuards(JwtAuthGuard, RolesGuard) @UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin') @Roles('admin')
@Post('searchNewsletterSubscriptions') @Post('searchNewsletterSubscriptions')
......
...@@ -12,9 +12,13 @@ describe('AppController', () => { ...@@ -12,9 +12,13 @@ describe('AppController', () => {
describe('healthcheck', () => { describe('healthcheck', () => {
it('should return "Hello World!"', async () => { it('should return "Hello World!"', async () => {
const appController = app.get<AppController>(AppController); const appController = app.get<AppController>(AppController);
const result = { status: 'API Online', uptime: 1 }; const result = { status: 'API Online', uptime: 1, version: '' };
jest.spyOn(appController, 'healthcheck').mockImplementation(async (): Promise<{ status; uptime }> => result); jest
expect(await appController.healthcheck()).toBe(result); .spyOn(appController, 'healthcheck')
.mockImplementation(async (): Promise<{ status; uptime; version }> => result);
const healthcheck = await appController.healthcheck();
expect(healthcheck.status).toBe(result.status);
expect(healthcheck.uptime).toBe(result.uptime);
}); });
}); });
}); });
import { Controller, Get } from '@nestjs/common'; import { Controller, Get } from '@nestjs/common';
import { version } from '../package.json';
@Controller() @Controller()
export class AppController { export class AppController {
private start: number; private start: number;
private version: string = version;
constructor() { constructor() {
this.start = Date.now(); this.start = Date.now();
...@@ -13,6 +15,7 @@ export class AppController { ...@@ -13,6 +15,7 @@ export class AppController {
return { return {
status: 'API Online', status: 'API Online',
uptime: Number((now - this.start) / 1000).toFixed(0), uptime: Number((now - this.start) / 1000).toFixed(0),
version: version,
}; };
} }
} }
...@@ -13,6 +13,7 @@ import { AdminModule } from './admin/admin.module'; ...@@ -13,6 +13,7 @@ import { AdminModule } from './admin/admin.module';
import { PostsModule } from './posts/posts.module'; import { PostsModule } from './posts/posts.module';
import { TempUserModule } from './temp-user/temp-user.module'; import { TempUserModule } from './temp-user/temp-user.module';
import { NewsletterModule } from './newsletter/newsletter.module'; import { NewsletterModule } from './newsletter/newsletter.module';
import { ContactModule } from './contact/contact.module';
@Module({ @Module({
imports: [ imports: [
ConfigurationModule, ConfigurationModule,
...@@ -30,6 +31,7 @@ import { NewsletterModule } from './newsletter/newsletter.module'; ...@@ -30,6 +31,7 @@ import { NewsletterModule } from './newsletter/newsletter.module';
PostsModule, PostsModule,
TempUserModule, TempUserModule,
NewsletterModule, NewsletterModule,
ContactModule,
], ],
controllers: [AppController], controllers: [AppController],
}) })
......
...@@ -4,7 +4,7 @@ export const configDev = { ...@@ -4,7 +4,7 @@ export const configDev = {
host: 'resin-dev.grandlyon.com', host: 'resin-dev.grandlyon.com',
protocol: 'https', protocol: 'https',
port: '443', port: '443',
from: 'inclusionnumerique@grandlyon.com', from: 'noreplyinclusionnumerique@grandlyon.com',
from_name: 'Réseau des acteurs de la médiation numérique', from_name: '[DEV] Réseau des acteurs de la médiation numérique',
replyTo: 'inclusionnumerique@grandlyon.com', replyTo: 'noreplyinclusionnumerique@grandlyon.com',
}; };
...@@ -4,7 +4,7 @@ export const configProd = { ...@@ -4,7 +4,7 @@ export const configProd = {
host: 'resin.grandlyon.com', host: 'resin.grandlyon.com',
protocol: 'https', protocol: 'https',
port: '443', port: '443',
from: 'inclusionnumerique@grandlyon.com', from: 'noreplyinclusionnumerique@grandlyon.com',
from_name: 'Réseau des acteurs de la médiation numérique', from_name: 'Réseau des acteurs de la médiation numérique',
replyTo: 'inclusionnumerique@grandlyon.com', replyTo: 'noreplyinclusionnumerique@grandlyon.com',
}; };
export const configRec = {
url: process.env.MAIL_URL,
token: process.env.MAIL_TOKEN,
host: 'resin-rec.grandlyon.com',
protocol: 'https',
port: '443',
from: 'noreplyinclusionnumerique@grandlyon.com',
from_name: '[REC] Réseau des acteurs de la médiation numérique',
replyTo: 'noreplyinclusionnumerique@grandlyon.com',
};
...@@ -5,7 +5,7 @@ export const config = { ...@@ -5,7 +5,7 @@ export const config = {
protocol: 'http', protocol: 'http',
port: '4200', port: '4200',
from: 'noreplyinclusionnumerique@grandlyon.com', from: 'noreplyinclusionnumerique@grandlyon.com',
from_name: 'Réseau des acteurs de la médiation numérique', from_name: '[LOCAL] Réseau des acteurs de la médiation numérique',
replyTo: 'noreplyinclusionnumerique@grandlyon.com', replyTo: 'noreplyinclusionnumerique@grandlyon.com',
templates: { templates: {
directory: './src/mailer/mail-templates', directory: './src/mailer/mail-templates',
...@@ -61,6 +61,10 @@ export const config = { ...@@ -61,6 +61,10 @@ export const config = {
ejs: 'structureDeletionNotification.ejs', ejs: 'structureDeletionNotification.ejs',
json: 'structureDeletionNotification.json', json: 'structureDeletionNotification.json',
}, },
contactMessage: {
ejs: 'contactMessage.ejs',
json: 'contactMessage.json',
},
newApticStructure: { newApticStructure: {
ejs: 'newApticStructure.ejs', ejs: 'newApticStructure.ejs',
json: 'newApticStructure.json', json: 'newApticStructure.json',
......
...@@ -3,22 +3,33 @@ import * as dotenv from 'dotenv'; ...@@ -3,22 +3,33 @@ import * as dotenv from 'dotenv';
import { config } from './config'; import { config } from './config';
import { configProd } from './config.prod'; import { configProd } from './config.prod';
import { configDev } from './config.dev'; import { configDev } from './config.dev';
import { configRec } from './config.rec';
export class ConfigurationService { export class ConfigurationService {
private readonly _config; private readonly _config;
private readonly _appUrl;
constructor() { constructor() {
// Initializing conf with values from var env // Initializing conf with values from var env
if (process.env.NODE_ENV && process.env.NODE_ENV === 'production') { switch (process.env.NODE_ENV) {
this._config = configProd; case 'production':
this._config.templates = config.templates; // Add mail templates this._config = configProd;
Logger.log('App started with production conf', 'ConfigurationService'); Logger.log('App started with production conf', 'ConfigurationService');
} else if (process.env.NODE_ENV && process.env.NODE_ENV === 'dev') { break;
this._config = configDev; case 'dev':
this._config.templates = config.templates; // Add mail templates this._config = configDev;
Logger.log('App started with dev conf', 'ConfigurationService'); Logger.log('App started with dev conf', 'ConfigurationService');
} else { break;
this._config = config; case 'rec':
this._config = configRec;
Logger.log('App started with rec conf', 'ConfigurationService');
break;
default:
this._config = config;
Logger.warn('App started with default conf', 'ConfigurationService');
break;
} }
this._config.templates = config.templates; // Add mail templates
this._appUrl = `${config.protocol}://${config.host}${config.port ? ':' + config.port : ''}`;
dotenv.config(); dotenv.config();
} }
...@@ -29,4 +40,8 @@ export class ConfigurationService { ...@@ -29,4 +40,8 @@ export class ConfigurationService {
get config() { get config() {
return this._config; return this._config;
} }
get appUrl() {
return this._appUrl;
}
} }
import { Test, TestingModule } from '@nestjs/testing';
import { ContactController } from './contact.controller';
import { ContactService } from './contact.service';
import { MailerModule } from '../mailer/mailer.module';
describe('ContactController', () => {
let controller: ContactController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [MailerModule],
providers: [ContactService],
controllers: [ContactController],
}).compile();
controller = module.get<ContactController>(ContactController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});
import { Body, Controller, Post } from '@nestjs/common';
import { ContactMessage } from './schemas/contact-message.schema';
import { ContactService } from './contact.service';
@Controller('contact')
export class ContactController {
constructor(private contactService: ContactService) {}
@Post('message')
public async sendContactMessage(@Body() data: { contactMessage: ContactMessage }): Promise<any> {
await this.contactService.sendMessage(data.contactMessage);
}
}
import { Module } from '@nestjs/common';
import { MailerModule } from '../mailer/mailer.module';
import { ContactController } from './contact.controller';
import { ContactService } from './contact.service';
@Module({
imports: [MailerModule],
controllers: [ContactController],
providers: [ContactService]
})
export class ContactModule {}
import { Test, TestingModule } from '@nestjs/testing';
import { MailerModule } from '../mailer/mailer.module';
import { ContactService } from './contact.service';
describe('ContactService', () => {
let service: ContactService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [MailerModule],
providers: [ContactService],
}).compile();
service = module.get<ContactService>(ContactService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable } from '@nestjs/common';
import { MailerService } from '../mailer/mailer.service';
import { ContactMessage } from './schemas/contact-message.schema';
import * as ejs from 'ejs';
import * as sanitizeHtml from 'sanitize-html';
@Injectable()
export class ContactService {
constructor(private readonly mailerService: MailerService) {}
public async sendMessage(contactMessage: ContactMessage): Promise<any> {
const config = this.mailerService.config;
const ejsPath = this.mailerService.getTemplateLocation(config.templates.contactMessage.ejs);
const jsonConfig = this.mailerService.loadJsonConfig(config.templates.contactMessage.json);
const html = await ejs.renderFile(ejsPath, {
config,
name: sanitizeHtml(contactMessage.name),
email: sanitizeHtml(contactMessage.email),
phone: sanitizeHtml(contactMessage.phone),
subject: sanitizeHtml(contactMessage.subject),
message: sanitizeHtml(contactMessage.message).replace(/\n/g, "<br />"),
});
return this.mailerService.send(process.env.MAIL_CONTACT, jsonConfig.subject, html);
}
}
\ No newline at end of file
import { IsNotEmpty } from 'class-validator';
export class ContactMessage {
@IsNotEmpty()
surname: string;
@IsNotEmpty()
name: string;
@IsNotEmpty()
email: string;
phone: string;
@IsNotEmpty()
subject: string;
@IsNotEmpty()
message: string;
}