Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into ui-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
AngelaZQ1 committed Oct 25, 2023
2 parents 56178ea + eb61b74 commit ca874a0
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 72 deletions.
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ Please describe how you tested this PR (both manually and with tests) Provide in
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] I've run the end to end tests
- [ ] Any dependent changes have been merged and published in downstream modules
2 changes: 1 addition & 1 deletion packages/api-v2/ormconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ormconfig: TypeOrmModuleOptions = {
username: process.env.POSTGRES_USERNAME,
password: process.env.POSTGRES_PASSWORD || "",
database: process.env.POSTGRES_DATABASE,
synchronize: false,
synchronize: process.env.NODE_ENV === "testing",
entities: [Student, Plan],
migrations: ["./dist/migrations/*.js"],
cli: {
Expand Down
2 changes: 1 addition & 1 deletion packages/api-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:db:up": "docker-compose -f ../../infrastructure/test/docker-compose.e2e.yml up -d",
"test:db:down": "docker-compose -f ../../infrastructure/test/docker-compose.e2e.yml down",
"test:e2e": "yarn g:cross-env NODE_ENV=testing jest --config ./test/jest-e2e.json --detectOpenHandles",
"test:e2e": "yarn g:cross-env NODE_ENV=testing jest --config ./test/jest-e2e.json --detectOpenHandles --no-cache --force-exit",
"typeorm": "yarn g:cross-env NODE_ENV=development ts-node --project ./tsconfig.json ../../node_modules/typeorm/cli.js",
"dev:db:reset": "yarn typeorm schema:drop",
"dev:migration:generate": "yarn dev:db:reset && yarn typeorm migration:run && yarn typeorm migration:generate",
Expand Down
8 changes: 5 additions & 3 deletions packages/api-v2/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ export class AuthController {
sameSite: "strict",
secure: isSecure,
});
await this.emailConfirmationService.sendVerificationLink(
createStudentDto.email
);
if (process.env.NODE_ENV !== "testing") {
await this.emailConfirmationService.sendVerificationLink(
createStudentDto.email
);
}
return student;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/api-v2/src/auth/auth.errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ export class TokenExpiredError extends Error {
constructor() {
super();
}
}
}
4 changes: 1 addition & 3 deletions packages/api-v2/src/auth/interfaces/authenticated-request.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Student } from "src/student/entities/student.entity";

