feat: remove unused packages, config

This commit is contained in:
M1000fr 2024-12-12 22:06:35 +01:00
parent bc4dcc26ef
commit e52c9acf2d
12 changed files with 74 additions and 126 deletions

View File

@ -23,7 +23,6 @@
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.3.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/mapped-types": "^2.0.6",
"@nestjs/platform-express": "^10.4.11",
"@nestjs/platform-socket.io": "^10.4.12",
@ -34,6 +33,7 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"joi": "^17.13.3",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.1.0",
"nestjs-prisma": "^0.23.0",
"prisma": "^6.0.1",

View File

@ -1,7 +1,6 @@
import env from "@Config/env";
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { JwtModule } from "@nestjs/jwt";
import { ConfigModule } from "@nestjs/config";
import { envValidation } from "@Validations/env.validation";
import { AuthModule } from "@Modules/auth/auth.module";
@ -17,16 +16,6 @@ import { ClassModule } from "./modules/class/class.module";
load: [env],
validationSchema: envValidation,
}),
JwtModule.registerAsync({
global: true,
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
secret: configService.get<string>("JWT.secret"),
signOptions: {
expiresIn: configService.get<string>("JWT.expiresIn"),
},
}),
}),
PrismaModule.forRoot({
isGlobal: true,
}),
@ -34,6 +23,6 @@ import { ClassModule } from "./modules/class/class.module";
AuthModule,
ClassModule,
],
controllers: [AppController],
controllers: [AppController]
})
export class AppModule {}

View File

@ -1,19 +1,6 @@
export default () => ({
JWT: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN,
refresh: {
secret: process.env.REFRESH_JWT_SECRET,
expiresIn: process.env.REFRESH_JWT_EXPIRES_IN,
},
},
oauth2: {
authorizationURL: process.env.OAUTH2_AUTHORIZATION_URL,
tokenURL: process.env.OAUTH2_TOKEN_URL,
clientID: process.env.OAUTH2_CLIENT_ID,
clientSecret: process.env.OAUTH2_CLIENT_SECRET,
callbackURL: process.env.OAUTH2_CALLBACK_URL,
profileURL: process.env.OAUTH2_PROFILE_URL,
scopes: process.env.OAUTH2_SCOPES,
auth: {
jwksURL: process.env.AUTH_JWKS_URI,
usernameField: process.env.AUTH_USERNAME_FIELD
},
});

View File

@ -1,9 +1,8 @@
import { UserModule } from "@Modules/user/user.module";
import { Module } from "@nestjs/common";
import { AuthService } from "./auth.service";
@Module({
imports: [UserModule],
providers: [AuthService],
exports: [AuthService],
})
export class AuthModule {}

View File

