diff --git a/backend/package.json b/backend/package.json index e045788..0aacccf 100644 --- a/backend/package.json +++ b/backend/package.json @@ -20,10 +20,14 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@nestjs/axios": "^0.1.0", "@nestjs/common": "^9.0.0", + "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^9.0.0", + "@nestjs/swagger": "^6.1.2", + "axios": "^0.27.2", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0" diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 5600721..1808341 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -1,9 +1,16 @@ import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; import { AppController } from './app.controller'; import { AuthModule } from './auth/auth.module'; @Module({ - imports: [AuthModule], + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + expandVariables: true, + }), + AuthModule, + ], controllers: [AppController], providers: [], }) diff --git a/backend/src/auth/login/dto/kc.data.dto.ts b/backend/src/auth/login/dto/kc.data.dto.ts new file mode 100644 index 0000000..51ad8a9 --- /dev/null +++ b/backend/src/auth/login/dto/kc.data.dto.ts @@ -0,0 +1,8 @@ +export class KeycloakDataDto { + client_id: string; + client_secret: string; + grant_type: string; + username?: string; + email?: string; + password: string; +} diff --git a/backend/src/auth/login/dto/login.dto.ts b/backend/src/auth/login/dto/login.dto.ts index 4289575..f0b4b6c 100644 --- a/backend/src/auth/login/dto/login.dto.ts +++ b/backend/src/auth/login/dto/login.dto.ts @@ -1 +1,5 @@ -export class LoginDto {} +export class LoginDto { + username?: string; + email?: string; + password: string; +} diff --git a/backend/src/auth/login/dto/token.dto.ts b/backend/src/auth/login/dto/token.dto.ts new file mode 100644 index 0000000..e319a4b --- /dev/null +++ b/backend/src/auth/login/dto/token.dto.ts @@ -0,0 +1,10 @@ +export class TokenDto { + access_token: string; + expires_in: number; + refresh_token: string; + refresh_expires_in: number; + token_type: string; + 'not-before-policy': number; + session_state: string; + scope: string; +} diff --git a/backend/src/auth/login/login.controller.ts b/backend/src/auth/login/login.controller.ts index 5ff6dba..42f0e73 100644 --- a/backend/src/auth/login/login.controller.ts +++ b/backend/src/auth/login/login.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Post, Body } from '@nestjs/common'; +import { Controller, Post, Body, Get } from '@nestjs/common'; import { LoginService } from './login.service'; import { LoginDto } from './dto/login.dto'; diff --git a/backend/src/auth/login/login.module.ts b/backend/src/auth/login/login.module.ts index 655dc6f..29484c2 100644 --- a/backend/src/auth/login/login.module.ts +++ b/backend/src/auth/login/login.module.ts @@ -1,9 +1,11 @@ import { Module } from '@nestjs/common'; import { LoginService } from './login.service'; import { LoginController } from './login.controller'; +import { HttpModule } from '@nestjs/axios'; @Module({ + imports: [HttpModule], controllers: [LoginController], - providers: [LoginService] + providers: [LoginService], }) export class LoginModule {} diff --git a/backend/src/auth/login/login.service.ts b/backend/src/auth/login/login.service.ts index 8e6401b..4d6cf6f 100644 --- a/backend/src/auth/login/login.service.ts +++ b/backend/src/auth/login/login.service.ts @@ -1,9 +1,40 @@ +import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; +import { lastValueFrom } from 'rxjs'; import { LoginDto } from './dto/login.dto'; +import { KeycloakDataDto } from './dto/kc.data.dto'; +const querystring = require('querystring'); @Injectable() export class LoginService { - login(loginDto: LoginDto) { - return 'This action adds a new login'; + constructor(private readonly httpService: HttpService) {} + + async login(loginDto: LoginDto) { + const keycloakHeaders = { + Accept: 'application/xhtml+xml', + 'content-type': 'application/x-www-form-urlencoded', + }; + + const keycloakTokenData = { + client_id: process.env.KC_CLIENT_ID || 'client_id', + client_secret: process.env.KC_CLIENT_SECRET || 'client_secret', + grant_type: process.env.KC_GRANT_TYPE || 'grant_type', + }; + + const kcData: KeycloakDataDto = { ...keycloakTokenData, ...loginDto }; + + try { + const res = await lastValueFrom( + this.httpService.request({ + method: 'POST', + data: querystring.stringify(kcData), + headers: keycloakHeaders, + url: process.env.KC_TOKEN_ENDPOINT, + }), + ); + return res.data; + } catch (error) { + return error; + } } } diff --git a/backend/src/auth/register/register.module.ts b/backend/src/auth/register/register.module.ts index ccc23e4..b44ac23 100644 --- a/backend/src/auth/register/register.module.ts +++ b/backend/src/auth/register/register.module.ts @@ -1,8 +1,10 @@ import { Module } from '@nestjs/common'; import { RegisterService } from './register.service'; import { RegisterController } from './register.controller'; +import { HttpModule } from '@nestjs/axios'; @Module({ + imports: [HttpModule], controllers: [RegisterController], providers: [RegisterService] }) diff --git a/backend/src/auth/register/register.service.ts b/backend/src/auth/register/register.service.ts index 933ac8d..88bdaa1 100644 --- a/backend/src/auth/register/register.service.ts +++ b/backend/src/auth/register/register.service.ts @@ -1,15 +1,22 @@ +import { HttpService } from '@nestjs/axios'; import { Injectable } from '@nestjs/common'; +import { AxiosResponse } from 'axios'; +import { lastValueFrom, Observable, of } from 'rxjs'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; @Injectable() export class RegisterService { + constructor(private readonly httpService: HttpService) {} + create(createRegisterDto: CreateUserDto) { return 'This action adds a new register'; } - findAll() { - return `This action returns all register`; + async findAll() { + // const obj = await lastValueFrom(this.httpService.get('https://jsonplaceholder.typicode.com/todos')) + // return obj.data; + return 'Find all Users'; } findOne(id: number) { diff --git a/backend/src/main.ts b/backend/src/main.ts index 13cad38..20dffc6 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -3,6 +3,6 @@ import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); - await app.listen(3000); + await app.listen(process.env.APP_PORT || '3000'); } bootstrap(); diff --git a/backend/yarn.lock b/backend/yarn.lock index 6e8934b..09a8a48 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -623,6 +623,13 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@nestjs/axios@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nestjs/axios/-/axios-0.1.0.tgz#6cf93df11ef93b598b3c7411adb980eedd13b3e3" + integrity sha512-b2TT2X6BFbnNoeteiaxCIiHaFcSbVW+S5yygYqiIq5i6H77yIU3IVuLdpQkHq8/EqOWFwMopLN8jdkUT71Am9w== + dependencies: + axios "0.27.2" + "@nestjs/cli@^9.0.0": version "9.1.1" resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-9.1.1.tgz#d84c1655a41bcbda9b42ffa6ba7344f0f471efc4" @@ -660,6 +667,16 @@ tslib "2.4.0" uuid "8.3.2" +"@nestjs/config@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-2.2.0.tgz#9f3da35f7c4a58724c0a0817d6f04b66e6703430" + integrity sha512-78Eg6oMbCy3D/YvqeiGBTOWei1Jwi3f2pSIZcZ1QxY67kYsJzTRTkwRT8Iv30DbK0sGKc1mcloDLD5UXgZAZtg== + dependencies: + dotenv "16.0.1" + dotenv-expand "8.0.3" + lodash "4.17.21" + uuid "8.3.2" + "@nestjs/core@^9.0.0": version "9.0.11" resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-9.0.11.tgz#1bed969d81685f17d4a01f854c43a222dd3e13ce" @@ -673,7 +690,7 @@ tslib "2.4.0" uuid "8.3.2" -"@nestjs/mapped-types@*": +"@nestjs/mapped-types@*", "@nestjs/mapped-types@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-1.1.0.tgz#54a9fa61079635dd6c3c75fd9593f20b2302a55b" integrity sha512-+2kSly4P1QI+9eGt+/uGyPdEG1hVz7nbpqPHWZVYgoqz8eOHljpXPag+UCVRw9zo2XCu4sgNUIGe8Uk0+OvUQg== @@ -700,6 +717,17 @@ jsonc-parser "3.2.0" pluralize "8.0.0" +"@nestjs/swagger@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-6.1.2.tgz#5eb9c134fc976f16c139ecaf80a7f02a5d33da46" + integrity sha512-RU1DeTDyuN/lRXKFWaf7I9LYF34/ale3IIGeY3romAcXL/N9W0+50Ek3ou+Ajd5FqpLqzt7saYhnaQegVuU4UQ== + dependencies: + "@nestjs/mapped-types" "1.1.0" + js-yaml "4.1.0" + lodash "4.17.21" + path-to-regexp "3.2.0" + swagger-ui-dist "4.14.0" + "@nestjs/testing@^9.0.0": version "9.0.11" resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-9.0.11.tgz#8e60107a7aaf9fc7b2bf29d473c2bdb1887de017" @@ -1214,6 +1242,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -1229,6 +1262,14 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +axios@0.27.2, axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + babel-jest@^28.1.3: version "28.1.3" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" @@ -1745,6 +1786,16 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dotenv-expand@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-8.0.3.tgz#29016757455bcc748469c83a19b36aaf2b83dd6e" + integrity sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg== + +dotenv@16.0.1: + version "16.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" + integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2006,6 +2057,11 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +follow-redirects@^1.14.9: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + fork-ts-checker-webpack-plugin@7.2.13: version "7.2.13" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz#51ffd6a2f96f03ab64b92f8aedf305dbf3dee0f1" @@ -2791,6 +2847,13 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" @@ -2875,7 +2938,7 @@ lodash.memoize@4.x: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== -lodash@^4.17.19, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3773,6 +3836,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swagger-ui-dist@4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz#e34d807464eb84578c43902e393084a1a6fbda52" + integrity sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw== + symbol-observable@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"