Skip to content

Commit

Permalink
feat: validate loginId to be a valid id generated from whisper (#729)
Browse files Browse the repository at this point in the history
Co-authored-by: _sameer <[email protected]>
Co-authored-by: Dunsin <[email protected]>
  • Loading branch information
3 people authored Nov 29, 2024
1 parent f33a6a3 commit b5dbcfc
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
9 changes: 5 additions & 4 deletions client/src/context/AuthContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createContext, useContext, useMemo, useReducer } from 'react';
import PropTypes from 'prop-types';

import authReducer, { initialState } from './reducers/authReducer';
import { validateUserID } from 'src/lib/utils';

const AuthContext = createContext({
...initialState,
Expand All @@ -23,10 +24,10 @@ const initializeAuthState = (defaultState) => {
return defaultState;
}

/**
* TODO: Validate loginId to be a valid uuid using the uuid
* library from npm
*/
if (!validateUserID(persistedState.loginId, persistedState.loginType)) {
// User is trying to hack app by manipulating localStorage
throw new Error('Invalid loginId! :(');
}
if (!persistedState.loginId && persistedState.isLoggedIn === true) {
// User is trying to hack app by manipulating localStorage
throw new Error('Gotcha! :D');
Expand Down
13 changes: 13 additions & 0 deletions client/src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,16 @@ export const decrypt = (encryptedText) => {

return originalText;
};

export const validateUserID = (userID, userType) => {
const userIDPattern = /^[a-z0-9]{12}$/;
const userHexIdPattern = /^[a-f0-9]{24}$/;

if (userType === 'email') {
// user id validation for hex pattern of email login
return userHexIdPattern.test(userID);
} else {
// user id validation for anonymous login
return userIDPattern.test(userID);
}
};
4 changes: 2 additions & 2 deletions server/controllers/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const storage = multer.memoryStorage();
const imageUpload = multer({ storage: storage });

const User = require('../models/UserModel');
const { emailValidator, generateObjectId } = require('../utils/helper');
const { emailValidator, generateObjectId, validateUserID } = require('../utils/helper');

const { isUserBlocked, blockUser } = require('../utils/lib.js');
const {
Expand Down Expand Up @@ -169,7 +169,7 @@ const blockUserHandler = async (req, res) => {
}
}

UserRouter.route('/login').post(emailValidator, loginUser);
UserRouter.route('/login').post(emailValidator, validateUserID, loginUser);
UserRouter.route('/profile').post(
imageUpload.single('profileImage'),
emailValidator,
Expand Down
17 changes: 17 additions & 0 deletions server/utils/helper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const crypto = require('crypto');
const { NOT_ACCEPTABLE } = require('../httpStatusCodes');

// Defining separate email validation middleware
const validator = require('validator').default;
Expand All @@ -18,7 +19,23 @@ function generateObjectId() {
return crypto.randomBytes(12).toString('hex');
}

const validateUserID = (req, res, next) => {
const { id } = req.body;
const userIDPattern = /^[a-z0-9]{12}$/;

// If id is required and not present or invalid, reject the request
if (!id || typeof id !== 'string' || !userIDPattern.test(id)) {
return res.status(406).json({
message: 'Invalid login Id.'
});
}

// If id is valid, proceed to the next middleware
next();
}

module.exports = {
emailValidator,
generateObjectId,
validateUserID,
};

0 comments on commit b5dbcfc

Please sign in to comment.