apps/api: move redis caching feature to ldap module
This commit is contained in:
parent
01422661e8
commit
a42aa89aec
@ -71,4 +71,13 @@ export class LdapController {
|
||||
return reply.status(HttpStatus.UNAUTHORIZED).send();
|
||||
}
|
||||
}
|
||||
|
||||
@Get('/get-user')
|
||||
async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) {
|
||||
const token = req.cookies[env.COOKIE_TOKEN_NAME];
|
||||
|
||||
const user = await this.ldapService.getUser(token);
|
||||
|
||||
return reply.send(user);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,21 @@
|
||||
import { UsersModule } from '../users/users.module';
|
||||
import { LdapController } from './ldap.controller';
|
||||
import { LdapService } from './ldap.service';
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
import { Module } from '@nestjs/common';
|
||||
import * as redisStore from 'cache-manager-ioredis';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
import { env } from 'src/config/env';
|
||||
|
||||
@Module({
|
||||
controllers: [LdapController],
|
||||
imports: [UsersModule],
|
||||
imports: [
|
||||
CacheModule.register<RedisOptions>({
|
||||
host: env.REDIS_HOST,
|
||||
port: env.REDIS_PORT,
|
||||
store: redisStore,
|
||||
ttl: env.API_CACHE_TTL,
|
||||
}),
|
||||
],
|
||||
providers: [LdapService],
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import { UsersCache } from '../users/users.cache';
|
||||
import type { DecodedToken, TokenPayload } from './types/jwt';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { Cache } from 'cache-manager';
|
||||
import { env } from 'src/config/env';
|
||||
import * as ldap from 'src/utils/ldap';
|
||||
|
||||
@Injectable()
|
||||
export class LdapService {
|
||||
constructor(
|
||||
private readonly usersCache: UsersCache,
|
||||
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
|
||||
private readonly jwtService: JwtService
|
||||
) {}
|
||||
|
||||
@ -16,7 +17,7 @@ export class LdapService {
|
||||
const user = await ldap.authenticate(login, password);
|
||||
const { username } = user;
|
||||
|
||||
await this.usersCache.addUser(username, user);
|
||||
await this.cacheManager.set(username, user);
|
||||
|
||||
const payload: TokenPayload = {
|
||||
domain: env.LDAP_DOMAIN,
|
||||
@ -28,7 +29,10 @@ export class LdapService {
|
||||
|
||||
public async logout(token: string) {
|
||||
const { username } = this.jwtService.decode(token) as DecodedToken;
|
||||
await this.usersCache.deleteUser(username);
|
||||
|
||||
if (this.cacheManager.get(username)) {
|
||||
await this.cacheManager.del(username);
|
||||
}
|
||||
}
|
||||
|
||||
public checkToken(token: string) {
|
||||
@ -36,8 +40,25 @@ export class LdapService {
|
||||
}
|
||||
|
||||
public refreshToken(token: string) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { exp, iat, ...payload } = this.jwtService.decode(token) as DecodedToken;
|
||||
|
||||
return this.jwtService.sign(payload);
|
||||
}
|
||||
|
||||
public async getUser(token: string) {
|
||||
const { username } = this.jwtService.decode(token) as DecodedToken;
|
||||
|
||||
const cachedUser = await this.cacheManager.get(username);
|
||||
|
||||
if (!cachedUser) {
|
||||
const user = await ldap.authenticate(username);
|
||||
|
||||
await this.cacheManager.set(username, user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return cachedUser;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Cache } from 'cache-manager';
|
||||
|
||||
@Injectable()
|
||||
export class UsersCache {
|
||||
constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}
|
||||
public async getUser<T extends object>(username: string) {
|
||||
return (await this.cacheManager.get(username)) as T;
|
||||
}
|
||||
|
||||
public async addUser<T extends object>(username: string, user: T) {
|
||||
await this.cacheManager.set(username, user);
|
||||
}
|
||||
|
||||
public async deleteUser(username: string) {
|
||||
if (this.cacheManager.get(username)) {
|
||||
await this.cacheManager.del(username);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,24 +3,13 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { CreateUserDto } from './dto/create-user.dto';
|
||||
import { UsersService } from './users.service';
|
||||
import { Body, Controller, Delete, Get, Param, Post, Req, Res } from '@nestjs/common';
|
||||
import { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { env } from 'src/config/env';
|
||||
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common';
|
||||
import { User } from 'src/schemas/user.schema';
|
||||
|
||||
@Controller()
|
||||
export class UsersController {
|
||||
constructor(private readonly usersService: UsersService) {}
|
||||
|
||||
@Get('/get-user')
|
||||
async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) {
|
||||
const token = req.cookies[env.COOKIE_TOKEN_NAME];
|
||||
|
||||
const user = await this.usersService.getUser(token);
|
||||
|
||||
return reply.send(user);
|
||||
}
|
||||
|
||||
@Post('/users/create-user')
|
||||
async create(@Body() createUserDto: CreateUserDto) {
|
||||
return this.usersService.create(createUserDto);
|
||||
|
||||
@ -1,27 +1,14 @@
|
||||
import { UsersCache } from './users.cache';
|
||||
import { UsersController } from './users.controller';
|
||||
import { UsersService } from './users.service';
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MongooseModule } from '@nestjs/mongoose';
|
||||
import * as redisStore from 'cache-manager-ioredis';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
import { env } from 'src/config/env';
|
||||
import { User, UserSchema } from 'src/schemas/user.schema';
|
||||
|
||||
@Module({
|
||||
controllers: [UsersController],
|
||||
exports: [UsersCache],
|
||||
imports: [
|
||||
CacheModule.register<RedisOptions>({
|
||||
host: env.REDIS_HOST,
|
||||
port: env.REDIS_PORT,
|
||||
store: redisStore,
|
||||
ttl: env.API_CACHE_TTL,
|
||||
}),
|
||||
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
|
||||
],
|
||||
providers: [UsersService, UsersCache],
|
||||
exports: [],
|
||||
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
|
||||
providers: [UsersService],
|
||||
})
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
export class UsersModule {}
|
||||
|
||||
@ -1,40 +1,19 @@
|
||||
import type { DecodedToken } from '../ldap/types/jwt';
|
||||
import type { CreateUserDto } from './dto/create-user.dto';
|
||||
import { UsersCache } from './users.cache';
|
||||
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { InjectModel } from '@nestjs/mongoose';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { Model } from 'mongoose';
|
||||
import { User } from 'src/schemas/user.schema';
|
||||
import * as ldap from 'src/utils/ldap';
|
||||
import { generatePassword } from 'src/utils/password';
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
constructor(
|
||||
private readonly usersCache: UsersCache,
|
||||
private readonly jwtService: JwtService,
|
||||
@InjectModel(User.name)
|
||||
private userModel: Model<User>
|
||||
@InjectModel(User.name) private userModel: Model<User>
|
||||
) {}
|
||||
|
||||
public async getUser(token: string) {
|
||||
const { username } = this.jwtService.decode(token) as DecodedToken;
|
||||
|
||||
const cachedUser = await this.usersCache.getUser(username);
|
||||
|
||||
if (!cachedUser) {
|
||||
const user = await ldap.authenticate(username);
|
||||
|
||||
await this.usersCache.addUser(username, user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return cachedUser;
|
||||
}
|
||||
|
||||
public async create(createUserDto: CreateUserDto): Promise<User> {
|
||||
const password = createUserDto.password || generatePassword();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user