Skip to content

Commit

Permalink
added user status logic (ballerine-io#1792)
Browse files Browse the repository at this point in the history
  • Loading branch information
Blokh authored Dec 10, 2023
1 parent 19455e7 commit 0595e50
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 3 deletions.
2 changes: 1 addition & 1 deletion services/workflows-service/prisma/data-migrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "UserStatus" AS ENUM ('Active', 'Blocked', 'Deleted');

-- AlterTable
ALTER TABLE "User" ADD COLUMN "status" "UserStatus" NOT NULL DEFAULT 'Active';
7 changes: 7 additions & 0 deletions services/workflows-service/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ generator client {
provider = "prisma-client-js"
}

enum UserStatus {
Active
Blocked
Deleted
}

model User {
id String @id @default(cuid())
firstName String
Expand All @@ -16,6 +22,7 @@ model User {
password String
avatarUrl String?
roles Json
status UserStatus @default(Active)
userToProjects UserToProject[]
Expand Down
6 changes: 5 additions & 1 deletion services/workflows-service/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@nestjs/common';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserStatus } from '@prisma/client';
import { UserInfo } from '../user/user-info';
import { UserService } from '../user/user.service';
import { PasswordService } from './password/password.service';
Expand All @@ -12,7 +13,10 @@ export class AuthService {

async validateUser(email: string, password: string): Promise<UserInfo | null> {
const user = await this.userService.getByEmailUnscoped(email);

if (user && (await this.passwordService.compare(password, user.password))) {
if (user?.status !== UserStatus.Active) throw new UnauthorizedException('Unauthorized');

const { id, firstName, lastName, roles } = user;
const roleList = roles as string[];
return { id, email, firstName, lastName, roles: roleList };
Expand Down
18 changes: 18 additions & 0 deletions services/workflows-service/src/auth/auth.service.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const USER = {
...VALID_CREDENTIALS,
createdAt: new Date(),
id: VALID_ID,
status: 'Active',
roles: ['admin'],
updatedAt: new Date(),
};
Expand All @@ -41,6 +42,10 @@ const passwordService = {

describe('AuthService', () => {
//ARRANGE
beforeEach(() => {
USER.status = 'Active';
});

let service: AuthService;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
Expand Down Expand Up @@ -80,5 +85,18 @@ describe('AuthService', () => {
service.validateUser(INVALID_CREDENTIALS.email, INVALID_CREDENTIALS.password),
).resolves.toBe(null);
});

describe('when user is inactive', () => {
beforeEach(() => {
USER.status = 'Blocked';
});

it('it throws an UnauthorizedException', async () => {
await expect(
async () =>
await service.validateUser(VALID_CREDENTIALS.email, VALID_CREDENTIALS.password),
).rejects.toThrowError('Unauthorized');
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import * as common from '@nestjs/common';
import { UseGuards } from '@nestjs/common';
import * as swagger from '@nestjs/swagger';
import { UserService } from './user.service';
import { UserModel } from './user.model';
import { UserCreateDto } from '@/user/dtos/user-create';
import { AdminAuthGuard } from '@/common/guards/admin-auth.guard';
import { UseGuards } from '@nestjs/common';
import { ProjectIds } from '@/common/decorators/project-ids.decorator';
import type { TProjectId, TProjectIds } from '@/types';
import { CurrentProject } from '@/common/decorators/current-project.decorator';
import { UserStatus } from '@prisma/client';

@swagger.ApiTags('internal/users')
@common.Controller('internal/users')
Expand All @@ -20,6 +21,7 @@ export class UserControllerInternal {
async list(@ProjectIds() projectIds: TProjectIds): Promise<UserModel[]> {
return this.service.list(
{
where: { status: UserStatus.Active },
select: {
id: true,
firstName: true,
Expand Down

0 comments on commit 0595e50

Please sign in to comment.