From 498a5b56397aef0dccbd548294ecacaaca80ee68 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Thu, 12 Mar 2026 11:41:40 +0330 Subject: [PATCH] direct login --- src/app.module.ts | 4 +- src/configs/dpage.config.ts | 20 +++++ src/modules/dmenu/dmenu.controller.ts | 1 - src/modules/dpage/constants/index.ts | 1 + src/modules/dpage/dpage.controller.ts | 40 +++++++++ src/modules/dpage/dpage.module.ts | 19 ++++ src/modules/dpage/dpage.service.ts | 87 +++++++++++++++++++ src/modules/dpage/dto/login.dto.ts | 9 ++ src/modules/dpage/dto/update-dpage.dto.ts | 4 + .../providers/subscriptions.service.ts | 9 ++ 10 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 src/configs/dpage.config.ts create mode 100644 src/modules/dpage/constants/index.ts create mode 100644 src/modules/dpage/dpage.controller.ts create mode 100644 src/modules/dpage/dpage.module.ts create mode 100644 src/modules/dpage/dpage.service.ts create mode 100644 src/modules/dpage/dto/login.dto.ts create mode 100644 src/modules/dpage/dto/update-dpage.dto.ts diff --git a/src/app.module.ts b/src/app.module.ts index 5c797bb..50555dc 100755 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -43,6 +43,7 @@ import { UploaderModule } from "./modules/uploader/uploader.module"; import { UsersModule } from "./modules/users/users.module"; import { WalletsModule } from "./modules/wallets/wallets.module"; import { DkalaModule } from "./modules/dkala/dkala.module"; +import { DpageModule } from './modules/dpage/dpage.module'; @Module({ imports: [ // TelegrafModule.forRootAsync(telegrafConfig()), @@ -88,7 +89,8 @@ import { DkalaModule } from "./modules/dkala/dkala.module"; SupportPlansModule, AccessLogsModule, DmenuModule, - DkalaModule + DkalaModule, + DpageModule ], controllers: [], }) diff --git a/src/configs/dpage.config.ts b/src/configs/dpage.config.ts new file mode 100644 index 0000000..d07ba5c --- /dev/null +++ b/src/configs/dpage.config.ts @@ -0,0 +1,20 @@ +import { ConfigService } from "@nestjs/config"; + +export function dpageConfig() { + return { + inject: [ConfigService], + useFactory: async (configService: ConfigService) => { + return { + baseUrl: configService.get("DPAGE_BACKEND_URL")??'https://dpage-api.danakcorp.com', + username: configService.get("DPAGE_USERNAME")??'danak@dsc.com', + password: configService.get("DPAGE_PASSWORD")??'DsCdAnAk?@ABC', + }; + }, + }; +} + +export interface IDPageConfig { + baseUrl: string; + username: string; + password: string; +} diff --git a/src/modules/dmenu/dmenu.controller.ts b/src/modules/dmenu/dmenu.controller.ts index 8d86c7d..d8a4b9f 100644 --- a/src/modules/dmenu/dmenu.controller.ts +++ b/src/modules/dmenu/dmenu.controller.ts @@ -20,7 +20,6 @@ import { UserDec } from "../../common/decorators/user.decorator"; @ApiTags("d-menu") @Controller() @AuthGuards() - @ApiBearerAuth() export class DmenuController { constructor( diff --git a/src/modules/dpage/constants/index.ts b/src/modules/dpage/constants/index.ts new file mode 100644 index 0000000..1fedecb --- /dev/null +++ b/src/modules/dpage/constants/index.ts @@ -0,0 +1 @@ +export const DPAGE_CONFIG = "DPAGE_CONFIG"; diff --git a/src/modules/dpage/dpage.controller.ts b/src/modules/dpage/dpage.controller.ts new file mode 100644 index 0000000..e494e1a --- /dev/null +++ b/src/modules/dpage/dpage.controller.ts @@ -0,0 +1,40 @@ +import { Controller, Get, Post, Body, Param, Delete } from '@nestjs/common'; +import { DPageService } from './dpage.service'; +import { LoginDto } from './dto/login.dto'; +import { UserDec } from '../../common/decorators/user.decorator'; +import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; +import { AuthGuards } from '../../common/decorators/auth-guard.decorator'; + +@Controller('dpage') +@ApiTags('d-page') +@AuthGuards() +@ApiBearerAuth() +export class DpageController { + constructor(private readonly dpageService: DPageService) { } + + @Post('login') + @ApiOperation({ summary: 'direct login' }) + login(@Body() dto: LoginDto, @UserDec("id") userId: string) { + return this.dpageService.loginToDpage(dto, userId); + } + + @Get() + findAll() { + return this.dpageService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.dpageService.findOne(+id); + } + + // @Patch(':id') + // update(@Param('id') id: string, @Body() updateDpageDto: UpdateDpageDto) { + // return this.dpageService.update(id, updateDpageDto); + // } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.dpageService.remove(+id); + } +} diff --git a/src/modules/dpage/dpage.module.ts b/src/modules/dpage/dpage.module.ts new file mode 100644 index 0000000..978e060 --- /dev/null +++ b/src/modules/dpage/dpage.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common'; +import { DPageService } from './dpage.service'; +import { DpageController } from './dpage.controller'; +import { SubscriptionsModule } from '../subscriptions/subscriptions.module'; +import { DPAGE_CONFIG } from './constants'; +import { dpageConfig } from '../../configs/dpage.config'; + +@Module({ + imports: [SubscriptionsModule], + controllers: [DpageController], + providers: [DPageService, + { + provide: DPAGE_CONFIG, + useFactory: dpageConfig().useFactory, + inject: dpageConfig().inject, + }, + ], +}) +export class DpageModule { } diff --git a/src/modules/dpage/dpage.service.ts b/src/modules/dpage/dpage.service.ts new file mode 100644 index 0000000..a311254 --- /dev/null +++ b/src/modules/dpage/dpage.service.ts @@ -0,0 +1,87 @@ +import { BadRequestException, HttpException, Injectable, Logger } from "@nestjs/common"; +import { HttpService } from "@nestjs/axios"; +import { Inject } from "@nestjs/common"; +import { AxiosError } from "axios"; +import { catchError, firstValueFrom, throwError } from "rxjs"; +import { SubscriptionsService } from "../subscriptions/providers/subscriptions.service"; +import { IDPageConfig } from "../../configs/dpage.config"; +import { LoginDto } from './dto/login.dto'; +import { DPAGE_CONFIG } from "./constants"; +// import { UsersService } from "../users/providers/users.service"; +// import { UpdateDpageDto } from './dto/update-dpage.dto'; + +@Injectable() +export class DPageService { + private readonly logger = new Logger(DPageService.name); + constructor( + @Inject(DPAGE_CONFIG) private readonly config: IDPageConfig, + private readonly httpService: HttpService, + private readonly subscriptionService: SubscriptionsService, + // private readonly usersService: UsersService, + ) { } + + private getHeaders(): Record { + const credentials = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64"); + return { + "Content-Type": "application/json", + Authorization: `Basic ${credentials}`, + }; + } + + findAll() { + return `This action returns all dpage`; + } + + findOne(id: number) { + return `This action returns a #${id} dpage`; + } + + // update(id: number, updateDpageDto: UpdateDpageDto) { + // return `This action updates a #${id} dpage`; + // } + + remove(id: number) { + return `This action removes a #${id} dpage`; + } + + async loginToDpage(dto: LoginDto, userId: string) { + const { userSubscriptionId } = dto + // 1. validate userSubscription by id + const userSubscription = await this.subscriptionService.findOneOrFail(userSubscriptionId) + + + if (userSubscription.user.id !== userId) { + throw new BadRequestException("this subscription doesnt belongs to you") + } + + try { + // 2. Login with userSubscriptionId + const { data } = await firstValueFrom( + this.httpService + .post(`${this.config.baseUrl}/super-admin/auth/direct-login`, { + subscriptionId: userSubscriptionId + }, { + headers: this.getHeaders(), + }) + .pipe( + catchError((err: AxiosError) => { + this.logger.error(`Failed to perform direct login: ${err.message}`, err.stack); + return throwError(() => err); + }), + ), + ); + return data; + } catch (error: unknown) { + if (error instanceof AxiosError && error.response) { + this.logger.error(`External API error response:`, error.response.data); + const errorResponse = { + ...error.response.data, + message: error.response.data.error?.message || error.message, + }; + throw new HttpException(errorResponse, error.response.status); + } + this.logger.error(`Error performing direct login: ${error instanceof Error ? error.message : "Unknown error"}`); + throw error; + } + } +} diff --git a/src/modules/dpage/dto/login.dto.ts b/src/modules/dpage/dto/login.dto.ts new file mode 100644 index 0000000..cc3cdcb --- /dev/null +++ b/src/modules/dpage/dto/login.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsNotEmpty, IsString } from "class-validator"; + +export class LoginDto { + @IsNotEmpty() + @IsString() + @ApiProperty() + userSubscriptionId:string +} diff --git a/src/modules/dpage/dto/update-dpage.dto.ts b/src/modules/dpage/dto/update-dpage.dto.ts new file mode 100644 index 0000000..65bdb45 --- /dev/null +++ b/src/modules/dpage/dto/update-dpage.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { LoginDto } from './login.dto'; + +export class UpdateDpageDto extends PartialType(LoginDto) {} diff --git a/src/modules/subscriptions/providers/subscriptions.service.ts b/src/modules/subscriptions/providers/subscriptions.service.ts index 5009852..99167d4 100755 --- a/src/modules/subscriptions/providers/subscriptions.service.ts +++ b/src/modules/subscriptions/providers/subscriptions.service.ts @@ -700,4 +700,13 @@ export class SubscriptionsService { message: SubscriptionMessage.SUBSCRIPTION_DELETED } } + + // ******************************** // + async findOneOrFail(userSubscriptionId: string){ + const usersubscription = await this.userSubscriptionsRepository.findOne({ where: { id: userSubscriptionId },relations:['user'] }) + if (!usersubscription) { + throw new BadRequestException(SubscriptionMessage.NOT_FOUND) + } + return usersubscription + } }