Skip to content

Commit

Permalink
replace isAdmin with scope
Browse files Browse the repository at this point in the history
  • Loading branch information
laurenbrissette committed Feb 3, 2025
1 parent 9d0e4b0 commit 0aa033c
Show file tree
Hide file tree
Showing 19 changed files with 51 additions and 42 deletions.
7 changes: 6 additions & 1 deletion apps/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ enum SignerType {
USER_LIST
}

enum EmployeeScope {
BASE_USER
ADMIN
}

// `Departments` represent the various departments that employees could work in.
model Department {
id String @id @default(uuid()) @db.Uuid
Expand All @@ -39,7 +44,7 @@ model Employee {
lastName String @db.VarChar(255)
email String @unique @db.VarChar(255)
signatureLink String @db.VarChar(255)
isAdmin Boolean @default(false) @db.Boolean
scope EmployeeScope @default(BASE_USER) // TODO @db tag
pswdHash String? @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Expand Down
14 changes: 7 additions & 7 deletions apps/server/prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PrismaClient } from '@prisma/client';
import { EmployeeScope, PrismaClient } from '@prisma/client';
import { v4 as uuidv4 } from 'uuid';

const prisma = new PrismaClient();
Expand Down Expand Up @@ -49,7 +49,7 @@ type EmployeeData = {
email: string;
positionId: string;
signatureLink: string;
isAdmin: boolean;
scope: EmployeeScope;
};

// update or insert employee to database based on the employee id
Expand All @@ -66,7 +66,7 @@ async function upsertEmployee(empData: EmployeeData) {
position: {
connect: { id: empData.positionId },
},
isAdmin: empData.isAdmin,
scope: empData.scope,
},
});
}
Expand Down Expand Up @@ -389,7 +389,7 @@ async function main() {
email: 'zhang.iri@northeastern.edu',
positionId: CHIEF_OF_STAFF_UUID,
signatureLink: DEV_SIGNATURE_LINK,
isAdmin: true,
scope: EmployeeScope.BASE_USER,
},
{
id: KAI_ZHENG_UUID,
Expand All @@ -398,7 +398,7 @@ async function main() {
email: 'zheng.kaiy@northeastern.edu',
positionId: CHIEF_FIN_OFFICER_UUID,
signatureLink: DEV_SIGNATURE_LINK,
isAdmin: true,
scope: EmployeeScope.BASE_USER,
},
{
id: ANGELA_WEIGL_UUID,
Expand All @@ -407,7 +407,7 @@ async function main() {
email: 'weigl.a@northeastern.edu',
positionId: AGG_DIR_UUID,
signatureLink: DEV_SIGNATURE_LINK,
isAdmin: true,
scope: EmployeeScope.BASE_USER,
},
{
id: ANSHUL_SHIRUDE_UUID,
Expand All @@ -416,7 +416,7 @@ async function main() {
email: 'shirude.a@northeastern.edu',
positionId: CHIEF_LEARNING_ENGAGEMENT_UUID,
signatureLink: DEV_SIGNATURE_LINK,
isAdmin: true,
scope: EmployeeScope.BASE_USER,
},
];

Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class AppController {
password: employeeDto.password,
signatureLink: employeeDto.signatureLink,
positionId: '',
isAdmin: employeeDto.isAdmin,
scope: employeeDto.scope,
};

const newEmployee = await this.authService.register(
Expand Down
7 changes: 4 additions & 3 deletions apps/server/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { EmployeeEntity } from '../employees/entities/employee.entity';
import { PositionBaseEntity } from '../positions/entities/position.entity';
import { DepartmentsService } from '../departments/departments.service';
import { PositionsService } from '../positions/positions.service';
import { EmployeeScope } from '@prisma/client';

describe('AuthService', () => {
let service: AuthService;
Expand Down Expand Up @@ -60,7 +61,7 @@ describe('AuthService', () => {
updatedAt: new Date(1672531200),
},
email: 'info@mfa.org',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: 'password',
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
Expand Down Expand Up @@ -89,7 +90,7 @@ describe('AuthService', () => {
updatedAt: new Date(1672531200),
},
email: 'info@mfa.org',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
refreshToken: null,
Expand Down Expand Up @@ -147,7 +148,7 @@ describe('AuthService', () => {
firstName: 'First',
lastName: 'Last',
positionId: 'position-id',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: null,
createdAt: new Date(0),
updatedAt: new Date(0),
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class AuthService {
sub: user.id,
positionId: user.positionId,
departmentId: user.position.departmentId,
isAdmin: user.isAdmin,
scope: user.scope,
};

const [accessToken, refreshToken] = await Promise.all([
Expand Down
13 changes: 4 additions & 9 deletions apps/server/src/auth/dto/register-employee.dto.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsNotEmpty,
IsString,
MinLength,
IsEmail,
IsBoolean,
} from 'class-validator';
import { EmployeeScope } from '@prisma/client';
import { IsNotEmpty, IsString, MinLength, IsEmail } from 'class-validator';

export class RegisterEmployeeDto {
@IsString()
Expand Down Expand Up @@ -44,8 +39,8 @@ export class RegisterEmployeeDto {
@ApiProperty()
signatureLink: string;

@IsBoolean()
@IsString()
@IsNotEmpty()
@ApiProperty()
isAdmin: boolean;
scope: EmployeeScope;
}
3 changes: 2 additions & 1 deletion apps/server/src/auth/guards/admin-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { EmployeeScope } from '@prisma/client';
import { Request } from 'express';

@Injectable()
Expand All @@ -23,7 +24,7 @@ export class AdminAuthGuard extends AuthGuard('jwt') {

handleRequest(err: any, user: any, info: any) {
// You can throw an exception based on either "info" or "err" arguments
if (err || !user || !user.isAdmin) {
if (err || !user || !(user.scope == EmployeeScope.ADMIN)) {
console.log(info);
throw err || new UnauthorizedException();
}
Expand Down
4 changes: 1 addition & 3 deletions apps/server/src/employees/dto/create-employee.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsBoolean,
IsEmail,
IsNotEmpty,
IsString,
Expand Down Expand Up @@ -40,8 +39,7 @@ export class CreateEmployeeDto {
@ApiProperty()
signatureLink: string;

@IsBoolean()
@IsNotEmpty()
@ApiProperty()
isAdmin: boolean;
scope: any;
}
9 changes: 5 additions & 4 deletions apps/server/src/employees/employees.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { EmployeesService } from './employees.service';
import { PrismaService } from '../prisma/prisma.service';
import { EmployeeEntity } from './entities/employee.entity';
import { LoggerServiceImpl } from '../logger/logger.service';
import { EmployeeScope } from '@prisma/client';

describe('EmployeesController', () => {
let controller: EmployeesController;
Expand Down Expand Up @@ -47,7 +48,7 @@ describe('EmployeesController', () => {
},
},
email: 'john.doe@example.com',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: 'thisIsASecureHash',
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
Expand All @@ -74,7 +75,7 @@ describe('EmployeesController', () => {
},
},
email: 'bilbo.baggins@example.com',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: 'thisIsASecureHash',
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
Expand Down Expand Up @@ -104,7 +105,7 @@ describe('EmployeesController', () => {
},
},
email: 'john.doe@example.com',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: 'thisIsASecureHash',
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
Expand All @@ -131,7 +132,7 @@ describe('EmployeesController', () => {
},
},
email: 'bilbo.baggins@example.com',
isAdmin: false,
scope: EmployeeScope.BASE_USER,
pswdHash: 'thisIsASecureHash',
createdAt: new Date(1672531200),
updatedAt: new Date(1672531200),
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/employees/employees.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class EmployeesService {
createEmployeeDto.password,
await bcrypt.genSalt(),
),
isAdmin: createEmployeeDto.isAdmin,
scope: createEmployeeDto.scope,
},
include: {
position: {
Expand Down
6 changes: 3 additions & 3 deletions apps/server/src/employees/entities/employee.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { Employee } from '@prisma/client';
import { Employee, EmployeeScope } from '@prisma/client';
import { PositionBaseEntity } from './../../positions/entities/position.entity';
import { Exclude } from 'class-transformer';

Expand All @@ -20,10 +20,10 @@ export class EmployeeBaseEntity implements Employee {
email: string;

@ApiProperty()
isAdmin: boolean;
signatureLink: string;

@ApiProperty()
signatureLink: string;
scope: EmployeeScope;

@Exclude()
pswdHash: string | null;
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { EmployeeScope } from '@prisma/client';

/* eslint-disable */
export default async () => {
const t = {
Expand Down Expand Up @@ -107,7 +109,7 @@ export default async () => {
positionId: { required: true, type: () => String },
email: { required: true, type: () => String },
password: { required: true, type: () => String, minLength: 5 },
isAdmin: { required: true, type: () => Boolean },
scope: { required: true, type: () => EmployeeScope },
},
},
],
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/client/models/CreateEmployeeDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export type CreateEmployeeDto = {
email: string;
password: string;
signatureLink: string;
isAdmin: boolean;
scope: Record<string, any>;
};

2 changes: 1 addition & 1 deletion apps/web/src/client/models/EmployeeBaseEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export type EmployeeBaseEntity = {
firstName: string;
lastName: string;
email: string;
isAdmin: boolean;
signatureLink: string;
scope: Record<string, any>;
positionId: string;
pswdHash: string | null;
createdAt: string;
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/client/models/EmployeeEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export type EmployeeEntity = {
firstName: string;
lastName: string;
email: string;
isAdmin: boolean;
signatureLink: string;
scope: Record<string, any>;
position: PositionBaseEntity;
positionId: string;
pswdHash: string | null;
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/client/models/RegisterEmployeeDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export type RegisterEmployeeDto = {
positionName: string;
departmentName: string;
signatureLink: string;
scope: Record<string, any>;
};

1 change: 1 addition & 0 deletions apps/web/src/client/models/UpdateEmployeeDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export type UpdateEmployeeDto = {
lastName?: string;
positionId?: string;
signatureLink?: string;
scope?: Record<string, any>;
};

7 changes: 5 additions & 2 deletions apps/web/src/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { loginRequest } from '@web/authConfig';
import { callMsGraph } from '@web/graph';
import { useMutation } from '@tanstack/react-query';
import { RegisterEmployeeDto } from '@web/client';
import { EmployeeScope } from '@prisma/client';

// Reference: https://blog.finiam.com/blog/predictable-react-authentication-with-the-context-api

export const AuthContext = createContext<AuthContextType>(
Expand Down Expand Up @@ -54,7 +56,7 @@ export const AuthProvider = ({ children }: any) => {
email: decoded.email,
firstName: decoded.firstName,
lastName: decoded.lastName,
isAdmin: decoded.isAdmin,
scope: decoded.scope,
};

setUser(user);
Expand Down Expand Up @@ -89,7 +91,7 @@ export const AuthProvider = ({ children }: any) => {
email: employee.email,
firstName: employee.firstName,
lastName: employee.lastName,
isAdmin: employee.isAdmin,
scope: EmployeeScope.BASE_USER,
});
})
.catch(async (_error) => {
Expand Down Expand Up @@ -194,6 +196,7 @@ export const AuthProvider = ({ children }: any) => {
departmentName: department,
positionName: position,
signatureLink: signatureLink,
scope: EmployeeScope,
};

registerEmployeeMutation.mutate(employee, {
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/context/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
FormFields,
FieldGroups,
} from '@web/components/createFormTemplate/createFormTemplateEditor/FormEditor';
import { EmployeeScope } from '@prisma/client';

// for storage in context
export type User = {
Expand All @@ -12,7 +13,7 @@ export type User = {
email: string;
firstName: string;
lastName: string;
isAdmin: boolean;
scope: EmployeeScope;
};
// jwt payload returned from server
export type jwtPayload = {
Expand All @@ -22,7 +23,7 @@ export type jwtPayload = {
email: string;
firstName: string;
lastName: string;
isAdmin: boolean;
scope: EmployeeScope;
};

export interface AuthContextType {
Expand Down

0 comments on commit 0aa033c

Please sign in to comment.