feat: abstracted jwt service (#13016)
* remove unused JwtModule from the auth module * feat: create abstracted jwt service * refactor: tokens module and service use new jwt service * refactor: oauth-client module and repository use new jwt service * implement Morgans requests
This commit is contained in:
parent
78ecd2c9e1
commit
55327ce035
|
@ -2,6 +2,7 @@ import { AppLoggerMiddleware } from "@/app.logger.middleware";
|
|||
import appConfig from "@/config/app";
|
||||
import { AuthModule } from "@/modules/auth/auth.module";
|
||||
import { EndpointsModule } from "@/modules/endpoints.module";
|
||||
import { JwtModule } from "@/modules/jwt/jwt.module";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
|
@ -18,6 +19,7 @@ import { AppController } from "./app.controller";
|
|||
PrismaModule,
|
||||
EndpointsModule,
|
||||
AuthModule,
|
||||
JwtModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
})
|
||||
|
|
|
@ -9,18 +9,10 @@ import { OAuthFlowService } from "@/modules/oauth-clients/services/oauth-flow.se
|
|||
import { TokensModule } from "@/modules/tokens/tokens.module";
|
||||
import { UsersModule } from "@/modules/users/users.module";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { JwtModule } from "@nestjs/jwt";
|
||||
import { PassportModule } from "@nestjs/passport";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
PassportModule,
|
||||
JwtModule.register({}),
|
||||
ApiKeyModule,
|
||||
UsersModule,
|
||||
MembershipsModule,
|
||||
TokensModule,
|
||||
],
|
||||
imports: [PassportModule, ApiKeyModule, UsersModule, MembershipsModule, TokensModule],
|
||||
providers: [
|
||||
ApiKeyAuthStrategy,
|
||||
NextAuthGuard,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { getEnv } from "@/env";
|
||||
import { JwtService } from "@/modules/jwt/jwt.service";
|
||||
import { Global, Module } from "@nestjs/common";
|
||||
import { JwtModule as NestJwtModule } from "@nestjs/jwt";
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [NestJwtModule.register({ secret: getEnv("JWT_SECRET") })],
|
||||
providers: [JwtService],
|
||||
exports: [JwtService],
|
||||
})
|
||||
export class JwtModule {}
|
|
@ -0,0 +1,31 @@
|
|||
import { Injectable } from "@nestjs/common";
|
||||
import { JwtService as NestJwtService } from "@nestjs/jwt";
|
||||
|
||||
@Injectable()
|
||||
export class JwtService {
|
||||
constructor(private readonly nestJwtService: NestJwtService) {}
|
||||
|
||||
signAccessToken(payload: Payload) {
|
||||
const accessToken = this.sign({ type: "access_token", ...payload });
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
signRefreshToken(payload: Payload) {
|
||||
const refreshToken = this.sign({ type: "refresh_token", ...payload });
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
sign(payload: Payload) {
|
||||
const issuedAtTime = this.getIssuedAtTime();
|
||||
|
||||
const token = this.nestJwtService.sign({ ...payload, iat: issuedAtTime });
|
||||
return token;
|
||||
}
|
||||
|
||||
getIssuedAtTime() {
|
||||
// divided by 1000 because iat (issued at time) is in seconds (not milliseconds) as informed by JWT speficication
|
||||
return Math.floor(Date.now() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
type Payload = Record<string | number | symbol, any>;
|
|
@ -1,4 +1,3 @@
|
|||
import { getEnv } from "@/env";
|
||||
import { AuthModule } from "@/modules/auth/auth.module";
|
||||
import { MembershipsModule } from "@/modules/memberships/memberships.module";
|
||||
import { OAuthClientUsersController } from "@/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller";
|
||||
|
@ -11,17 +10,10 @@ import { PrismaModule } from "@/modules/prisma/prisma.module";
|
|||
import { TokensRepository } from "@/modules/tokens/tokens.repository";
|
||||
import { UsersModule } from "@/modules/users/users.module";
|
||||
import { Global, Module } from "@nestjs/common";
|
||||
import { JwtModule } from "@nestjs/jwt";
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [
|
||||
PrismaModule,
|
||||
AuthModule,
|
||||
UsersModule,
|
||||
MembershipsModule,
|
||||
JwtModule.register({ secret: getEnv("JWT_SECRET") }),
|
||||
],
|
||||
imports: [PrismaModule, AuthModule, UsersModule, MembershipsModule],
|
||||
providers: [OAuthClientRepository, OAuthClientCredentialsGuard, TokensRepository, OAuthFlowService],
|
||||
controllers: [OAuthClientUsersController, OAuthClientsController, OAuthFlowController],
|
||||
exports: [OAuthClientRepository, OAuthClientCredentialsGuard],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { JwtService } from "@/modules/jwt/jwt.service";
|
||||
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { JwtService } from "@nestjs/jwt";
|
||||
import type { PlatformOAuthClient } from "@prisma/client";
|
||||
|
||||
import type { CreateOAuthClientInput } from "@calcom/platform-types";
|
||||
|
@ -18,7 +18,7 @@ export class OAuthClientRepository {
|
|||
return this.dbWrite.prisma.platformOAuthClient.create({
|
||||
data: {
|
||||
...data,
|
||||
secret: await this.jwtService.signAsync(JSON.stringify(data)),
|
||||
secret: this.jwtService.sign(data),
|
||||
organizationId,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import { getEnv } from "@/env";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { TokensRepository } from "@/modules/tokens/tokens.repository";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { JwtModule } from "@nestjs/jwt";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
JwtModule.register({
|
||||
secret: getEnv("NEXTAUTH_SECRET"),
|
||||
}),
|
||||
PrismaModule,
|
||||
],
|
||||
imports: [PrismaModule],
|
||||
providers: [TokensRepository],
|
||||
exports: [TokensRepository],
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { JwtService } from "@/modules/jwt/jwt.service";
|
||||
import { PrismaReadService } from "@/modules/prisma/prisma-read.service";
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { JwtService } from "@nestjs/jwt";
|
||||
import { PlatformAuthorizationToken } from "@prisma/client";
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
|
@ -43,14 +43,10 @@ export class TokensRepository {
|
|||
const accessExpiry = DateTime.now().plus({ days: 1 }).startOf("day").toJSDate();
|
||||
const refreshExpiry = DateTime.now().plus({ year: 1 }).startOf("day").toJSDate();
|
||||
|
||||
const issuedAtTime = Math.floor(Date.now() / 1000);
|
||||
|
||||
const [accessToken, refreshToken] = await this.dbWrite.prisma.$transaction([
|
||||
this.dbWrite.prisma.accessToken.create({
|
||||
data: {
|
||||
secret: this.jwtService.sign(
|
||||
JSON.stringify({ type: "access_token", clientId, ownerId, iat: issuedAtTime })
|
||||
),
|
||||
secret: this.jwtService.signAccessToken({ clientId, ownerId }),
|
||||
expiresAt: accessExpiry,
|
||||
client: { connect: { id: clientId } },
|
||||
owner: { connect: { id: ownerId } },
|
||||
|
@ -58,9 +54,7 @@ export class TokensRepository {
|
|||
}),
|
||||
this.dbWrite.prisma.refreshToken.create({
|
||||
data: {
|
||||
secret: this.jwtService.sign(
|
||||
JSON.stringify({ type: "refresh_token", clientId, ownerId, iat: issuedAtTime })
|
||||
),
|
||||
secret: this.jwtService.signRefreshToken({ clientId, ownerId }),
|
||||
expiresAt: refreshExpiry,
|
||||
client: { connect: { id: clientId } },
|
||||
owner: { connect: { id: ownerId } },
|
||||
|
@ -103,8 +97,6 @@ export class TokensRepository {
|
|||
const accessExpiry = DateTime.now().plus({ days: 1 }).startOf("day").toJSDate();
|
||||
const refreshExpiry = DateTime.now().plus({ year: 1 }).startOf("day").toJSDate();
|
||||
|
||||
const issuedAtTime = Math.floor(Date.now() / 1000);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [_, _refresh, accessToken, refreshToken] = await this.dbWrite.prisma.$transaction([
|
||||
this.dbWrite.prisma.accessToken.deleteMany({
|
||||
|
@ -113,9 +105,7 @@ export class TokensRepository {
|
|||
this.dbWrite.prisma.refreshToken.delete({ where: { secret: refreshTokenSecret } }),
|
||||
this.dbWrite.prisma.accessToken.create({
|
||||
data: {
|
||||
secret: this.jwtService.sign(
|
||||
JSON.stringify({ type: "access_token", clientId, userId: tokenUserId, iat: issuedAtTime })
|
||||
),
|
||||
secret: this.jwtService.signAccessToken({ clientId, userId: tokenUserId }),
|
||||
expiresAt: accessExpiry,
|
||||
client: { connect: { id: clientId } },
|
||||
owner: { connect: { id: tokenUserId } },
|
||||
|
@ -123,9 +113,7 @@ export class TokensRepository {
|
|||
}),
|
||||
this.dbWrite.prisma.refreshToken.create({
|
||||
data: {
|
||||
secret: this.jwtService.sign(
|
||||
JSON.stringify({ type: "refresh_token", clientId, userId: tokenUserId, iat: issuedAtTime })
|
||||
),
|
||||
secret: this.jwtService.signRefreshToken({ clientId, userId: tokenUserId }),
|
||||
expiresAt: refreshExpiry,
|
||||
client: { connect: { id: clientId } },
|
||||
owner: { connect: { id: tokenUserId } },
|
||||
|
|
Loading…
Reference in New Issue
Block a user