Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: migrate /auth endpoint handling to Typescript #215

Merged
merged 62 commits into from
Sep 7, 2020

Conversation

karrui
Copy link
Contributor

@karrui karrui commented Aug 26, 2020

Problem

This PR tries to encapsulate the /auth route under a new auth module located in modules/auth.

The first Typescript integration tests are also written for auth.routes, using a new testing directory directly inside the module folder for closer integration. The various tsconfig and eslintrc files has been updated to accommodate this change.

Related to #144

Solution

Features:

  • New auth module containing
    • auth/auth.route
    • auth/auth.middlewares
    • auth/auth.controller
    • auth/auth.service
    • auth/auth.errors

Improvements:

  • Remove unused functions in old auth controller

Tests

  • Add unit tests for:

    • auth/auth.middlewares
    • auth/auth.controller
    • auth/auth.service
  • Add integration tests for:

    • auth/auth.route

Release Tests

  • Sign out should work properly
  • Logging in to existing user should work properly
    • Invalid OTP should return 422 with invalid OTP message
    • Entering wrong OTP 10 times should return 422, and subsequently entering correct OTP will still return 422.
    • Requesting for new OTP should work, and login successfully
  • Attempt to login as a new user by logging in with your open.gov.sg email; e.g. <youremail>[email protected]
    • Should create new user successfully upon log in, test with creating a form, log out and log back in. Your form should still be there.

@karrui karrui marked this pull request as draft August 26, 2020 11:17
karrui added 11 commits August 26, 2020 19:21
# Conflicts:
#	src/app/controllers/authentication.server.controller.js
#	src/app/modules/user/user.service.ts
#	src/loaders/express/index.ts
# Conflicts:
#	src/app/controllers/authentication.server.controller.js
# Conflicts:
#	src/app/controllers/authentication.server.controller.js
#	src/app/routes/authentication.server.routes.js
#	src/loaders/express/index.ts
#	tests/unit/backend/controllers/authentication.server.controller.spec.js
@karrui
Copy link
Contributor Author

karrui commented Sep 2, 2020

Ready for review. Please don't be scared by the high line count, it's just because it has a lot of new tests.

@karrui karrui marked this pull request as ready for review September 2, 2020 04:18
@karrui karrui changed the title wip: migrate /auth endpoint handling to Typescript feat: migrate /auth endpoint handling to Typescript Sep 2, 2020
@karrui karrui changed the title feat: migrate /auth endpoint handling to Typescript refactor: migrate /auth endpoint handling to Typescript Sep 2, 2020
@karrui
Copy link
Contributor Author

karrui commented Sep 2, 2020

Forgot /signout integration tests...

Comment on lines 108 to 120
if (verifyErr) {
logger.warn({
message:
verifyErr instanceof InvalidOtpError
? 'Login OTP is invalid'
: 'Error occurred when trying to validate login OTP',
meta: logMeta,
error: verifyErr,
})

if (verifyErr instanceof InvalidOtpError) {
return res.status(verifyErr.status).send(verifyErr.message)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (verifyErr) {
logger.warn({
message:
verifyErr instanceof InvalidOtpError
? 'Login OTP is invalid'
: 'Error occurred when trying to validate login OTP',
meta: logMeta,
error: verifyErr,
})
if (verifyErr instanceof InvalidOtpError) {
return res.status(verifyErr.status).send(verifyErr.message)
}
if (verifyErr) {
logger.warn({
message:
verifyErr instanceof InvalidOtpError
? 'Login OTP is invalid'
: 'Error occurred when trying to validate login OTP',
meta: logMeta,
error: verifyErr,
return res.status(verifyErr.status).send(verifyErr.message)
}

Would this be safer? Although we have tests, I would like to minimise the chance of a future engineer refactoring wrongly or introducing a vulnerability to the login.

Copy link
Contributor Author

@karrui karrui Sep 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change the check to instanceof ApplicationError, and all known errors should be an ApplicationError. However, we will still need the check, since normal errors don't have err.status.

EDIT: Updated the check in 9db99b4


// OTP is valid, proceed to login user.
try {
const agency = await AuthService.getAgencyWithEmail(email)
Copy link
Contributor

@liangyuanruo liangyuanruo Sep 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we see that the middleware pattern with validateDomain results in an additional network call to the database to fetch the agency object again. can we revisit our discussion? because (1) adhering to a pattern at the cost of performance seems dogmatic, and (2) the controller can help to set the context in which an agency lookup failure occurs, so duplicate logging may not be a real issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss after syncup later; but I also agree. I've experimented with passing agency into locals like before in b6a48db; seems like the best way to save some db calls. Take a look.

@liangyuanruo liangyuanruo merged commit 5cba28a into develop Sep 7, 2020
@liangyuanruo liangyuanruo deleted the feat/ts-auth-controller branch September 7, 2020 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants