diff --git a/apps/api/src/users/users.controller.ts b/apps/api/src/account/account.controller.ts similarity index 66% rename from apps/api/src/users/users.controller.ts rename to apps/api/src/account/account.controller.ts index 52584ca..0ac980c 100644 --- a/apps/api/src/users/users.controller.ts +++ b/apps/api/src/account/account.controller.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/explicit-member-accessibility */ /* eslint-disable class-methods-use-this */ /* eslint-disable import/no-extraneous-dependencies */ -import { CreateUserDto } from './dto/create-user.dto'; -import { UsersService } from './users.service'; +import { AccountService } from './account.service'; +import { CreateAccountDto } from './dto/create-account.dto'; import { Body, Controller, @@ -20,9 +20,9 @@ import { cookieOptions } from 'src/config/cookie'; import { env } from 'src/config/env'; import { Credentials } from 'src/dto/credentials'; -@Controller('users') -export class UsersController { - constructor(private readonly usersService: UsersService) {} +@Controller('account') +export class AccountController { + constructor(private readonly accountService: AccountService) {} private clearCookies(req, reply) { if (req.cookies) { @@ -35,11 +35,11 @@ export class UsersController { } @Post('/create') - async create(@Body() createUserDto: CreateUserDto, @Res() reply: FastifyReply) { + async create(@Body() createAccountDto: CreateAccountDto, @Res() reply: FastifyReply) { try { - const createdUser = await this.usersService.create(createUserDto); + const createdAccount = await this.accountService.create(createAccountDto); - return reply.send(createdUser); + return reply.send(createdAccount); } catch (error) { throw new HttpException(error, HttpStatus.BAD_REQUEST); } @@ -47,18 +47,18 @@ export class UsersController { @Get() async findAll() { - return this.usersService.findAll(); + return this.accountService.findAll(); } @Delete('/delete/:login') - async delete(@Param('login') username: CreateUserDto['username']) { - return this.usersService.delete(username); + async delete(@Param('login') username: CreateAccountDto['username']) { + return this.accountService.delete(username); } @Post('/signin') async login(@Body() credentials: Credentials, @Res() reply: FastifyReply) { try { - const token = await this.usersService.login(credentials); + const token = await this.accountService.login(credentials); return reply.setCookie(env.COOKIE_TOKEN_NAME, token, cookieOptions).status(200).send(); } catch { @@ -77,8 +77,8 @@ export class UsersController { async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { const token = req.cookies[env.COOKIE_TOKEN_NAME]; - const user = await this.usersService.getUser(token); + const account = await this.accountService.getUser(token); - return reply.send(user); + return reply.send(account); } } diff --git a/apps/api/src/account/account.module.ts b/apps/api/src/account/account.module.ts new file mode 100644 index 0000000..f87c10f --- /dev/null +++ b/apps/api/src/account/account.module.ts @@ -0,0 +1,14 @@ +import { AccountController } from './account.controller'; +import { AccountService } from './account.service'; +import { Module } from '@nestjs/common'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Account, AccountSchema } from 'src/schemas/account.schema'; + +@Module({ + controllers: [AccountController], + exports: [], + imports: [MongooseModule.forFeature([{ name: Account.name, schema: AccountSchema }])], + providers: [AccountService], +}) +// eslint-disable-next-line @typescript-eslint/no-extraneous-class +export class AccountModule {} diff --git a/apps/api/src/users/users.service.ts b/apps/api/src/account/account.service.ts similarity index 51% rename from apps/api/src/users/users.service.ts rename to apps/api/src/account/account.service.ts index d932a9f..3931caf 100644 --- a/apps/api/src/users/users.service.ts +++ b/apps/api/src/account/account.service.ts @@ -1,4 +1,4 @@ -import type { CreateUserDto } from './dto/create-user.dto'; +import type { CreateAccountDto } from './dto/create-account.dto'; import { Injectable, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { InjectModel } from '@nestjs/mongoose'; @@ -7,48 +7,48 @@ import { Model } from 'mongoose'; import { omit } from 'radash'; import type { Credentials } from 'src/dto/credentials'; import type { TokenPayload } from 'src/ldap/types/jwt'; -import { User } from 'src/schemas/user.schema'; +import { Account } from 'src/schemas/account.schema'; import { generatePassword } from 'src/utils/password'; @Injectable() -export class UsersService { +export class AccountService { constructor( private readonly jwtService: JwtService, - @InjectModel(User.name) private userModel: Model + @InjectModel(Account.name) private accountModel: Model ) {} - public async create(createUserDto: CreateUserDto): Promise { - const password = createUserDto.password || generatePassword(); + public async create(createAccountDto: CreateAccountDto): Promise { + const password = createAccountDto.password || generatePassword(); - const createdUser = new this.userModel({ ...createUserDto, password }); + const createdAccount = new this.accountModel({ ...createAccountDto, password }); - createdUser.save(); + createdAccount.save(); - return { ...createdUser.toJSON(), password }; + return { ...createdAccount.toJSON(), password }; } - public async findAll(): Promise { - return this.userModel.find().exec(); + public async findAll(): Promise { + return this.accountModel.find().exec(); } public async delete(username: string) { - return this.userModel.findOneAndDelete({ username }).exec(); + return this.accountModel.findOneAndDelete({ username }).exec(); } public async login({ login, password }: Credentials) { try { - const user = await this.userModel.findOne({ username: login }); - if (!user) { - throw new UnauthorizedException('User not found'); + const account = await this.accountModel.findOne({ username: login }); + if (!account) { + throw new UnauthorizedException('Account not found'); } - const passwordMatch = await bcrypt.compare(password, user.password); + const passwordMatch = await bcrypt.compare(password, account.password); if (!passwordMatch) { throw new UnauthorizedException('Invalid login credentials'); } const payload: TokenPayload = { username: login, - ...omit(user.toJSON(), ['password']), + ...omit(account.toJSON(), ['password']), }; return this.jwtService.sign(payload); diff --git a/apps/api/src/users/dto/create-user.dto.ts b/apps/api/src/account/dto/create-account.dto.ts similarity index 88% rename from apps/api/src/users/dto/create-user.dto.ts rename to apps/api/src/account/dto/create-account.dto.ts index 74897d3..373a921 100644 --- a/apps/api/src/users/dto/create-user.dto.ts +++ b/apps/api/src/account/dto/create-account.dto.ts @@ -1,6 +1,6 @@ import { IsNotEmpty, IsOptional, IsString, MinLength } from 'class-validator'; -export class CreateUserDto { +export class CreateAccountDto { @IsString() @IsNotEmpty() readonly username: string; diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 8356048..f855004 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -1,8 +1,8 @@ +import { AccountModule } from './account/account.module'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { env } from './config/env'; import { LdapModule } from './ldap/ldap.module'; -import { UsersModule } from './users/users.module'; import { Global, Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { JwtModule } from '@nestjs/jwt'; @@ -23,7 +23,7 @@ import { MongooseModule } from '@nestjs/mongoose'; }, }), LdapModule, - UsersModule, + AccountModule, MongooseModule.forRoot(`mongodb://${env.MONGO_HOST}`), ], providers: [AppService], diff --git a/apps/api/src/schemas/user.schema.ts b/apps/api/src/schemas/account.schema.ts similarity index 74% rename from apps/api/src/schemas/user.schema.ts rename to apps/api/src/schemas/account.schema.ts index 6131445..5d2f973 100644 --- a/apps/api/src/schemas/user.schema.ts +++ b/apps/api/src/schemas/account.schema.ts @@ -3,10 +3,10 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import * as bcrypt from 'bcrypt'; import type { HydratedDocument } from 'mongoose'; -export type UserDocument = HydratedDocument; +export type UserDocument = HydratedDocument; @Schema({ strict: false }) -export class User { +export class Account { @Prop({ index: { unique: true }, required: true }) username: string; @@ -14,9 +14,9 @@ export class User { password: string; } -export const UserSchema = SchemaFactory.createForClass(User); +export const AccountSchema = SchemaFactory.createForClass(Account); -UserSchema.pre('save', async function (next) { +AccountSchema.pre('save', async function (next) { try { if (!this.isModified('password')) return next(); diff --git a/apps/api/src/users/users.controller.spec.ts b/apps/api/src/users/users.controller.spec.ts deleted file mode 100644 index 71c1341..0000000 --- a/apps/api/src/users/users.controller.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { UsersController } from './users.controller'; -import { UsersService } from './users.service'; -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; - -describe('UsersController', () => { - let controller: UsersController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [UsersController], - providers: [UsersService], - }).compile(); - - controller = module.get(UsersController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/apps/api/src/users/users.module.ts b/apps/api/src/users/users.module.ts deleted file mode 100644 index 5e27ca4..0000000 --- a/apps/api/src/users/users.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { UsersController } from './users.controller'; -import { UsersService } from './users.service'; -import { Module } from '@nestjs/common'; -import { MongooseModule } from '@nestjs/mongoose'; -import { User, UserSchema } from 'src/schemas/user.schema'; - -@Module({ - controllers: [UsersController], - exports: [], - imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])], - providers: [UsersService], -}) -// eslint-disable-next-line @typescript-eslint/no-extraneous-class -export class UsersModule {} diff --git a/apps/api/src/users/users.service.spec.ts b/apps/api/src/users/users.service.spec.ts deleted file mode 100644 index c619357..0000000 --- a/apps/api/src/users/users.service.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { UsersService } from './users.service'; -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; - -describe('UsersService', () => { - let service: UsersService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [UsersService], - }).compile(); - - service = module.get(UsersService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -});