mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
3.0.1
- Switch VK ID authentication to use JWT tokens - Implement JWT verification and decoding - Validate JWT issuer and app ID - Add VKID OAuth integration and constants
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "schedule-parser-next",
|
"name": "schedule-parser-next",
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "N08I40K",
|
"author": "N08I40K",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"firebase-admin": "^13.0.2",
|
"firebase-admin": "^13.0.2",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
"object-hash": "^3.0.0",
|
"object-hash": "^3.0.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
ConflictException,
|
ConflictException,
|
||||||
Injectable,
|
Injectable,
|
||||||
|
NotAcceptableException,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { JwtService } from "@nestjs/jwt";
|
import { JwtService } from "@nestjs/jwt";
|
||||||
@@ -15,8 +16,8 @@ import SignUpErrorDto, { SignUpErrorCode } from "./dto/sign-up-error.dto";
|
|||||||
import { SignInDto, SignInVKDto } from "./dto/sign-in.dto";
|
import { SignInDto, SignInVKDto } from "./dto/sign-in.dto";
|
||||||
import ObjectID from "bson-objectid";
|
import ObjectID from "bson-objectid";
|
||||||
import UserDto from "../users/dto/user.dto";
|
import UserDto from "../users/dto/user.dto";
|
||||||
import { decodeJwt, verifyJwtSignature } from "firebase-admin/lib/utils/jwt";
|
|
||||||
import { vkIdConstants } from "../contants";
|
import { vkIdConstants } from "../contants";
|
||||||
|
import * as jwt from "jsonwebtoken";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@@ -136,16 +137,6 @@ export class AuthService {
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
private static async parseVKID(idToken: string): Promise<number> {
|
private static async parseVKID(idToken: string): Promise<number> {
|
||||||
try {
|
|
||||||
await verifyJwtSignature(idToken, vkIdConstants.jwtPubKey, {
|
|
||||||
issuer: "VK",
|
|
||||||
jwtid: "21",
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const decodedToken = await decodeJwt(idToken);
|
|
||||||
type TokenData = {
|
type TokenData = {
|
||||||
iis: string;
|
iis: string;
|
||||||
sub: number;
|
sub: number;
|
||||||
@@ -155,9 +146,45 @@ export class AuthService {
|
|||||||
jti: number;
|
jti: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const payload = decodedToken.payload as TokenData;
|
const payload = await new Promise<TokenData>((resolve, reject) => {
|
||||||
|
jwt.verify(idToken, vkIdConstants.jwtPubKey, (err, data) => {
|
||||||
|
if (err) return reject(new NotAcceptableException(err.message));
|
||||||
|
|
||||||
if (payload.app !== vkIdConstants.clientId) return null;
|
const payload = data as unknown as TokenData;
|
||||||
|
|
||||||
|
if (typeof payload !== "object") {
|
||||||
|
return reject(
|
||||||
|
new NotAcceptableException("Invalid token payload"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.iis !== "VK") {
|
||||||
|
return reject(
|
||||||
|
new NotAcceptableException(
|
||||||
|
`Unknown issuer, excepted "VK", got "${payload.iis}"`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.jti !== 21) {
|
||||||
|
return reject(
|
||||||
|
new NotAcceptableException(
|
||||||
|
`Unknown type, excepted 21, got ${payload.jti}`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.app !== vkIdConstants.clientId) {
|
||||||
|
return reject(
|
||||||
|
new NotAcceptableException(
|
||||||
|
`Invalid client_id ${payload.app}`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(payload);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return payload.sub;
|
return payload.sub;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ async function bootstrap() {
|
|||||||
enableDebugMessages: true,
|
enableDebugMessages: true,
|
||||||
forbidNonWhitelisted: true,
|
forbidNonWhitelisted: true,
|
||||||
strictGroups: true,
|
strictGroups: true,
|
||||||
|
forbidUnknownValues: true,
|
||||||
};
|
};
|
||||||
app.useGlobalPipes(new PartialValidationPipe(validatorOptions));
|
app.useGlobalPipes(new PartialValidationPipe(validatorOptions));
|
||||||
app.useGlobalInterceptors(new ClassValidatorInterceptor(validatorOptions));
|
app.useGlobalInterceptors(new ClassValidatorInterceptor(validatorOptions));
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ export class VKIDController {
|
|||||||
const result = await this.vkidService.oauth(oAuthRequestDto);
|
const result = await this.vkidService.oauth(oAuthRequestDto);
|
||||||
if (!result) throw new NotAcceptableException("OAuth process failed");
|
if (!result) throw new NotAcceptableException("OAuth process failed");
|
||||||
|
|
||||||
console.log("Access token exchanged!", result.accessToken);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user