@ -1,41 +1,49 @@
import { Injectable } from "@nestjs/common";
import { Injectable, UnauthorizedException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { JwtService } from "@nestjs/jwt";
import * as jwt from "jsonwebtoken";
import JwksRsa, * as jwksRsa from "jwks-rsa";
@Injectable()
export class AuthService {
constructor(
private readonly jwtService: JwtService,
private readonly configService: ConfigService,
) {}
private jwksClient: JwksRsa.JwksClient;
accessToken(user: { id: string }) {
return this.jwtService.sign(
{ id: user.id },
{
secret: this.configService.get<string>("JWT.secret"),
expiresIn: this.configService.get<string>("JWT.expiresIn"),
},
);
}
refreshToken(user: { id: string }) {
return this.jwtService.sign(
{ id: user.id },
{
secret: this.configService.get<string>("JWT.refresh.secret"),
expiresIn: this.configService.get<string>(
"JWT.refresh.expiresIn",
),
},
);
}
async verifyToken(token: string): Promise<{
id: string;
}> {
return await this.jwtService.verifyAsync(token, {
secret: this.configService.get<string>("JWT.secret"),
constructor(configService: ConfigService) {
this.jwksClient = jwksRsa({
jwksUri: configService.get<string>("AUTH_JWKS_URI"),
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 10,
});
}
async getSigningKey(kid: string): Promise<string> {
const key = await this.jwksClient.getSigningKey(kid);
return key.getPublicKey();
}
decodeJwt(token: string) {
return jwt.decode(token, { complete: true });
}
verifyJwt(token: string, key: string) {
return jwt.verify(token, key, {
algorithms: ["RS256"],
});
}
async checkToken(token: string): Promise<jwt.JwtPayload> {
const decodedHeader = this.decodeJwt(token);
const kid = decodedHeader?.header?.kid;
if (!kid) throw "Token kid not found";
const key = await this.getSigningKey(kid);
const jwtPayload = this.verifyJwt(token, key);
if (typeof jwtPayload == "string")
throw new UnauthorizedException("Invalid token");
return jwtPayload;
}
}

View File

@ -5,25 +5,16 @@ import {
Injectable,
UnauthorizedException,
} from "@nestjs/common";
import { AuthService } from "../auth.service";
import { ConfigService } from "@nestjs/config";
import * as jwt from "jsonwebtoken";
import * as jwksRsa from "jwks-rsa";
@Injectable()
export class JwtAuthGuard implements CanActivate {
private jwksClient: jwksRsa.JwksClient;
constructor(
private readonly userService: UserService,
configService: ConfigService,
) {
this.jwksClient = jwksRsa({
jwksUri: configService.get<string>("AUTH_JWKS_URI"),
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 10,
});
}
private readonly authService: AuthService,
private readonly configService: ConfigService,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
@ -34,25 +25,11 @@ export class JwtAuthGuard implements CanActivate {
}
try {
const decodedHeader: any = jwt.decode(token, { complete: true });
const kid = decodedHeader?.header?.kid;
if (!kid) {
throw new UnauthorizedException("Token kid not found");
}
const key = await this.getSigningKey(kid);
const verifiedToken = jwt.verify(token, key, {
algorithms: ["RS256"],
});
if (typeof verifiedToken == "string")
throw new UnauthorizedException("Invalid token");
const jwtPayload = await this.authService.checkToken(token);
let user = await this.userService.findOrCreateByProviderId({
providerId: verifiedToken.sub.toString(),
username: verifiedToken.preferred_username,
providerId: jwtPayload.sub.toString(),
username: jwtPayload[this.configService.get("auth.usernameField")],
});
request.user = user;
@ -74,9 +51,4 @@ export class JwtAuthGuard implements CanActivate {
return parts[1];
}
private async getSigningKey(kid: string): Promise<string> {
const key = await this.jwksClient.getSigningKey(kid);
return key.getPublicKey();
}
}

View File

@ -1,10 +1,11 @@
import { Module } from "@nestjs/common";
import { ClassService } from "./class.service";
import { ClassController } from "./class.controller";
import { UserService } from "../user/user.service";
import { UserModule } from "../user/user.module";
@Module({
imports: [UserModule],
controllers: [ClassController],
providers: [ClassService, UserService],
providers: [ClassService],
})
export class ClassModule {}

View File

@ -9,12 +9,14 @@ import {
import { Server, Socket } from "socket.io";
import { AuthService } from "../auth/auth.service";
import { UserService } from "./user.service";
import { ConfigService } from "@nestjs/config";
@WebSocketGateway()
export class UserGateway implements OnGatewayConnection, OnGatewayDisconnect {
constructor(
private readonly authService: AuthService,
private readonly userService: UserService,
private readonly configService: ConfigService,
) {}
@WebSocketServer() io: Server;
@ -22,16 +24,21 @@ export class UserGateway implements OnGatewayConnection, OnGatewayDisconnect {
public clients: Socket[] = [];
async handleConnection(client: Socket) {
const Authorization = client.handshake.headers.authorization;
const token = client.handshake.headers.authorization;
try {
var jwtDecoded = await this.authService.verifyToken(Authorization);
var jwtPayload = await this.authService.checkToken(token);
if (!jwtPayload) throw "Invalid token";
} catch (error) {
client.emit("auth", error);
return client.disconnect();
}
const user = await this.userService.findOne(jwtDecoded.id);
const user = await this.userService.findOrCreateByProviderId({
providerId: jwtPayload.sub.toString(),
username: jwtPayload[this.configService.get("auth.usernameField")],
});
if (!user) {
client.emit("auth", "User not found");

View File

@ -7,8 +7,8 @@ import { UserGateway } from "./user.gateway";
import { UserService } from "./user.service";
@Module({
providers: [UserService, PrismaService, UserGateway, AuthService],
providers: [UserService, AuthService, PrismaService, UserGateway],
controllers: [UserController],
exports: [UserService],
exports: [UserService, AuthService],
})
export class UserModule {}

View File

@ -52,10 +52,9 @@ export class UserService {
providerId: string;
username: string;
}) {
let user = await this.prisma.user.findUnique({
let user = await this.prisma.user.findFirst({
where: {
providerId,
username,
OR: [{ providerId }, { username }],
},
});

View File

@ -4,6 +4,7 @@ export const envValidation = Joi.object({
DATABASE_URL: Joi.string().required(),
AUTH_JWKS_URI: Joi.string().uri().required(),
AUTH_USERNAME_FIELD: Joi.string().required(),
PORT: Joi.number().optional(),
});

View File

@ -318,14 +318,6 @@
path-to-regexp "3.3.0"
tslib "2.8.1"
"@nestjs/jwt@^10.2.0":
version "10.2.0"
resolved "https://registry.yarnpkg.com/@nestjs/jwt/-/jwt-10.2.0.tgz#6aa35a04922d19c6426efced4671620f92e6dbd0"
integrity sha512-x8cG90SURkEiLOehNaN2aRlotxT0KZESUliOPKKnjWiyJOcWurkF3w345WOX0P4MgFzUjGoZ1Sy0aZnxeihT0g==
dependencies:
"@types/jsonwebtoken" "9.0.5"
jsonwebtoken "9.0.2"
"@nestjs/mapped-types@2.0.6", "@nestjs/mapped-types@^2.0.6":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.6.tgz#d2d8523709fd5d872a9b9e0c38162746e2a7f44e"
@ -617,13 +609,6 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/jsonwebtoken@9.0.5":
version "9.0.5"
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz#0bd9b841c9e6c5a937c17656e2368f65da025588"
integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==
dependencies:
"@types/node" "*"
"@types/jsonwebtoken@^9.0.2":
version "9.0.7"
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz#e49b96c2b29356ed462e9708fc73b833014727d2"
@ -2301,7 +2286,7 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
jsonwebtoken@9.0.2:
jsonwebtoken@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==