Merge pull request 'pre-production' (#77) from pre-production into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

Reviewed-on: #77
pull/78/head 1.0.5-production.1
irfan 2024-09-03 11:16:58 +00:00
commit 5666c31dfa
11 changed files with 163 additions and 37 deletions

6
env/env.development vendored
View File

@ -39,4 +39,8 @@ EXPORT_LIMIT_PARTITION=200
ASSETS="https://asset.sky.eigen.co.id/" ASSETS="https://asset.sky.eigen.co.id/"
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o" GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com" GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin

6
env/env.production vendored
View File

@ -36,4 +36,8 @@ EXPORT_LIMIT_PARTITION=200
ASSETS="https://asset.sky.eigen.co.id/" ASSETS="https://asset.sky.eigen.co.id/"
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o" GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com" GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin

View File

@ -28,6 +28,7 @@
}, },
"dependencies": { "dependencies": {
"@faker-js/faker": "^8.4.1", "@faker-js/faker": "^8.4.1",
"@nestjs/axios": "^3.0.3",
"@nestjs/common": "^10.0.0", "@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.2", "@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.0.0", "@nestjs/core": "^10.0.0",
@ -39,6 +40,7 @@
"@nestjs/typeorm": "^10.0.2", "@nestjs/typeorm": "^10.0.2",
"@types/multer": "^1.4.11", "@types/multer": "^1.4.11",
"algebra.js": "^0.2.6", "algebra.js": "^0.2.6",
"axios": "^1.7.5",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.1", "class-validator": "^0.14.1",

View File

@ -75,6 +75,7 @@ import { MailModule } from './modules/configuration/mail/mail.module';
import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model'; import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model';
import { ExportModule } from './modules/configuration/export/export.module'; import { ExportModule } from './modules/configuration/export/export.module';
import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model'; import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model';
import { SupersetModule } from './modules/configuration/superset/superset.module';
@Module({ @Module({
imports: [ imports: [
@ -174,6 +175,9 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da
ReportModule, ReportModule,
ReportBookmarkModule, ReportBookmarkModule,
ReportExportModule, ReportExportModule,
// superset
SupersetModule,
], ],
controllers: [], controllers: [],
providers: [ providers: [

View File

@ -0,0 +1,17 @@
import { Controller, Get, Param } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { ExcludePrivilege, Public } from 'src/core/guards';
import { SupersetService } from './superset.service';
@ApiTags(`Superset`)
@Controller(`v1/superset`)
@Public(false)
@ApiBearerAuth('JWT')
export class SupersetController {
constructor(private service: SupersetService) {}
@Get('token/:id')
@ExcludePrivilege()
async getGuestToken(@Param('id') id: string) {
return this.service.getGuestToken(id);
}
}

View File

@ -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 {}

View File

@ -0,0 +1,77 @@
import { HttpService } from '@nestjs/axios';
import { Injectable, Logger } from '@nestjs/common';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class SupersetService {
private readonly logger = new Logger(SupersetService.name);
private supersetURL = process.env.SUPERSET_URL + '/api';
private adminUsername = process.env.SUPERSET_ADMIN_USERNAME;
private adminPassword = process.env.SUPERSET_ADMIN_PASSWORD;
constructor(private readonly httpService: HttpService) {}
async getLoginToken() {
const data = {
username: this.adminUsername,
password: this.adminPassword,
provider: 'db',
refresh: true,
};
const response = await firstValueFrom(
this.httpService.request({
method: 'POST',
url: `${this.supersetURL}/v1/security/login`,
data: data,
}),
);
return response.data.access_token;
}
async getCSRFToken() {
const loginToken = await this.getLoginToken();
const response = await firstValueFrom(
this.httpService.request({
method: 'GET',
url: `${this.supersetURL}/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.supersetURL}/v1/security/guest_token/`,
};
const response = await firstValueFrom(
this.httpService.request({
method: 'POST',
url: `${this.supersetURL}/v1/security/guest_token/`,
data: data,
headers: headers,
}),
).catch((err) => {
this.logger.verbose({ loginToken, csrfToken });
this.logger.error(err.response.data);
throw err;
});
return response.data.token;
}
}

View File

@ -24,7 +24,13 @@ export class CreatePaymentMethodManager extends BaseCreateManager<PaymentMethodE
} }
get uniqueColumns(): columnUniques[] { get uniqueColumns(): columnUniques[] {
return [{ column: 'account_number' }, { column: 'account_name' }]; // return [{ column: 'account_number' }, { column: 'account_name' }];
return [
{
column: 'account_number',
query: { account_name: this.data.account_name, type: this.data.type },
},
];
} }
get eventTopics(): EventTopics[] { get eventTopics(): EventTopics[] {

View File

@ -28,7 +28,13 @@ export class UpdatePaymentMethodManager extends BaseUpdateManager<PaymentMethodE
} }
get uniqueColumns(): columnUniques[] { get uniqueColumns(): columnUniques[] {
return [{ column: 'account_number' }, { column: 'account_name' }]; // return [{ column: 'account_number' }, { column: 'account_name' }];
return [
{
column: 'account_number',
query: { account_name: this.data.account_name, type: this.data.type },
},
];
} }
get entityTarget(): any { get entityTarget(): any {

View File

@ -6,7 +6,6 @@ import {
} from 'src/core/strings/constants/interface.constants'; } from 'src/core/strings/constants/interface.constants';
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager'; import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model'; import { UserPrivilegeConfigurationModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege-configuration.model';
import { UserPrivilegeConfigUpdatedEvent } from '../../../entities/event/user-privilege-configuration-updated.event';
@Injectable() @Injectable()
export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager<UserPrivilegeConfigurationEntity> { export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager<UserPrivilegeConfigurationEntity> {
@ -47,11 +46,18 @@ export class UpdateUserPrivilegeConfigurationManager extends BaseCustomManager<U
} }
get eventTopics(): EventTopics[] { get eventTopics(): EventTopics[] {
/**
* Remove Event update privilege
* This event cause the privilege update twice
* When I check this event function, the function to add privilege detail (view, create, update, etc)
* But when case update, privilege doesn't need to add the privilege detail again
* So, this event is not require in privilege update
*/
return [ return [
{ // {
topic: UserPrivilegeConfigUpdatedEvent, // topic: UserPrivilegeConfigUpdatedEvent,
data: this.data, // data: this.data,
}, // },
]; ];
} }
} }

View File

@ -790,6 +790,11 @@
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d" resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d"
integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA== 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": "@nestjs/cli@^10.0.0":
version "10.4.2" version "10.4.2"
resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-10.4.2.tgz#b71c9aacbdd92cebd81add5c4a4bf60b5a184c98" 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" form-data "^4.0.0"
proxy-from-env "^1.1.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: babel-jest@^29.7.0:
version "29.7.0" version "29.7.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" 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" char-regex "^1.0.2"
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
"string-width-cjs@npm:string-width@^4.2.0": "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==
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:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -6736,14 +6741,7 @@ string_decoder@~1.1.1:
dependencies: dependencies:
safe-buffer "~5.1.0" safe-buffer "~5.1.0"
"strip-ansi-cjs@npm: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==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -7460,7 +7458,7 @@ wordwrap@^1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== 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" version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 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" string-width "^4.1.0"
strip-ansi "^6.0.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: wrap-ansi@^8.1.0:
version "8.1.0" version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"