/**
* Represents an authenticated request using the JwtAuthGuard.
*/
/** Represents an authenticated request using the JwtAuthGuard. */
export interface AuthenticatedRequest extends Request {
user: Student;
}
4 changes: 1 addition & 3 deletions packages/api-v2/src/auth/interfaces/jwt-payload.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/**
* Represents the information stored in the JWT.
*/
/** Represents the information stored in the JWT. */
export interface JwtPayload {
uuid: string;
email: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/api-v2/src/environment-variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export interface EnvironmentVariables {
EMAIL_SERVICE: string;
EMAIL_USER: string;
EMAIL_PASSWORD: string;
FORGOT_PASSWORD_URL: string
FORGOT_PASSWORD_URL: string;
}
4 changes: 1 addition & 3 deletions packages/api-v2/src/guards/dev-route.guard.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
import { Observable } from "rxjs";

/**
* Guards dev routes so that they are not accessible in production.
*/
/** Guards dev routes so that they are not accessible in production. */
@Injectable()
export class DevRouteGuard implements CanActivate {
canActivate(
Expand Down
6 changes: 3 additions & 3 deletions packages/api-v2/src/guards/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

/**
* Used to protect any route with the JWT strategy.
* The JWT strategy verifies a JWT in the request and attaches the student to
* the request object on successful verfication.
* Used to protect any route with the JWT strategy. The JWT strategy verifies a
* JWT in the request and attaches the student to the request object on
* successful verfication.
*/
@Injectable()
export class JwtAuthGuard extends AuthGuard("jwt") {}
15 changes: 11 additions & 4 deletions packages/api-v2/src/student/student.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ import {
ChangePasswordDto,
wrongPasswordError,
} from "@graduate/common";
import { EmailAlreadyExists, WeakPassword, WrongPassword } from "./student.errors";
import {
EmailAlreadyExists,
WeakPassword,
WrongPassword,
} from "./student.errors";

@Controller("students")
export class StudentController {
constructor(private readonly studentService: StudentService) { }
constructor(private readonly studentService: StudentService) {}

@UseGuards(JwtAuthGuard)
@Get("me")
Expand Down Expand Up @@ -123,12 +127,15 @@ export class StudentController {
@Req() req: AuthenticatedRequest,
@Body() changePasswordDto: ChangePasswordDto
): Promise<void> {
const changePasswordResult = await this.studentService.changePassword(req.user.uuid, changePasswordDto);
const changePasswordResult = await this.studentService.changePassword(
req.user.uuid,
changePasswordDto
);
if (changePasswordResult instanceof WrongPassword) {
throw new BadRequestException(wrongPasswordError);
}
if (changePasswordResult instanceof WeakPassword) {
throw new BadRequestException(weakPasswordError)
throw new BadRequestException(weakPasswordError);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/api-v2/src/student/student.errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ export class EmailNotConfirmed extends Error {
constructor() {
super();
}
}
}
55 changes: 37 additions & 18 deletions packages/api-v2/src/student/student.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
UpdateStudentDto,
} from "@graduate/common";
import { Student } from "./entities/student.entity";
import { EmailAlreadyExists, NewPasswordsDontMatch, WeakPassword, WrongPassword } from "./student.errors";
import {
EmailAlreadyExists,
NewPasswordsDontMatch,
WeakPassword,
WrongPassword,
} from "./student.errors";

@Injectable()
export class StudentService {
Expand All @@ -25,7 +30,7 @@ export class StudentService {
constructor(
@InjectRepository(Student)
private studentRepository: Repository<Student>
) { }
) {}

async create(
createStudentDto: SignUpStudentDto
Expand Down Expand Up @@ -161,49 +166,63 @@ export class StudentService {
return formatServiceCtx(StudentService.name, methodName);
}

async changePassword(uuid: any, changePasswordDto: ChangePasswordDto): Promise<void | WeakPassword | WrongPassword> {
const { currentPassword, newPassword, newPasswordConfirm } = changePasswordDto;
async changePassword(
uuid: any,
changePasswordDto: ChangePasswordDto
): Promise<void | WeakPassword | WrongPassword> {
const { currentPassword, newPassword, newPasswordConfirm } =
changePasswordDto;
const student = await this.findByUuid(uuid);

if (newPassword !== newPasswordConfirm) {
return new NewPasswordsDontMatch();
}

const { password: trueHashedPassword } = student;
const isValidPassword = await bcrypt.compare(currentPassword, trueHashedPassword);
const isValidPassword = await bcrypt.compare(
currentPassword,
trueHashedPassword
);

if (!isValidPassword) {
this.logger.debug(
{ message: "Invalid password", oldPassword: currentPassword },
);
this.logger.debug({
message: "Invalid password",
oldPassword: currentPassword,
});
return new WrongPassword();
}

if (!isStrongPassword(newPassword)) {
this.logger.debug(
{ message: "weak password", oldPassword: currentPassword },
);
this.logger.debug({
message: "weak password",
oldPassword: currentPassword,
});
return new WeakPassword();
}
await this.studentRepository.save(Object.assign(student, { password: newPassword }));
await this.studentRepository.save(
Object.assign(student, { password: newPassword })
);
}

async resetPassword(email, resetPasswordData: ResetPasswordDto): Promise<Student | Error> {
async resetPassword(
email,
resetPasswordData: ResetPasswordDto
): Promise<Student | Error> {
const { password, passwordConfirm } = resetPasswordData;

const student = await this.findByEmail(email)
const student = await this.findByEmail(email);

if (password !== passwordConfirm) {
return new NewPasswordsDontMatch();
}

if (!isStrongPassword(password)) {
this.logger.debug(
{ message: "weak password", password },
);
this.logger.debug({ message: "weak password", password });
return new WeakPassword();
}

return await this.studentRepository.save(Object.assign(student, { password }))
return await this.studentRepository.save(
Object.assign(student, { password })
);
}
}
15 changes: 13 additions & 2 deletions packages/api-v2/test/auth/auth.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe("AuthController (e2e)", () => {
let app: INestApplication;
let connection: Connection;

beforeEach(async () => {
beforeAll(async () => {
app = await initializeApp();
connection = app.get(Connection);

Expand All @@ -30,7 +30,8 @@ describe("AuthController (e2e)", () => {
.post("/auth/register")
.send({
email: "test-register@gmail.com",
password: "1234567890",
password: "1234567890a",
passwordConfirm: "1234567890a",
})
.expect(201);

Expand All @@ -50,13 +51,23 @@ describe("AuthController (e2e)", () => {
.into(Student)
.values([{ ...testUser1 }]);

await request(app.getHttpServer())
.post("/auth/register")
.send(testUser1)
.expect(201);

await request(app.getHttpServer())
.post("/auth/register")
.send(testUser1)
.expect(400);
});

it("logs in with valid credentials", async () => {
await request(app.getHttpServer())
.post("/auth/register")
.send(testUser1)
.expect(201);

const res = await request(app.getHttpServer())
.post("/auth/login")
.send(testUser1)
Expand Down
3 changes: 3 additions & 0 deletions packages/api-v2/test/jest-e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"moduleNameMapper": {
"^src/(.*)": "<rootDir>/../src/$1"
},
"transformIgnorePatterns": ["^.+\\.js$"]
}
10 changes: 5 additions & 5 deletions packages/api-v2/test/major/major.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("MajorController (e2e)", () => {

it("retrieves the major for a valid year and major name", async () => {
const response = await request(app.getHttpServer())
.post("/majors/2022/Computer%20Science,%20BSCS")
.get("/majors/2022/Computer%20Science,%20BSCS")
.expect(200);

const major = response.body;
Expand All @@ -25,14 +25,14 @@ describe("MajorController (e2e)", () => {
it("fails to retrieve a major from an invalid year", () => {
const INVALID_YEAR = 2000;
return request(app.getHttpServer())
.post(`/majors/${INVALID_YEAR}/Computer%20Science,%20BSCS`)
.expect(400);
.get(`/majors/${INVALID_YEAR}/Computer%20Science,%20BSCS`)
.expect(404);
});

it("fails to retrieve a major from a valid year but invalid major name", () => {
const INVALID_MAJOR_NAME = "wrong";
return request(app.getHttpServer())
.post(`/majors/2022/${INVALID_MAJOR_NAME}`)
.expect(400);
.get(`/majors/2022/${INVALID_MAJOR_NAME}`)
.expect(404);
});
});
Loading

0 comments on commit ca874a0

Please sign in to comment.