mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
Add VKID OAuth integration and constants
- Add VKIDModule - Define vkIdConstants in constants.ts - Create OAuthRequestDto for VKID - Create OAuthResponseDto for VKID
This commit is contained in:
@@ -4,6 +4,7 @@ import { UsersModule } from "./users/users.module";
|
|||||||
import { ScheduleModule } from "./schedule/schedule.module";
|
import { ScheduleModule } from "./schedule/schedule.module";
|
||||||
import { CacheModule } from "@nestjs/cache-manager";
|
import { CacheModule } from "@nestjs/cache-manager";
|
||||||
import { FirebaseAdminModule } from "./firebase-admin/firebase-admin.module";
|
import { FirebaseAdminModule } from "./firebase-admin/firebase-admin.module";
|
||||||
|
import { VKIDModule } from "./vkid/vkid.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -12,6 +13,7 @@ import { FirebaseAdminModule } from "./firebase-admin/firebase-admin.module";
|
|||||||
ScheduleModule,
|
ScheduleModule,
|
||||||
CacheModule.register({ ttl: 5 * 60 * 1000, isGlobal: true }),
|
CacheModule.register({ ttl: 5 * 60 * 1000, isGlobal: true }),
|
||||||
FirebaseAdminModule,
|
FirebaseAdminModule,
|
||||||
|
VKIDModule,
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ import * as process from "node:process";
|
|||||||
|
|
||||||
configDotenv();
|
configDotenv();
|
||||||
|
|
||||||
|
export const vkIdConstants = {
|
||||||
|
clientId: +process.env.VKID_CLIENT_ID,
|
||||||
|
redirectUri: process.env.VKID_REDIRECT_URI,
|
||||||
|
};
|
||||||
|
|
||||||
export const jwtConstants = {
|
export const jwtConstants = {
|
||||||
secret: process.env.JWT_SECRET,
|
secret: process.env.JWT_SECRET,
|
||||||
};
|
};
|
||||||
|
|||||||
12
src/vkid/dto/oauth.request.dto.ts
Normal file
12
src/vkid/dto/oauth.request.dto.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { IsString } from "class-validator";
|
||||||
|
|
||||||
|
export default class OAuthRequestDto {
|
||||||
|
@IsString()
|
||||||
|
code: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
codeVerifier: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
deviceId: string;
|
||||||
|
}
|
||||||
11
src/vkid/dto/oauth.response.dto.ts
Normal file
11
src/vkid/dto/oauth.response.dto.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { IsString } from "class-validator";
|
||||||
|
import {
|
||||||
|
ClassTransformerCtor,
|
||||||
|
Ctor,
|
||||||
|
} from "../../utility/class-trasformer/class-transformer-ctor";
|
||||||
|
|
||||||
|
@ClassTransformerCtor()
|
||||||
|
export default class OAuthResponseDto extends Ctor<OAuthResponseDto> {
|
||||||
|
@IsString()
|
||||||
|
accessToken: string;
|
||||||
|
}
|
||||||
18
src/vkid/vkid.controller.spec.ts
Normal file
18
src/vkid/vkid.controller.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { VKIDController } from './vkid.controller';
|
||||||
|
|
||||||
|
describe('VkidController', () => {
|
||||||
|
let controller: VKIDController;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [VKIDController],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
controller = module.get<VKIDController>(VKIDController);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
43
src/vkid/vkid.controller.ts
Normal file
43
src/vkid/vkid.controller.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
HttpStatus,
|
||||||
|
NotAcceptableException,
|
||||||
|
Post,
|
||||||
|
} from "@nestjs/common";
|
||||||
|
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||||
|
import { VKIDService } from "./vkid.service";
|
||||||
|
import OAuthRequestDto from "./dto/oauth.request.dto";
|
||||||
|
import OAuthResponseDto from "./dto/oauth.response.dto";
|
||||||
|
import { ResultDto } from "../utility/validation/class-validator.interceptor";
|
||||||
|
|
||||||
|
@ApiTags("v1/vkid")
|
||||||
|
@Controller({ path: "vkid", version: "1" })
|
||||||
|
export class VKIDController {
|
||||||
|
constructor(private readonly vkidService: VKIDService) {}
|
||||||
|
|
||||||
|
@ApiOperation({
|
||||||
|
summary: "OAuth аутентификация",
|
||||||
|
description: "Аутентификация пользователя с использованием OAuth",
|
||||||
|
})
|
||||||
|
@ApiBody({ type: OAuthRequestDto, description: "Данные для OAuth запроса" })
|
||||||
|
@ApiResponse({
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
type: OAuthResponseDto,
|
||||||
|
description: "OAuth аутентификация прошла успешно",
|
||||||
|
})
|
||||||
|
@ApiResponse({
|
||||||
|
status: HttpStatus.NOT_ACCEPTABLE,
|
||||||
|
description: "Ошибка в процессе OAuth",
|
||||||
|
})
|
||||||
|
@ResultDto(OAuthResponseDto)
|
||||||
|
@Post("oauth")
|
||||||
|
async oauth(
|
||||||
|
@Body() oAuthRequestDto: OAuthRequestDto,
|
||||||
|
): Promise<OAuthResponseDto> {
|
||||||
|
const result = await this.vkidService.oauth(oAuthRequestDto);
|
||||||
|
if (!result) throw new NotAcceptableException("OAuth process failed");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/vkid/vkid.module.ts
Normal file
11
src/vkid/vkid.module.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
import { VKIDService } from "./vkid.service";
|
||||||
|
import { VKIDController } from "./vkid.controller";
|
||||||
|
import { UsersModule } from "../users/users.module";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [UsersModule],
|
||||||
|
providers: [VKIDService],
|
||||||
|
controllers: [VKIDController],
|
||||||
|
})
|
||||||
|
export class VKIDModule {}
|
||||||
18
src/vkid/vkid.service.spec.ts
Normal file
18
src/vkid/vkid.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { VKIDService } from './vkid.service';
|
||||||
|
|
||||||
|
describe('VkidService', () => {
|
||||||
|
let service: VKIDService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [VKIDService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<VKIDService>(VKIDService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
36
src/vkid/vkid.service.ts
Normal file
36
src/vkid/vkid.service.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
|
import OAuthRequestDto from "./dto/oauth.request.dto";
|
||||||
|
import OAuthResponseDto from "./dto/oauth.response.dto";
|
||||||
|
import axios from "axios";
|
||||||
|
import { vkIdConstants } from "../contants";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class VKIDService {
|
||||||
|
async oauth(oauthRequestDto: OAuthRequestDto): Promise<OAuthResponseDto> {
|
||||||
|
const state = uuidv4();
|
||||||
|
|
||||||
|
const response = await axios.post(
|
||||||
|
"https://id.vk.com/oauth2/auth",
|
||||||
|
"grant_type=authorization_code&" +
|
||||||
|
`client_id=${vkIdConstants.clientId}&` +
|
||||||
|
`state=${state}&` +
|
||||||
|
`code_verifier=${oauthRequestDto.codeVerifier}&` +
|
||||||
|
`code=${oauthRequestDto.code}&` +
|
||||||
|
`device_id=${oauthRequestDto.deviceId}&` +
|
||||||
|
`redirect_uri=${vkIdConstants.redirectUri}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const accessToken: string = (response.data as { access_token: string })
|
||||||
|
.access_token;
|
||||||
|
|
||||||
|
if (!accessToken) {
|
||||||
|
console.error(response.data);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OAuthResponseDto({
|
||||||
|
accessToken: accessToken,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user