diff --git a/README.md b/README.md index fcb8826..ae6dd6c 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,7 @@ We are using the following conventions to identify what the commit is doing: ## Stay in touch - Author - [Liaqat Saeed](https://liaqatsaeed6777.com) -- Website - [https://nestjs.com](https://liaqatsaeed6777.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) +- Twitter - [@liaqatsaeed6777](https://twitter.com/liaqatsaeed6777) ## Authentication @@ -60,7 +59,7 @@ We'll start by generating an **AuthModule** and in it, an **AuthService** and an ### Commands -- `$ nest g module auth -$ nest g controller auth -$ nest g service auth` +- `$ nest g module MODULE_NAME` creates module +- `$ nest g controller CONTROLLER_NAME` creates controller +- `$ nest g service SERVICE_NAME` creates service diff --git a/package.json b/package.json index 59c3d6c..df5ca15 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,11 @@ "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", + "@nestjs/jwt": "^10.1.0", + "@nestjs/mongoose": "^10.0.1", "@nestjs/platform-express": "^10.0.0", "@nestjs/serve-static": "^4.0.0", + "mongoose": "^7.4.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" }, @@ -76,5 +79,9 @@ "commitizen": { "path": "./node_modules/cz-conventional-changelog" } + }, + "engines": { + "npm": "8.1.0", + "node": "v17.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3110313..afa7d98 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,8 @@ specifiers: '@nestjs/cli': ^10.0.0 '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 + '@nestjs/jwt': ^10.1.0 + '@nestjs/mongoose': ^10.0.1 '@nestjs/platform-express': ^10.0.0 '@nestjs/schematics': ^10.0.0 '@nestjs/serve-static': ^4.0.0 @@ -22,6 +24,7 @@ specifiers: eslint-plugin-prettier: ^4.2.1 express-handlebars: ^7.1.0 jest: ^29.5.0 + mongoose: ^7.4.0 prettier: ^2.8.8 reflect-metadata: ^0.1.13 rxjs: ^7.8.1 @@ -36,8 +39,11 @@ specifiers: dependencies: '@nestjs/common': 10.1.0_atc7tu2sld2m3nk4hmwkqn6qde '@nestjs/core': 10.1.0_zcgudmvmawbpprhlgdfoaktvzy + '@nestjs/jwt': 10.1.0_@nestjs+common@10.1.0 + '@nestjs/mongoose': 10.0.1_e6ewa3wujzys76qeogqer26674 '@nestjs/platform-express': 10.1.0_hbea26ufw2zquywaxfa5b5stgu '@nestjs/serve-static': 4.0.0_hbea26ufw2zquywaxfa5b5stgu + mongoose: 7.4.0 reflect-metadata: 0.1.13 rxjs: 7.8.1 @@ -1039,6 +1045,32 @@ packages: transitivePeerDependencies: - encoding + /@nestjs/jwt/10.1.0_@nestjs+common@10.1.0: + resolution: {integrity: sha512-iLwCGS25ybUxGS7i5j/Mwuyzvp/WxJftHlm8aLEBv5GV92apz6L1QVjxLdZrqXbzo++C8gdJauhzil8qitY+6w==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + dependencies: + '@nestjs/common': 10.1.0_atc7tu2sld2m3nk4hmwkqn6qde + '@types/jsonwebtoken': 9.0.2 + jsonwebtoken: 9.0.0 + dev: false + + /@nestjs/mongoose/10.0.1_e6ewa3wujzys76qeogqer26674: + resolution: {integrity: sha512-woUViG28WKf/kRiv6NFXu4Oc0DvAPeX4+fT4coDVt2OqndnfJZTXwkkys23uVsBpKSIflRyjPvmcVBHQvcunZw==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 + mongoose: ^6.0.2 || ^7.0.0 + reflect-metadata: ^0.1.12 + rxjs: ^7.0.0 + dependencies: + '@nestjs/common': 10.1.0_atc7tu2sld2m3nk4hmwkqn6qde + '@nestjs/core': 10.1.0_zcgudmvmawbpprhlgdfoaktvzy + mongoose: 7.4.0 + reflect-metadata: 0.1.13 + rxjs: 7.8.1 + dev: false + /@nestjs/platform-express/10.1.0_hbea26ufw2zquywaxfa5b5stgu: resolution: {integrity: sha512-wl3gsad9Zsv+Im8Fl+meXwpzPLNFRlLbrepGL6Y8za35xXsdx74oCv7NJbjptHMYdwzTZHvbyprfSxV+oHUaXg==} peerDependencies: @@ -1322,6 +1354,12 @@ packages: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true + /@types/jsonwebtoken/9.0.2: + resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==} + dependencies: + '@types/node': 20.4.2 + dev: false + /@types/mime/1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} dev: true @@ -1332,7 +1370,6 @@ packages: /@types/node/20.4.2: resolution: {integrity: sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==} - dev: true /@types/parse-json/4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -1386,6 +1423,17 @@ packages: '@types/superagent': 4.1.18 dev: true + /@types/webidl-conversions/7.0.0: + resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==} + dev: false + + /@types/whatwg-url/8.2.2: + resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} + dependencies: + '@types/node': 20.4.2 + '@types/webidl-conversions': 7.0.0 + dev: false + /@types/yargs-parser/21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: true @@ -1979,6 +2027,15 @@ packages: node-int64: 0.4.0 dev: true + /bson/5.4.0: + resolution: {integrity: sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA==} + engines: {node: '>=14.20.1'} + dev: false + + /buffer-equal-constant-time/1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: false + /buffer-from/1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2353,7 +2410,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /dedent/0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} @@ -2437,6 +2493,12 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true + /ecdsa-sig-formatter/1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /ee-first/1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -3306,6 +3368,10 @@ packages: engines: {node: '>= 0.10'} dev: true + /ip/2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: false + /ipaddr.js/1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -3925,6 +3991,36 @@ packages: graceful-fs: 4.2.11 dev: true + /jsonwebtoken/9.0.0: + resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==} + engines: {node: '>=12', npm: '>=6'} + dependencies: + jws: 3.2.2 + lodash: 4.17.21 + ms: 2.1.3 + semver: 7.5.4 + dev: false + + /jwa/1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: false + + /jws/3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: false + + /kareem/2.5.1: + resolution: {integrity: sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==} + engines: {node: '>=12.0.0'} + dev: false + /kleur/3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -3995,7 +4091,6 @@ packages: /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /log-symbols/4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -4026,7 +4121,6 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /macos-release/2.5.1: resolution: {integrity: sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==} @@ -4068,6 +4162,11 @@ packages: fs-monkey: 1.0.4 dev: true + /memory-pager/1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + dev: false + optional: true + /merge-descriptors/1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -4165,12 +4264,80 @@ packages: dependencies: minimist: 1.2.8 + /mongodb-connection-string-url/2.6.0: + resolution: {integrity: sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==} + dependencies: + '@types/whatwg-url': 8.2.2 + whatwg-url: 11.0.0 + dev: false + + /mongodb/5.7.0: + resolution: {integrity: sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw==} + engines: {node: '>=14.20.1'} + peerDependencies: + '@aws-sdk/credential-providers': ^3.201.0 + '@mongodb-js/zstd': ^1.1.0 + kerberos: ^2.0.1 + mongodb-client-encryption: '>=2.3.0 <3' + snappy: ^7.2.2 + peerDependenciesMeta: + '@aws-sdk/credential-providers': + optional: true + '@mongodb-js/zstd': + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + snappy: + optional: true + dependencies: + bson: 5.4.0 + mongodb-connection-string-url: 2.6.0 + socks: 2.7.1 + optionalDependencies: + saslprep: 1.0.3 + dev: false + + /mongoose/7.4.0: + resolution: {integrity: sha512-oHE1eqodfKzugXRlQxpo+msIea7jPcRoayDuEMr50+bYwM/juA5f+1stjkWlXcg6vo1PdJFVA6DGaKOPLuG5mA==} + engines: {node: '>=14.20.1'} + dependencies: + bson: 5.4.0 + kareem: 2.5.1 + mongodb: 5.7.0 + mpath: 0.9.0 + mquery: 5.0.0 + ms: 2.1.3 + sift: 16.0.1 + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - kerberos + - mongodb-client-encryption + - snappy + - supports-color + dev: false + + /mpath/0.9.0: + resolution: {integrity: sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==} + engines: {node: '>=4.0.0'} + dev: false + + /mquery/5.0.0: + resolution: {integrity: sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==} + engines: {node: '>=14.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -4496,7 +4663,6 @@ packages: /punycode/2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} - dev: true /pure-rand/6.0.2: resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} @@ -4703,6 +4869,15 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + /saslprep/1.0.3: + resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + sparse-bitfield: 3.0.3 + dev: false + optional: true + /schema-utils/3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} @@ -4723,7 +4898,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /send/0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -4794,6 +4968,10 @@ packages: get-intrinsic: 1.2.1 object-inspect: 1.12.3 + /sift/16.0.1: + resolution: {integrity: sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==} + dev: false + /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -4812,6 +4990,19 @@ packages: engines: {node: '>=8'} dev: true + /smart-buffer/4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: false + + /socks/2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: false + /source-map-support/0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -4836,6 +5027,13 @@ packages: engines: {node: '>= 8'} dev: true + /sparse-bitfield/3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + dependencies: + memory-pager: 1.5.0 + dev: false + optional: true + /sprintf-js/1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -5071,6 +5269,13 @@ packages: /tr46/0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + /tr46/3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + dependencies: + punycode: 2.3.0 + dev: false + /tree-kill/1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -5314,6 +5519,11 @@ packages: /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + /webidl-conversions/7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: false + /webpack-node-externals/3.0.0: resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} engines: {node: '>=6'} @@ -5364,6 +5574,14 @@ packages: - uglify-js dev: true + /whatwg-url/11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + dev: false + /whatwg-url/5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -5446,7 +5664,6 @@ packages: /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} diff --git a/src/app.module.ts b/src/app.module.ts index 106b857..687d9a2 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,9 +1,12 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { AuthModule } from './auth/auth.module'; +import { UsersModule } from './users/users.module'; +import { MongooseModule } from '@nestjs/mongoose'; @Module({ - imports: [], + imports: [AuthModule, UsersModule, MongooseModule.forRoot('mongodb://localhost:27017/?readPreference=primary&ssl=false&directConnection=true')], controllers: [AppController], providers: [AppService], }) diff --git a/src/app.service.ts b/src/app.service.ts index 908ea8b..fa4018c 100644 --- a/src/app.service.ts +++ b/src/app.service.ts @@ -7,6 +7,15 @@ export class AppService { return { message: 'Hello from Rate Everything API', title: 'Rate Everything - API', + author: 'Liaqat Saeed', + username: 'liaqatsaeed6777', + website: 'https://liaqatsaeed6777.com/', + email: 'email@liaqatsaeed007@gmail.com', + socials: { + twitter: 'https://twitter.com/', + youtube: 'https://www.youtube.com/@', + instagram: 'https://www.instagram.com/', + } }; } } diff --git a/src/auth/auth.controller.spec.ts b/src/auth/auth.controller.spec.ts new file mode 100644 index 0000000..27a31e6 --- /dev/null +++ b/src/auth/auth.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthController } from './auth.controller'; + +describe('AuthController', () => { + let controller: AuthController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AuthController], + }).compile(); + + controller = module.get(AuthController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts new file mode 100644 index 0000000..d64bfa9 --- /dev/null +++ b/src/auth/auth.controller.ts @@ -0,0 +1,13 @@ +import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common'; +import { AuthService } from './auth.service'; + +@Controller('auth') +export class AuthController { + constructor(private authService: AuthService) {} + + @HttpCode(HttpStatus.OK) + @Post('login') + signIn(@Body() signInDto: Record) { // Route handler parameter decorator. Extracts the entire body object + return this.authService.signIn(signInDto.username, signInDto.password); + } +} diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts new file mode 100644 index 0000000..949ae40 --- /dev/null +++ b/src/auth/auth.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; +import { AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; +import { UsersModule } from 'src/users/users.module'; +import { JwtModule } from '@nestjs/jwt'; +import { jwtConstants } from './constant'; + +@Module({ + imports: [UsersModule, + JwtModule.register({ + global: true, + secret: jwtConstants.secret, + signOptions:{expiresIn: '60s'} + })], + controllers: [AuthController], + providers: [AuthService], // The main idea of a provider is that it can be injected as a dependency. This dependency is resolved and passed to your controller's constructor +}) +export class AuthModule {} diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts new file mode 100644 index 0000000..800ab66 --- /dev/null +++ b/src/auth/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AuthService], + }).compile(); + + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts new file mode 100644 index 0000000..4bd20b1 --- /dev/null +++ b/src/auth/auth.service.ts @@ -0,0 +1,23 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { UsersService } from 'src/users/users.service'; +import { JwtService } from '@nestjs/jwt'; + +@Injectable() +export class AuthService { + constructor(private userService: UsersService, private jwtService: JwtService) {} + + async signIn(username: string, pass: string): Promise { + const user = await this.userService.findOne(username); + + if (user?.password !== pass) { + throw new UnauthorizedException(); + } + + const { password, ...result } = user; + + const payload = { sub: user.userId, username: user.username }; + return { + access_token: await this.jwtService.signAsync(payload), + }; + } +} diff --git a/src/auth/constant.ts b/src/auth/constant.ts new file mode 100644 index 0000000..9a923a1 --- /dev/null +++ b/src/auth/constant.ts @@ -0,0 +1,3 @@ +export const jwtConstants = { + secret: 'juniorjsonWebToken', + }; \ No newline at end of file diff --git a/src/dto/create-user.dto.ts b/src/dto/create-user.dto.ts new file mode 100644 index 0000000..2d394b3 --- /dev/null +++ b/src/dto/create-user.dto.ts @@ -0,0 +1,7 @@ +export class CreateUserDto { + readonly name: string; + readonly username: string; + readonly age: string; + readonly created_date: Date; + readonly userId: string; +} \ No newline at end of file diff --git a/src/interfaces/app.interface.ts b/src/interfaces/app.interface.ts index 36fde35..b1e90be 100644 --- a/src/interfaces/app.interface.ts +++ b/src/interfaces/app.interface.ts @@ -1,4 +1,11 @@ +import { ISocialProps } from "./social.interface"; + export interface IAppProps { message: string; title: string; + author: string; + socials?: ISocialProps; + username?: string; + website?: string; + email?: string; } diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 93246c3..6513907 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1 +1,2 @@ export { IAppProps } from './app.interface'; +export { IUserProps } from "./user.interface" \ No newline at end of file diff --git a/src/interfaces/social.interface.ts b/src/interfaces/social.interface.ts new file mode 100644 index 0000000..c083448 --- /dev/null +++ b/src/interfaces/social.interface.ts @@ -0,0 +1,7 @@ +export interface ISocialProps { + twitter?: string; + youtube?: string; + instagram?: string; + github?: string; + facebook?: string; +} \ No newline at end of file diff --git a/src/interfaces/user.interface.ts b/src/interfaces/user.interface.ts new file mode 100644 index 0000000..37ac60f --- /dev/null +++ b/src/interfaces/user.interface.ts @@ -0,0 +1,5 @@ +export interface IUserProps { + userId: number + username: string + password: string +} \ No newline at end of file diff --git a/src/schemas/users.schema.ts b/src/schemas/users.schema.ts new file mode 100644 index 0000000..3df6a2f --- /dev/null +++ b/src/schemas/users.schema.ts @@ -0,0 +1,27 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { HydratedDocument } from 'mongoose'; + +export type UserDocument = HydratedDocument; + +@Schema() +export class User { + @Prop() + name: string; + + @Prop() + username: string; + + @Prop() + age: string; + + @Prop() + userId: string; + + @Prop() + password: string; + + @Prop() + created_Date: Date; +} + +export const UserSchema = SchemaFactory.createForClass(User); \ No newline at end of file diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/users/users.module.ts b/src/users/users.module.ts new file mode 100644 index 0000000..350e18f --- /dev/null +++ b/src/users/users.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { UsersService } from './users.service'; +import { MongooseModule } from '@nestjs/mongoose'; +import { User, UserSchema } from 'src/schemas/users.schema'; + +@Module({ + imports: [MongooseModule.forFeature([{name: User.name,schema: UserSchema}])], + providers: [UsersService], + exports: [UsersService] +}) +export class UsersModule {} diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts new file mode 100644 index 0000000..62815ba --- /dev/null +++ b/src/users/users.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UsersService } from './users.service'; + +describe('UsersService', () => { + let service: UsersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [UsersService], + }).compile(); + + service = module.get(UsersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/users/users.service.ts b/src/users/users.service.ts new file mode 100644 index 0000000..1b35caa --- /dev/null +++ b/src/users/users.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { User } from 'src/schemas/users.schema'; +import { CreateUserDto } from 'src/dto/create-user.dto'; + +@Injectable() +export class UsersService { + constructor(@InjectModel(User.name) private readonly userModel: Model) {} + + async create(createUserDto: CreateUserDto): Promise { + const createdCat = await this.userModel.create(createUserDto); + return createdCat; + } + + async findAll(): Promise { + return this.userModel.find().exec(); + } + + async findOne(id: string): Promise { + return this.userModel.findOne({ _id: id }).exec(); + } + + async delete(id: string) { + const deletedCat = await this.userModel + .findByIdAndRemove({ _id: id }) + .exec(); + return deletedCat; + } +} \ No newline at end of file diff --git a/views/index.hbs b/views/index.hbs index e118a42..21c387a 100644 --- a/views/index.hbs +++ b/views/index.hbs @@ -1,9 +1,174 @@ - - - {{title}} - - - {{message}} - + + + + {{title}} + + + + +
+
+ +

{{message}}

+
+

API is Running: +

+

+ +
+ +

Author: {{author}}

+

{{email}}

+ +
+ + \ No newline at end of file