From 9f50d56cea526fc21945e8b2f5342413cf8ac776 Mon Sep 17 00:00:00 2001 From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:04:06 +0700 Subject: [PATCH] feat: setup superset BE --- package.json | 2 + src/app.module.ts | 4 ++ .../superset/superset.controller.ts | 15 +++++ .../configuration/superset/superset.module.ts | 11 ++++ .../superset/superset.service.ts | 60 +++++++++++++++++++ yarn.lock | 45 ++++++-------- 6 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 src/modules/configuration/superset/superset.controller.ts create mode 100644 src/modules/configuration/superset/superset.module.ts create mode 100644 src/modules/configuration/superset/superset.service.ts diff --git a/package.json b/package.json index b20c84e..9ae87fc 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", + "@nestjs/axios": "^3.0.3", "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.0.0", @@ -39,6 +40,7 @@ "@nestjs/typeorm": "^10.0.2", "@types/multer": "^1.4.11", "algebra.js": "^0.2.6", + "axios": "^1.7.5", "bcrypt": "^5.1.1", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", diff --git a/src/app.module.ts b/src/app.module.ts index c21e956..2c9e87e 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -75,6 +75,7 @@ import { MailModule } from './modules/configuration/mail/mail.module'; import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model'; import { ExportModule } from './modules/configuration/export/export.module'; import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model'; +import { SupersetModule } from './modules/configuration/superset/superset.module'; @Module({ imports: [ @@ -174,6 +175,9 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da ReportModule, ReportBookmarkModule, ReportExportModule, + + // superset + SupersetModule, ], controllers: [], providers: [ diff --git a/src/modules/configuration/superset/superset.controller.ts b/src/modules/configuration/superset/superset.controller.ts new file mode 100644 index 0000000..d36bd4e --- /dev/null +++ b/src/modules/configuration/superset/superset.controller.ts @@ -0,0 +1,15 @@ +import { Controller, Get, Param } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { Public } from 'src/core/guards'; +import { SupersetService } from './superset.service'; + +@ApiTags(`Superset`) +@Controller(`v1/superset`) +export class SupersetController { + constructor(private service: SupersetService) {} + @Get('token/:id') + @Public(true) + async getGuestToken(@Param('id') id: string) { + return this.service.getGuestToken(id); + } +} diff --git a/src/modules/configuration/superset/superset.module.ts b/src/modules/configuration/superset/superset.module.ts new file mode 100644 index 0000000..ecf4c76 --- /dev/null +++ b/src/modules/configuration/superset/superset.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { SupersetController } from './superset.controller'; +import { SupersetService } from './superset.service'; +import { HttpModule } from '@nestjs/axios'; + +@Module({ + imports: [HttpModule], + controllers: [SupersetController], + providers: [SupersetService], +}) +export class SupersetModule {} diff --git a/src/modules/configuration/superset/superset.service.ts b/src/modules/configuration/superset/superset.service.ts new file mode 100644 index 0000000..4704517 --- /dev/null +++ b/src/modules/configuration/superset/superset.service.ts @@ -0,0 +1,60 @@ +import { HttpService } from '@nestjs/axios'; +import { Injectable } from '@nestjs/common'; +import { firstValueFrom } from 'rxjs'; + +@Injectable() +export class SupersetService { + private SUPERSET_URL = 'https://dashboard.weplayground.eigen.co.id'; + constructor(private readonly httpService: HttpService) {} + async getLoginToken() { + const data = { + username: 'admin', + password: 'admin', + provider: 'db', + refresh: true, + }; + const response = await firstValueFrom( + this.httpService.post(`${this.SUPERSET_URL}/api/v1/security/login`, data), + ); + + return response.data.access_token; + } + + async getCSRFToken() { + const loginToken = await this.getLoginToken(); + + const response = await firstValueFrom( + this.httpService.get(`${this.SUPERSET_URL}/api/v1/security/csrf_token/`, { + headers: { Authorization: `Bearer ${loginToken}` }, + }), + ); + + return { loginToken, csrfToken: response.data.result }; + } + + async getGuestToken(uuid: string) { + const { loginToken, csrfToken } = await this.getCSRFToken(); + const data = { + resources: [{ type: 'dashboard', id: uuid }], + rls: [], + user: { username: 'pos_embed', first_name: 'pos', last_name: 'embed' }, + }; + + const headers = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${loginToken}`, + 'X-CSRFToken': `${csrfToken}`, + Referer: `${this.SUPERSET_URL}/api/v1/security/guest_token/`, + }; + + const response = await firstValueFrom( + this.httpService.post( + `${this.SUPERSET_URL}/api/v1/security/guest_token/`, + data, + { headers, xsrfHeaderName: 'X-CSRFToken' }, + ), + ); + + return response.data.token; + } +} diff --git a/yarn.lock b/yarn.lock index b77f4e8..080d6c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -790,6 +790,11 @@ resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d" integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA== +"@nestjs/axios@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@nestjs/axios/-/axios-3.0.3.tgz#a663cb13cff07ea6b9a7107263de2ae472d41118" + integrity sha512-h6TCn3yJwD6OKqqqfmtRS5Zo4E46Ip2n+gK1sqwzNBC+qxQ9xpCu+ODVRFur6V3alHSCSBxb3nNtt73VEdluyA== + "@nestjs/cli@^10.0.0": version "10.4.2" resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-10.4.2.tgz#b71c9aacbdd92cebd81add5c4a4bf60b5a184c98" @@ -1871,6 +1876,15 @@ axios@^1.6.2: form-data "^4.0.0" proxy-from-env "^1.1.0" +axios@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.5.tgz#21eed340eb5daf47d29b6e002424b3e88c8c54b1" + integrity sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -6686,16 +6700,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6736,14 +6741,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7460,7 +7458,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -7478,15 +7476,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" -- 2.40.1