Skip to content

Commit

Permalink
feat: admin update super admin status
Browse files Browse the repository at this point in the history
  • Loading branch information
eleanorreem committed Aug 14, 2024
1 parent 2832681 commit 37d6272
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async function bootstrap() {
const logger = app.get(Logger);
app.useLogger(logger);
app.useGlobalInterceptors(new LoggingInterceptor());
app.useGlobalPipes(new ValidationPipe({ transform: true }));
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
app.useGlobalFilters(new ExceptionsFilter());
await app.listen(PORT);
console.log(`Listening on localhost:${PORT}, CTRL+C to stop`);
Expand Down
45 changes: 45 additions & 0 deletions src/user/dtos/admin-update-user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsDate, IsEmail, IsOptional, IsString } from 'class-validator';
import { EMAIL_REMINDERS_FREQUENCY } from '../../utils/constants';

export class AdminUpdateUserDto {
@IsString()
@IsOptional()
@ApiProperty({ type: String })
name: string;

@IsBoolean()
@IsOptional()
@ApiProperty({ type: Boolean })
contactPermission: boolean;

@IsBoolean()
@IsOptional()
@ApiProperty({ type: Boolean })
serviceEmailsPermission: boolean;

@IsOptional()
@IsString()
@ApiProperty({ type: String })
emailRemindersFrequency: EMAIL_REMINDERS_FREQUENCY;

@IsString()
@IsOptional()
@ApiProperty({ type: String })
signUpLanguage: string;

@IsDate()
@IsOptional()
@ApiProperty({ type: 'date' })
lastActiveAt: Date;

@IsEmail({})
@IsOptional()
@ApiProperty({ type: 'email' })
email: string;

@IsBoolean({})
@IsOptional()
@ApiProperty({ type: 'boolean' })
isSuperAdmin: boolean;
}
6 changes: 4 additions & 2 deletions src/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SuperAdminAuthGuard } from 'src/partner-admin/super-admin-auth.guard';
import { formatUserObject } from 'src/utils/serialize';
import { FirebaseAuthGuard } from '../firebase/firebase-auth.guard';
import { ControllerDecorator } from '../utils/controller.decorator';
import { AdminUpdateUserDto } from './dtos/admin-update-user.dto';
import { CreateUserDto } from './dtos/create-user.dto';
import { GetUserDto } from './dtos/get-user.dto';
import { UpdateUserDto } from './dtos/update-user.dto';
Expand Down Expand Up @@ -84,14 +85,15 @@ export class UserController {
@Patch()
@UseGuards(FirebaseAuthGuard)
async updateUser(@Body() updateUserDto: UpdateUserDto, @Req() req: Request) {
console.log('>>>>', updateUserDto);
return await this.userService.updateUser(updateUserDto, req['user'].user.id);
}

@ApiBearerAuth()
@Patch('/admin/:id')
@UseGuards(SuperAdminAuthGuard)
async adminUpdateUser(@Param() { id }, @Body() updateUserDto: UpdateUserDto) {
return await this.userService.updateUser(updateUserDto, id);
async adminUpdateUser(@Param() { id }, @Body() adminUpdateUserDto: AdminUpdateUserDto) {
return await this.userService.adminUpdateUser(adminUpdateUserDto, id);
}

@ApiBearerAuth()
Expand Down
16 changes: 16 additions & 0 deletions src/user/user.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { createQueryBuilderMock } from '../../test/utils/mockUtils';
import { AuthService } from '../auth/auth.service';
import { UserEntity } from '../entities/user.entity';
import { PartnerAccessService } from '../partner-access/partner-access.service';
import { AdminUpdateUserDto } from './dtos/admin-update-user.dto';
import { CreateUserDto } from './dtos/create-user.dto';
import { UpdateUserDto } from './dtos/update-user.dto';
import { UserService } from './user.service';
Expand Down Expand Up @@ -542,4 +543,19 @@ describe('UserService', () => {
expect(users).toEqual([{ ...mockUserEntity, email: '[email protected]' }]);
});
});

describe('adminUpdateUser', () => {
it("should update user's superAdmin status", async () => {
const user = mockUserEntity;
const userSaveSpy = jest.spyOn(repo, 'save').mockImplementationOnce(async () => {
return user;
});
const updatedUser = await service.adminUpdateUser(
{ isSuperAdmin: true } as AdminUpdateUserDto,
user.id,
);
expect(updatedUser).toHaveProperty('isSuperAdmin', true);
expect(userSaveSpy).toHaveBeenCalled();
});
});
});
23 changes: 23 additions & 0 deletions src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { AuthService } from '../auth/auth.service';
import { basePartnerAccess, PartnerAccessService } from '../partner-access/partner-access.service';
import { formatUserObject } from '../utils/serialize';
import { generateRandomString } from '../utils/utils';
import { AdminUpdateUserDto } from './dtos/admin-update-user.dto';
import { CreateUserDto } from './dtos/create-user.dto';
import { GetUserDto } from './dtos/get-user.dto';
import { UpdateUserDto } from './dtos/update-user.dto';
Expand Down Expand Up @@ -245,6 +246,28 @@ export class UserService {
return updatedUser;
}

public async adminUpdateUser(updateUserDto: Partial<AdminUpdateUserDto>, userId: string) {
const { isSuperAdmin, ...updateUserDtoWithoutSuperAdmin } = updateUserDto;

await this.updateUser(updateUserDtoWithoutSuperAdmin, userId);

if (typeof isSuperAdmin !== 'undefined') {
const user = await this.userRepository.findOneBy({ id: userId });
if (user.isSuperAdmin !== isSuperAdmin) {
const updatedUser = await this.userRepository.save({
...user,
isSuperAdmin,
});
this.logger.log({
event: USER_SERVICE_EVENTS.USER_UPDATED,
userId: user.id,
fields: ['isSuperAdmin'],
});
return updatedUser;
}
}
}

public async deleteCypressTestUsers(clean = false): Promise<UserEntity[]> {
let deletedUsers: UserEntity[] = [];
try {
Expand Down

0 comments on commit 37d6272

Please sign in to comment.