Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ module.exports = {
'max-lines-per-function': ['error', { max: 75, skipComments: true }],
'no-underscore-dangle': 0,
'react/jsx-props-no-spreading': 0,
'react/prop-types': 0

'react/prop-types': 0,
'prettier/prettier': [
'error',
{
endOfLine: 'auto'
}
]
}
};
8 changes: 1 addition & 7 deletions src/models/AuthCode.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { TEST_USER } from '../../jest.setup';
import AuthCode from './AuthCode';

/**
* TODO: (1.05)
* - Remove the ".skip" from the following function.
* - Go to your terminal and run the following command:
* npm run test AuthCode
* - Delete this comment.
*/

describe('Model: AuthCode', () => {
test('Should auto generate an OTP for value.', async () => {
// Even though we don't specify a value for the OTP code, it should
Expand Down
10 changes: 1 addition & 9 deletions src/models/AuthCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,7 @@ const authCodeSchema: Schema<AuthCodeDocument> = new Schema<AuthCodeDocument>(
{ timestamps: true }
);

/**
* (1.04) TODO:
* - Add a line of code here that will elete every document in the "AuthCode"
* collection after 5 minutes (60 seconds * 5).
* - To be very clear, the only way you're going to figure this out is by
* Googling around for the answer. The solution is one line.
* - Once you find something, add the code to this document and include a link
* to the code you found in a comment.
* */
authCodeSchema.index({ createdAt: 1 }, { expireAfterSeconds: 60 * 5 });

authCodeSchema.index({ createdAt: 1 }, { expireAfterSeconds: 60 * 5 });

Expand Down
9 changes: 1 addition & 8 deletions src/routes/LogoutRoute.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { TEST_AUTH_COOKIE } from '../../jest.setup';
import TestUtils from '../utils/TestUtils';

/**
* TODO: (9.03)
* - Remove the ".skip" from the following function.
* - Go to your terminal and run the following command:
* npm run test Logout
* - Delete this comment.
*/
describe.skip('POST /logout', () => {
describe('POST /logout', () => {
test('If the user is not authenticated, should return a 401.', async () => {
await TestUtils.agent.post('/logout').expect(401);
});
Expand Down
20 changes: 6 additions & 14 deletions src/routes/LogoutRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,9 @@ import { RouteMethod } from '../utils/constants';
export default class LogoutRoute extends BaseRoute<boolean> {
constructor() {
super({
/**
* TODO: (9.01)
* - Should the user be authenticated to hit this route?
* - Replace null with the correct route type from the RouteMethod enum
* in the constants.ts file.
* - Fill in the path string with the appropriate path to this endpoint.
* - Delete this comment.
*/
authenticated: false,
method: null,
path: '/'
authenticated: true,
method: RouteMethod.POST,
path: '/logout'
});
}

Expand All @@ -29,9 +21,9 @@ export default class LogoutRoute extends BaseRoute<boolean> {
* Returns true in all cases.
*/
async content(_: ApplicationRequest, res: Response): Promise<boolean> {
// TODO: (9.02) Use the res.clearCookie('') function to remove the
// accessToken and refreshToken from their cookies. Return true after!
res.clearCookie('accessToken');
res.clearCookie('refreshToken');

return false;
return true;
}
}
9 changes: 1 addition & 8 deletions src/routes/VerifyCodeRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@ import { TEST_USER } from '../../jest.setup';
import AuthCode, { AuthCodeDocument } from '../models/AuthCode';
import TestUtils from '../utils/TestUtils';

/**
* TODO: (8.08)
* - Remove the ".skip" from the following function.
* - Go to your terminal and run the following command:
* npm run test VerifyCode
* - Delete this comment.
*/
describe.skip('POST /verify', () => {
describe('POST /verify', () => {
test('If code is not a number, return a 400.', async () => {
await TestUtils.agent.post('/verify').send({ code: '123456' }).expect(400);
});
Expand Down
50 changes: 22 additions & 28 deletions src/routes/VerifyCodeRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,8 @@ type VerifyCodeRequest = ApplicationRequest<{}, VerifyCodeBody>;
export default class VerifyCodeRoute extends BaseRoute<boolean> {
constructor() {
super({
/**
* TODO: (8.01)
* - Replace null with the correct route type from the RouteMethod enum
* in the constants.ts file.
* - Fill in the path string with the appropriate path to this endpoint.
* - Delete this comment.
*/
method: null,
path: '/'
method: RouteMethod.POST,
path: '/verify'
});
}

Expand All @@ -36,14 +29,13 @@ export default class VerifyCodeRoute extends BaseRoute<boolean> {
* - body.phoneNumber
*/
middleware() {
/**
* TODO: (8.02)
* - Add another validation in the returned array to verify that the code
* from the body of the request is a 6-digit number.
* - We've left in the code that will verify that the phone number is a
* valid US phone number and checks if its in our database.
*/
return [
body('code')
.isInt()
.withMessage('Invalid input. Expected an integer')
.isLength({ max: 6, min: 6 })
.withMessage('The code must be a 6-digit number'),

body('phoneNumber')
.isMobilePhone('en-US')
.withMessage('The phone number you inputted was not valid.')
Expand All @@ -70,27 +62,29 @@ export default class VerifyCodeRoute extends BaseRoute<boolean> {
* @throws {RouteError} - If the code does not match what is in DB.
*/
async content(req: VerifyCodeRequest, res: Response): Promise<boolean> {
// TODO: (8.03) Get the code and phone number from the request body.
const { code, phoneNumber } = req.body;

const authCode: AuthCodeDocument = await AuthCode.findOne({ phoneNumber });

// TODO: (8.04) Find the real code associated with the number from our
// database.
if (authCode.value !== code) {
throw new RouteError({
message: 'Invalid code!',
statusCode: 401
});
}

// TODO: (8.05) Compare the code we received in the request body with the
// one from our database. If they differ, throw a RouteError and them know
// what's wrong.
let user: UserDocument = await User.findOne({ phoneNumber });

// TODO: (8.06) First try to get the user by fetching them from DB. But, if
// they don't already exist, then just create a new user.
const user: UserDocument = null;
if (!user) {
user = await User.create({ phoneNumber });
}

// Renew's the user's tokens and attaches these new tokens on the
// Express response object to send back to the client.
const { accessToken, refreshToken } = await user.renewToken();
MiddlewareUtils.attachTokens(res, { accessToken, refreshToken });

// TODO: (8.07) In the case that the user properly authenticates with the
// code, we no longer want to store the authentication code
// (it's short-lived), so we delete it!
await AuthCode.deleteOne({ phoneNumber });

return true;
}
Expand Down
14 changes: 14 additions & 0 deletions src/utils/AuthUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ import { APP } from './constants';
* all 0's.
*/
const generateOTP = (): number => {

// Generate a number between 0 and 1.
const randomFraction: number = Math.random();

// Multiply that number by 900000
const sixDigit: number = randomFraction * 900000;

// Get rid of decimal
const sixDigitNumber: number = Math.floor(sixDigit);

// return 6-digit number
return sixDigitNumber + 100000;
=======
// Generate a number between 0 and 1
const randomFraction: number = Math.random();

Expand All @@ -19,6 +32,7 @@ const generateOTP = (): number => {

// return the 6 digit number
return sixDigitWholeNumber + 100000;

};

/**
Expand Down