Compare commits
	
		
			23 Commits
		
	
	
		
			v0.11.1
			...
			2b641faa29
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2b641faa29 | |||
| 9fa8b93c08 | |||
| 4b676bc853 | |||
| 4433ddb1e1 | |||
| 39aa7598b7 | |||
| 19a290c3a9 | |||
| 9bc80aac8a | |||
| e184673963 | |||
| 68cd746a9f | |||
| 69651d9f6c | |||
| 6fd246f43c | |||
| ae14d6c74f | |||
| 2fa56b82d1 | |||
| 9cc66eebdf | |||
| 4c10e20b91 | |||
| 9217421221 | |||
| 4570845b3e | |||
| 0e78951300 | |||
| 6ad56b3126 | |||
| d95c6d3365 | |||
| 1f2c8abb22 | |||
| a6d5693ccd | |||
| 31b258b4ce | 
							
								
								
									
										51
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -29,7 +29,7 @@ get: | ||||
| --- | ||||
| kind: pipeline | ||||
| type: kubernetes | ||||
| name: tests:node_14.15.1-alpine3.12 | ||||
| name: tests:node | ||||
| clone: | ||||
|   disable: true | ||||
| steps: | ||||
| @@ -39,7 +39,7 @@ steps: | ||||
|       - git clone $DRONE_REMOTE_URL . | ||||
|       - git checkout $DRONE_SOURCE_BRANCH | ||||
|   - name: run tests | ||||
|     image: node:14.15.1-alpine3.12 | ||||
|     image: registry.odit.services/hub/library/node:19.5.0-alpine3.16 | ||||
|     commands: | ||||
|       - yarn | ||||
|       - yarn test:ci | ||||
| @@ -61,22 +61,28 @@ steps: | ||||
|       - git clone $DRONE_REMOTE_URL . | ||||
|       - git checkout dev | ||||
|   - name: build dev | ||||
|     image: plugins/docker | ||||
|     depends_on: [clone] | ||||
|     depends_on: ["clone"] | ||||
|     image: registry.odit.services/library/drone-kaniko | ||||
|     settings: | ||||
|       username: | ||||
|         from_secret: docker_username | ||||
|       password: | ||||
|         from_secret: docker_password | ||||
|       repo: registry.odit.services/lfk/backend | ||||
|       build_args: | ||||
|         - NPM_REGISTRY_DOMAIN: | ||||
|           from_secret: npmjs_domain | ||||
|         - NPM_REGISTRY_TOKEN: | ||||
|           from_secret: npmjs_token | ||||
|       repo: lfk/backend | ||||
|       tags: | ||||
|         - dev | ||||
|       cache: true | ||||
|       registry: registry.odit.services | ||||
|       mtu: 1000 | ||||
|   - name: run changelog export | ||||
|     depends_on: ["clone"] | ||||
|     image: node:latest | ||||
|     image: registry.odit.services/hub/library/node:19.5.0-alpine3.16 | ||||
|     commands: | ||||
|       - apk add git | ||||
|       - npx auto-changelog --commit-limit false -p -u --hide-credit | ||||
|   - name: push new changelog to repo | ||||
|     depends_on: ["run changelog export"] | ||||
| @@ -91,7 +97,7 @@ steps: | ||||
|         from_secret: git_ssh | ||||
|   - name: run full license export | ||||
|     depends_on: ["clone"] | ||||
|     image: node:14.15.1-alpine3.12 | ||||
|     image: registry.odit.services/hub/library/node:19.5.0-alpine3.16 | ||||
|     commands: | ||||
|       - yarn | ||||
|       - yarn licenses:export | ||||
| @@ -108,7 +114,6 @@ steps: | ||||
|       ssh_key: | ||||
|         from_secret: git_ssh | ||||
|  | ||||
|  | ||||
| trigger: | ||||
|   branch: | ||||
|     - dev | ||||
| @@ -132,17 +137,22 @@ steps: | ||||
|       - git checkout main | ||||
|   - name: build latest | ||||
|     depends_on: ["clone"] | ||||
|     image: plugins/docker | ||||
|     image: registry.odit.services/library/drone-kaniko | ||||
|     settings: | ||||
|       username: | ||||
|         from_secret: docker_username | ||||
|       password: | ||||
|         from_secret: docker_password | ||||
|       repo: registry.odit.services/lfk/backend | ||||
|       build_args: | ||||
|         - NPM_REGISTRY_DOMAIN: | ||||
|           from_secret: npmjs_domain | ||||
|         - NPM_REGISTRY_TOKEN: | ||||
|           from_secret: npmjs_token | ||||
|       repo: lfk/backend | ||||
|       tags: | ||||
|         - latest | ||||
|       cache: true | ||||
|       registry: registry.odit.services | ||||
|       mtu: 1000 | ||||
|   - name: push merge to repo | ||||
|     depends_on: ["clone"] | ||||
|     image: appleboy/drone-git-push | ||||
| @@ -166,18 +176,23 @@ name: build:tags | ||||
|  | ||||
| steps: | ||||
|   - name: build $DRONE_TAG | ||||
|     image: plugins/docker | ||||
|     depends_on: [clone] | ||||
|     depends_on: ["clone"] | ||||
|     image: registry.odit.services/library/drone-kaniko | ||||
|     settings: | ||||
|       username: | ||||
|         from_secret: docker_username | ||||
|       password: | ||||
|         from_secret: docker_password | ||||
|       repo: registry.odit.services/lfk/backend | ||||
|       build_args: | ||||
|         - NPM_REGISTRY_DOMAIN: | ||||
|           from_secret: npmjs_domain | ||||
|         - NPM_REGISTRY_TOKEN: | ||||
|           from_secret: npmjs_token | ||||
|       repo: lfk/backend | ||||
|       tags: | ||||
|         - '${DRONE_TAG}' | ||||
|         - "${DRONE_TAG}" | ||||
|       cache: true | ||||
|       registry: registry.odit.services | ||||
|       mtu: 1000 | ||||
|   - name: trigger node lib build | ||||
|     image: idcooldi/drone-webhook | ||||
|     settings: | ||||
| @@ -192,4 +207,4 @@ steps: | ||||
|         from_secret: ci_token | ||||
| trigger: | ||||
|   event: | ||||
|   - tag | ||||
|     - tag | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -135,4 +135,5 @@ build | ||||
| /docs | ||||
| lib | ||||
| /oss-attribution | ||||
| *.tmp | ||||
| *.tmp | ||||
| pnpm-lock.yaml | ||||
|   | ||||
							
								
								
									
										33
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -2,11 +2,44 @@ | ||||
|  | ||||
| All notable changes to this project will be documented in this file. Dates are displayed in UTC. | ||||
|  | ||||
| #### [v0.12.0](https://git.odit.services/lfk/backend/compare/v0.12.0...v0.12.0) | ||||
|  | ||||
| - Merge pull request 'feature/197-duplicate_runner_mail' (#198) from feature/197-duplicate_runner_mail into dev [`4b676bc`](https://git.odit.services/lfk/backend/commit/4b676bc85336c2d494e9e74823d38deec5cc0400) | ||||
| - Added faker for testing [`e184673`](https://git.odit.services/lfk/backend/commit/e1846739638905aab6ba7e059fd2cbf8ff467bf3) | ||||
| - Updated selfservice tests to prevent email duplication [`9bc80aa`](https://git.odit.services/lfk/backend/commit/9bc80aac8aab9b4dedc26c9bc3ce705d7fe9c0bf) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`ae14d6c`](https://git.odit.services/lfk/backend/commit/ae14d6c74f9205440b41ca5fdbd052ca449148fc) | ||||
| - Added selfservice runner create check to prevent duplicate email [`68cd746`](https://git.odit.services/lfk/backend/commit/68cd746a9f3360b3630a9ba570213d2aa62497b4) | ||||
| - Updated tests for new login in selfservice [`39aa759`](https://git.odit.services/lfk/backend/commit/39aa7598b7cd0ecb0f077f50ebdd31c6e205f06d) | ||||
| - Updated logo url [`4433ddb`](https://git.odit.services/lfk/backend/commit/4433ddb1e15a35481728670e22049200644bf337) | ||||
| - depends_on: ["clone"] [`9cc66ee`](https://git.odit.services/lfk/backend/commit/9cc66eebdfe8e7a2888bbc97197d1756ff44de30) | ||||
| - Fixed typo [`19a290c`](https://git.odit.services/lfk/backend/commit/19a290c3a931ead0d9ae9ebb0985bfbaac54df59) | ||||
| - Rename selfservice forgot to login [`69651d9`](https://git.odit.services/lfk/backend/commit/69651d9f6cd826b6d4720f164897a2a72a57c851) | ||||
| - 📖New license file version [CI SKIP] [skip ci] [`6fd246f`](https://git.odit.services/lfk/backend/commit/6fd246f43cb3f4d0ccb6e017ee699889ba17daac) | ||||
| - Add git for changelog fun [`2fa56b8`](https://git.odit.services/lfk/backend/commit/2fa56b82d1e082a1deae943e5fca5101f24e3ef5) | ||||
|  | ||||
| #### [v0.12.0](https://git.odit.services/lfk/backend/compare/v0.11.1...v0.12.0) | ||||
|  | ||||
| > 2 February 2023 | ||||
|  | ||||
| - Pinned versions [`a6d5693`](https://git.odit.services/lfk/backend/commit/a6d5693ccdeb25b15a09af8f7438142114268807) | ||||
| - Drone -> Kaniko based builds [`0e78951`](https://git.odit.services/lfk/backend/commit/0e789513008085d0db94fc3b2dd9e74a5e583049) | ||||
| - Drone images to odit registry [`6ad56b3`](https://git.odit.services/lfk/backend/commit/6ad56b31269bf19a740c1b6b1a303a8a9d7d59d0) | ||||
| - Bumped container base images [`d95c6d3`](https://git.odit.services/lfk/backend/commit/d95c6d33657f6aa977a8ebfefad7e199bb1cc9c3) | ||||
| - Enabled tag via release script [`9217421`](https://git.odit.services/lfk/backend/commit/92174212213f874e41c9472a927bcf87b963ac94) | ||||
| - Pinned pnpm for builds [`4570845`](https://git.odit.services/lfk/backend/commit/4570845b3e1bd00c228fe1b09b658c24e20aba7f) | ||||
| - 🚀Bumped version to v0.12.0 [`4c10e20`](https://git.odit.services/lfk/backend/commit/4c10e20b91a8101ee37b230373ceb3e024582b41) | ||||
| - Ignore pnpm lock [`1f2c8ab`](https://git.odit.services/lfk/backend/commit/1f2c8abb22f3ff1e61b7350b517bd699c3e315f6) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`31b258b`](https://git.odit.services/lfk/backend/commit/31b258b4ce82213144160a4233b7fd127e456776) | ||||
|  | ||||
| #### [v0.11.1](https://git.odit.services/lfk/backend/compare/v0.11.0...v0.11.1) | ||||
|  | ||||
| > 22 April 2021 | ||||
|  | ||||
| - Merge pull request 'Release 0.11.1' (#196) from dev into main [`f19f280`](https://git.odit.services/lfk/backend/commit/f19f2808d88414f1877c01f10996dac68b6f9617) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`2229cdf`](https://git.odit.services/lfk/backend/commit/2229cdf20db1a98f9f76a99fa9d3f463cdf6d804) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`348fe52`](https://git.odit.services/lfk/backend/commit/348fe52c42cfa32239b703041820f725e147154e) | ||||
| - Now prefixing runnercards with 2 [`8a82e05`](https://git.odit.services/lfk/backend/commit/8a82e059b74ceabf43c9cbfe9c9b89ef6ce15a28) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`3b9cd2e`](https://git.odit.services/lfk/backend/commit/3b9cd2e1bbbe8e69c3883233a98f286d768c2b79) | ||||
| - Added fix for the appended 2 [`eb526fb`](https://git.odit.services/lfk/backend/commit/eb526fb57faf631fd6e84af99af738ab1b3481c7) | ||||
| - 🚀Bumped version to v0.11.1 [`95320ca`](https://git.odit.services/lfk/backend/commit/95320ca1bccc2886553accea6a428aadffda0a27) | ||||
| - 🧾New changelog file version [CI SKIP] [skip ci] [`f2d127f`](https://git.odit.services/lfk/backend/commit/f2d127fc98d75ce658424624abd382c087737ca0) | ||||
|   | ||||
							
								
								
									
										13
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,16 +1,15 @@ | ||||
| # Typescript Build | ||||
| FROM node:14.15.1-alpine3.12 | ||||
| FROM registry.odit.services/hub/library/node:19.5.0-alpine3.16 | ||||
| WORKDIR /app | ||||
| COPY package.json ./ | ||||
| RUN npm i -g pnpm | ||||
| RUN pnpm i | ||||
| RUN npx pnpm@7.26.3 i | ||||
| COPY tsconfig.json ormconfig.js ./ | ||||
| COPY src ./src | ||||
| RUN pnpm run build | ||||
| RUN npm run build | ||||
|  | ||||
| # final image | ||||
| FROM node:14.15.1-alpine3.12 | ||||
| FROM registry.odit.services/hub/library/node:19.5.0-alpine3.16 | ||||
| COPY package.json ormconfig.js ./ | ||||
| RUN npm i -g pnpm | ||||
| RUN pnpm i --prod | ||||
| RUN npx pnpm@7.26.3 i --prod | ||||
| COPY --from=0 /app/dist dist | ||||
| ENTRYPOINT ["node", "dist/app.js"] | ||||
							
								
								
									
										71
									
								
								licenses.md
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								licenses.md
									
									
									
									
									
								
							| @@ -454,7 +454,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| ## License Text | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2010 - 2021 Brian Carlson | ||||
| Copyright (c) 2010 - 2020 Brian Carlson | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| @@ -696,6 +696,75 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|   | ||||
|  | ||||
| # @faker-js/faker | ||||
| **Author**: undefined | ||||
| **Repo**: [object Object] | ||||
| **License**: MIT | ||||
| **Description**: Generate massive amounts of fake contextual data | ||||
| ## License Text | ||||
| Faker - Copyright (c) 2022 | ||||
|  | ||||
| This software consists of voluntary contributions made by many individuals. | ||||
| For exact contribution history, see the revision history | ||||
| available at https://github.com/faker-js/faker | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining | ||||
| a copy of this software and associated documentation files (the | ||||
| "Software"), to deal in the Software without restriction, including | ||||
| without limitation the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the Software, and to | ||||
| permit persons to whom the Software is furnished to do so, subject to | ||||
| the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be | ||||
| included in all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|  | ||||
| === | ||||
|  | ||||
| From: https://github.com/faker-js/faker/commit/a9f98046c7d5eeaabe12fc587024c06d683800b8 | ||||
| To: https://github.com/faker-js/faker/commit/29234378807c4141588861f69421bf20b5ac635e | ||||
|  | ||||
| Based on faker.js, copyright Marak Squires and contributor, what follows below is the original license. | ||||
|  | ||||
| === | ||||
|  | ||||
| faker.js - Copyright (c) 2020 | ||||
| Marak Squires | ||||
| http://github.com/marak/faker.js/ | ||||
|  | ||||
| faker.js was inspired by and has used data definitions from: | ||||
|  | ||||
|  * https://github.com/stympy/faker/ - Copyright (c) 2007-2010 Benjamin Curtis | ||||
|  * http://search.cpan.org/~jasonk/Data-Faker-0.07/ - Copyright 2004-2005 by Jason Kohles | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining | ||||
| a copy of this software and associated documentation files (the | ||||
| "Software"), to deal in the Software without restriction, including | ||||
| without limitation the rights to use, copy, modify, merge, publish, | ||||
| distribute, sublicense, and/or sell copies of the Software, and to | ||||
| permit persons to whom the Software is furnished to do so, subject to | ||||
| the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be | ||||
| included in all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
|   | ||||
|  | ||||
| # @odit/license-exporter | ||||
| **Author**: ODIT.Services | ||||
| **Repo**: [object Object] | ||||
|   | ||||
							
								
								
									
										215
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,106 +1,109 @@ | ||||
| { | ||||
|   "name": "@odit/lfk-backend", | ||||
|   "version": "0.11.1", | ||||
|   "main": "src/app.ts", | ||||
|   "repository": "https://git.odit.services/lfk/backend", | ||||
|   "author": { | ||||
|     "name": "ODIT.Services", | ||||
|     "email": "info@odit.services", | ||||
|     "url": "https://odit.services" | ||||
|   }, | ||||
|   "contributors": [ | ||||
|     { | ||||
|       "name": "Philipp Dormann", | ||||
|       "email": "philipp@philippdormann.de", | ||||
|       "url": "https://philippdormann.de" | ||||
|     }, | ||||
|     { | ||||
|       "name": "Nicolai Ort", | ||||
|       "email": "info@nicolai-ort.com", | ||||
|       "url": "https://nicolai-ort.com" | ||||
|     } | ||||
|   ], | ||||
|   "license": "CC-BY-NC-SA-4.0", | ||||
|   "dependencies": { | ||||
|     "@odit/class-validator-jsonschema": "2.1.1", | ||||
|     "argon2": "^0.27.1", | ||||
|     "axios": "^0.21.1", | ||||
|     "body-parser": "^1.19.0", | ||||
|     "check-password-strength": "^2.0.2", | ||||
|     "class-transformer": "0.3.1", | ||||
|     "class-validator": "^0.13.1", | ||||
|     "consola": "^2.15.0", | ||||
|     "cookie": "^0.4.1", | ||||
|     "cookie-parser": "^1.4.5", | ||||
|     "cors": "^2.8.5", | ||||
|     "csvtojson": "^2.0.10", | ||||
|     "dotenv": "^8.2.0", | ||||
|     "express": "^4.17.1", | ||||
|     "jsonwebtoken": "^8.5.1", | ||||
|     "libphonenumber-js": "^1.9.9", | ||||
|     "mysql": "^2.18.1", | ||||
|     "pg": "^8.5.1", | ||||
|     "reflect-metadata": "^0.1.13", | ||||
|     "routing-controllers": "0.9.0-alpha.6", | ||||
|     "routing-controllers-openapi": "^2.2.0", | ||||
|     "sqlite3": "5.0.0", | ||||
|     "typeorm": "^0.2.30", | ||||
|     "typeorm-routing-controllers-extensions": "^0.2.0", | ||||
|     "typeorm-seeding": "^1.6.1", | ||||
|     "uuid": "^8.3.2", | ||||
|     "validator": "^13.5.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@odit/license-exporter": "^0.0.9", | ||||
|     "@types/cors": "^2.8.9", | ||||
|     "@types/csvtojson": "^1.1.5", | ||||
|     "@types/express": "^4.17.11", | ||||
|     "@types/jest": "^26.0.20", | ||||
|     "@types/jsonwebtoken": "^8.5.0", | ||||
|     "@types/node": "^14.14.22", | ||||
|     "@types/uuid": "^8.3.0", | ||||
|     "cp-cli": "^2.0.0", | ||||
|     "jest": "^26.6.3", | ||||
|     "nodemon": "^2.0.7", | ||||
|     "release-it": "^14.2.2", | ||||
|     "rimraf": "^3.0.2", | ||||
|     "start-server-and-test": "^1.11.7", | ||||
|     "ts-jest": "^26.5.0", | ||||
|     "ts-node": "^9.1.1", | ||||
|     "typedoc": "^0.20.19", | ||||
|     "typescript": "^4.1.3" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "dev": "nodemon src/app.ts", | ||||
|     "build": "rimraf ./dist && tsc && cp-cli ./src/static ./dist/static", | ||||
|     "docs": "typedoc --out docs src", | ||||
|     "test": "jest", | ||||
|     "test:watch": "jest --watchAll", | ||||
|     "test:ci:generate_env": "ts-node scripts/create_testenv.ts", | ||||
|     "test:ci:run": "start-server-and-test dev http://localhost:4010/api/docs/openapi.json test", | ||||
|     "test:ci": "npm run test:ci:generate_env && npm run test:ci:run", | ||||
|     "seed": "ts-node ./node_modules/typeorm/cli.js schema:sync && ts-node ./node_modules/typeorm-seeding/dist/cli.js seed", | ||||
|     "openapi:export": "ts-node scripts/openapi_export.ts", | ||||
|     "licenses:export": "license-exporter --markdown", | ||||
|     "release": "release-it --only-version" | ||||
|   }, | ||||
|   "release-it": { | ||||
|     "git": { | ||||
|       "commit": true, | ||||
|       "requireCleanWorkingDir": false, | ||||
|       "commitMessage": "🚀Bumped version to v${version}", | ||||
|       "requireBranch": "dev", | ||||
|       "push": false, | ||||
|       "tag": false | ||||
|     }, | ||||
|     "npm": { | ||||
|       "publish": false | ||||
|     } | ||||
|   }, | ||||
|   "nodemonConfig": { | ||||
|     "ignore": [ | ||||
|       "src/tests/*", | ||||
|       "docs/*" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
| { | ||||
|   "name": "@odit/lfk-backend", | ||||
|   "version": "0.12.0", | ||||
|   "main": "src/app.ts", | ||||
|   "repository": "https://git.odit.services/lfk/backend", | ||||
|   "author": { | ||||
|     "name": "ODIT.Services", | ||||
|     "email": "info@odit.services", | ||||
|     "url": "https://odit.services" | ||||
|   }, | ||||
|   "contributors": [ | ||||
|     { | ||||
|       "name": "Philipp Dormann", | ||||
|       "email": "philipp@philippdormann.de", | ||||
|       "url": "https://philippdormann.de" | ||||
|     }, | ||||
|     { | ||||
|       "name": "Nicolai Ort", | ||||
|       "email": "info@nicolai-ort.com", | ||||
|       "url": "https://nicolai-ort.com" | ||||
|     } | ||||
|   ], | ||||
|   "license": "CC-BY-NC-SA-4.0", | ||||
|   "dependencies": { | ||||
|     "@odit/class-validator-jsonschema": "2.1.1", | ||||
|     "argon2": "0.27.1", | ||||
|     "axios": "0.21.1", | ||||
|     "body-parser": "1.19.0", | ||||
|     "check-password-strength": "2.0.2", | ||||
|     "class-transformer": "0.3.1", | ||||
|     "class-validator": "0.13.1", | ||||
|     "consola": "2.15.0", | ||||
|     "cookie": "0.4.1", | ||||
|     "cookie-parser": "1.4.5", | ||||
|     "cors": "2.8.5", | ||||
|     "csvtojson": "2.0.10", | ||||
|     "dotenv": "8.2.0", | ||||
|     "express": "4.17.1", | ||||
|     "jsonwebtoken": "8.5.1", | ||||
|     "libphonenumber-js": "1.9.9", | ||||
|     "mysql": "2.18.1", | ||||
|     "pg": "8.5.1", | ||||
|     "reflect-metadata": "0.1.13", | ||||
|     "routing-controllers": "0.9.0-alpha.6", | ||||
|     "routing-controllers-openapi": "2.2.0", | ||||
|     "sqlite3": "5.0.0", | ||||
|     "typeorm": "0.2.30", | ||||
|     "typeorm-routing-controllers-extensions": "0.2.0", | ||||
|     "typeorm-seeding": "1.6.1", | ||||
|     "uuid": "8.3.2", | ||||
|     "validator": "13.5.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@faker-js/faker": "^7.6.0", | ||||
|     "@odit/license-exporter": "0.0.9", | ||||
|     "@types/cors": "2.8.9", | ||||
|     "@types/csvtojson": "1.1.5", | ||||
|     "@types/express": "4.17.11", | ||||
|     "@types/jest": "26.0.20", | ||||
|     "@types/jsonwebtoken": "8.5.0", | ||||
|     "@types/node": "14.14.22", | ||||
|     "@types/uuid": "8.3.0", | ||||
|     "cp-cli": "2.0.0", | ||||
|     "jest": "26.6.3", | ||||
|     "nodemon": "2.0.7", | ||||
|     "release-it": "14.2.2", | ||||
|     "rimraf": "3.0.2", | ||||
|     "start-server-and-test": "1.11.7", | ||||
|     "ts-jest": "26.5.0", | ||||
|     "ts-node": "9.1.1", | ||||
|     "typedoc": "0.20.19", | ||||
|     "typescript": "4.1.3" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "dev": "nodemon src/app.ts", | ||||
|     "build": "rimraf ./dist && tsc && cp-cli ./src/static ./dist/static", | ||||
|     "docs": "typedoc --out docs src", | ||||
|     "test": "jest", | ||||
|     "test:watch": "jest --watchAll", | ||||
|     "test:ci:generate_env": "ts-node scripts/create_testenv.ts", | ||||
|     "test:ci:run": "start-server-and-test dev http://localhost:4010/api/docs/openapi.json test", | ||||
|     "test:ci": "npm run test:ci:generate_env && npm run test:ci:run", | ||||
|     "seed": "ts-node ./node_modules/typeorm/cli.js schema:sync && ts-node ./node_modules/typeorm-seeding/dist/cli.js seed", | ||||
|     "openapi:export": "ts-node scripts/openapi_export.ts", | ||||
|     "licenses:export": "license-exporter --markdown", | ||||
|     "release": "release-it --only-version" | ||||
|   }, | ||||
|   "release-it": { | ||||
|     "git": { | ||||
|       "commit": true, | ||||
|       "requireCleanWorkingDir": false, | ||||
|       "commitMessage": "🚀Bumped version to v${version}", | ||||
|       "requireBranch": "dev", | ||||
|       "push": true, | ||||
|       "tag": true, | ||||
|       "tagName": "v${version}", | ||||
|       "tagAnnotation": "v${version}" | ||||
|     }, | ||||
|     "npm": { | ||||
|       "publish": false | ||||
|     } | ||||
|   }, | ||||
|   "nodemonConfig": { | ||||
|     "ignore": [ | ||||
|       "src/tests/*", | ||||
|       "docs/*" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Request } from "express"; | ||||
| import * as jwt from "jsonwebtoken"; | ||||
| import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers'; | ||||
| import { BadRequestError, Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers'; | ||||
| import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; | ||||
| import { getConnectionManager, Repository } from 'typeorm'; | ||||
| import { config } from '../config'; | ||||
| @@ -116,7 +116,7 @@ export class RunnerSelfServiceController { | ||||
| 		return scan.toResponse(); | ||||
| 	} | ||||
|  | ||||
| 	@Post('/runners/forgot') | ||||
| 	@Post('/runners/login') | ||||
| 	@ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) | ||||
| 	@OnUndefined(ResponseEmpty) | ||||
| 	@OpenAPI({ description: 'Use this endpoint to reuqest a new selfservice token/link to be sent to your mail address (rate limited to one mail every 24hrs).' }) | ||||
| @@ -148,8 +148,11 @@ export class RunnerSelfServiceController { | ||||
| 	@OpenAPI({ description: 'Create a new selfservice runner in the citizen org. <br> This endpoint shoud be used to allow "everyday citizen" to register themselves. <br> You have to provide a mail address, b/c the future we\'ll implement email verification.' }) | ||||
| 	async registerRunner(@Body({ validate: true }) createRunner: CreateSelfServiceCitizenRunner, @QueryParam("locale") locale: string = "en") { | ||||
| 		let runner = await createRunner.toEntity(); | ||||
|  | ||||
| 		if (await this.getRunnerExistsByMail(runner.email)) { | ||||
| 			throw new BadRequestError("E-Mail already registered") | ||||
| 		} | ||||
| 		runner = await this.runnerRepository.save(runner); | ||||
|  | ||||
| 		let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] })); | ||||
| 		response.token = JwtCreator.createSelfService(runner); | ||||
|  | ||||
| @@ -170,6 +173,9 @@ export class RunnerSelfServiceController { | ||||
| 		const org = await this.getOrgansisation(token); | ||||
|  | ||||
| 		let runner = await createRunner.toEntity(org); | ||||
| 		if (await this.getRunnerExistsByMail(runner.email)) { | ||||
| 			throw new BadRequestError("E-Mail already registered") | ||||
| 		} | ||||
| 		runner = await this.runnerRepository.save(runner); | ||||
|  | ||||
| 		let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] })); | ||||
| @@ -225,4 +231,14 @@ export class RunnerSelfServiceController { | ||||
|  | ||||
| 		return organization; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Checks if a runner already exists | ||||
| 	 * @param email The runner's email address | ||||
| 	 * @returns Boolean (true if exists, false if not) | ||||
| 	 */ | ||||
| 	private async getRunnerExistsByMail(email: string): Promise<boolean> { | ||||
| 		const runner = await this.runnerRepository.findOne({ email }); | ||||
| 		return runner != undefined | ||||
| 	} | ||||
| } | ||||
| @@ -114,7 +114,7 @@ export class CreateUser { | ||||
|         newUser.groups = await this.getGroups(); | ||||
|         newUser.enabled = this.enabled; | ||||
|  | ||||
|         if (!this.profilePic) { newUser.profilePic = `https://dev.lauf-fuer-kaya.de/lfk-logo.png`; } | ||||
|         if (!this.profilePic) { newUser.profilePic = `https://lauf-fuer-kaya.de/lfk-logo.png`; } | ||||
|         else { newUser.profilePic = this.profilePic; } | ||||
|  | ||||
|         return newUser; | ||||
|   | ||||
| @@ -124,7 +124,7 @@ export class UpdateUser { | ||||
|         user.phone = this.phone; | ||||
|         user.groups = await this.getGroups(); | ||||
|  | ||||
|         if (!this.profilePic) { user.profilePic = `https://dev.lauf-fuer-kaya.de/lfk-logo.png`; } | ||||
|         if (!this.profilePic) { user.profilePic = `https://lauf-fuer-kaya.de/lfk-logo.png`; } | ||||
|         else { user.profilePic = this.profilePic; } | ||||
|  | ||||
|         return user; | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| import { faker } from '@faker-js/faker'; | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
|  | ||||
| const base = "http://localhost:" + config.internal_port | ||||
|  | ||||
| let access_token; | ||||
| @@ -21,7 +23,7 @@ describe('delete selfservice runner invalid', () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         added_runner = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
| @@ -50,7 +52,7 @@ describe('delete selfservice runner valid', () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         added_runner = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|   | ||||
| @@ -15,20 +15,20 @@ beforeAll(async () => { | ||||
|     }; | ||||
| }); | ||||
|  | ||||
| describe('POST /api/runners/me/forgot invalid syntax/mail should fail', () => { | ||||
| describe('POST /api/runners/me/login invalid syntax/mail should fail', () => { | ||||
|     it('get without mail return 404', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/forgot', null, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/login', null, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('get without bs mail return 404', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/forgot?mail=asdasdasdasdasd@tester.test.dev.lauf-fuer-kaya.de', null, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/login?mail=asdasdasdasdasd@tester.test.dev.lauf-fuer-kaya.de', null, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('POST /api/runners/me/forgot 2 times within timeout should fail', () => { | ||||
| describe('POST /api/runners/me/login 2 times within timeout should fail', () => { | ||||
|     let added_runner; | ||||
|     it('registering as citizen should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
| @@ -42,19 +42,19 @@ describe('POST /api/runners/me/forgot 2 times within timeout should fail', () => | ||||
|         added_runner = res.data; | ||||
|     }); | ||||
|     it('post with valid mail should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/forgot?mail=' + added_runner.email, null, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/login?mail=' + added_runner.email, null, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('2nd post with valid mail should return 406', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/forgot?mail=' + added_runner.email, null, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/login?mail=' + added_runner.email, null, axios_config); | ||||
|         expect(res.status).toEqual(406); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| // --------------- | ||||
| describe('POST /api/runners/me/forgot valid should return 200', () => { | ||||
| describe('POST /api/runners/me/login valid should return 200', () => { | ||||
|     let added_runner; | ||||
|     let new_token; | ||||
|     it('registering as citizen should return 200', async () => { | ||||
| @@ -69,7 +69,7 @@ describe('POST /api/runners/me/forgot valid should return 200', () => { | ||||
|         added_runner = res.data; | ||||
|     }); | ||||
|     it('post with valid mail should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/runners/forgot?mail=' + added_runner.email, null, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/login?mail=' + added_runner.email, null, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         new_token = res.data.token; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { faker } from '@faker-js/faker'; | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
| @@ -30,7 +31,7 @@ describe('register + get should return 200', () => { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { faker } from '@faker-js/faker'; | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
| @@ -39,7 +40,7 @@ describe('register invalid citizen', () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
| @@ -48,7 +49,7 @@ describe('register invalid citizen', () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
| @@ -59,7 +60,26 @@ describe('register invalid citizen', () => { | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "phone": "peter", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('registering as citizen with duplicate mail should return 400', async () => { | ||||
|         const mail = faker.internet.exampleEmail(); | ||||
|         await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "phone": "peter", | ||||
|             "email": mail, | ||||
|         }, axios_config); | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "phone": "peter", | ||||
|             "email": mail, | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
| @@ -71,7 +91,7 @@ describe('register citizen valid', () => { | ||||
|         const res = await axios.post(base + '/api/runners/register', { | ||||
|             "firstname": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com" | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
| @@ -81,7 +101,7 @@ describe('register citizen valid', () => { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com", | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|             "phone": "+4909132123456", | ||||
|             "address": { | ||||
|                 address1: "Teststreet 1", | ||||
| @@ -187,7 +207,7 @@ describe('register valid company', () => { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com", | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|             "phone": "+4909132123456", | ||||
|             "address": { | ||||
|                 address1: "Teststreet 1", | ||||
| @@ -214,7 +234,7 @@ describe('register valid company', () => { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com", | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|             "phone": "+4909132123456", | ||||
|             "address": { | ||||
|                 address1: "Teststreet 1", | ||||
| @@ -232,7 +252,7 @@ describe('register valid company', () => { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "email": "user@example.com", | ||||
|             "email": faker.internet.exampleEmail(), | ||||
|             "phone": "+4909132123456", | ||||
|             "address": { | ||||
|                 address1: "Teststreet 1", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user