Skip to content
This repository has been archived by the owner on Apr 7, 2021. It is now read-only.

Revert ":sparkles: Added Input Validation" #43

Merged
merged 1 commit into from
Mar 27, 2020
Merged
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
35 changes: 8 additions & 27 deletions api/src/routes/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { isAuthenticated } from './passport'

const router = Router()

// * Remove data shouldn't be sent to client
const stripData = data => {
const result = JSON.parse(JSON.stringify(data))
/* Remove data shouldn't be sent to client E.g. password */
const stripData = userData => {
const result = JSON.parse(JSON.stringify(userData))
delete result['password']
return result
}
Expand Down Expand Up @@ -45,45 +45,26 @@ router.post('/signup', async (req: Request, res: Response) => {
// * Grab needed elements from request body
const { firstname, lastname, email, password } = req.body

// * Verify that the first and last name is valid
const nameRegex = /[^0-9\.\,\"\?\!\;\:\#\$\%\&\(\)\*\+\-\/\<\>\=\@\[\]\\\^\_\{\}\|\~]/
if (!nameRegex.test(firstname) || !nameRegex.test(lastname)) {
res.status(400).send('Name is invalid')
return
}

// * Verify that the email matches according to W3C standard
if (!/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email)) {
res.status(400).send('Email is invalid')
return
}

// * Verify the the password is adhering to out standard
// * Length is atleast than 8
// * Has one lower case and upper case English letter
// * Has one digit and one special character
if (!/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(password)) {
res.status(400).send('Password is not strong enough')
return
}

// * Check if user already exists
const test = await User.findOne({ email })
if (test) {
res.status(400).send('Email already exists!')
return
}

// * Hash password
const hashedPassword = await bcrypt.hash(password, 2)

// * Setup User
const user = new User({
firstname,
lastname,
email,
// * Hashed Password
password: await bcrypt.hash(password, 2)
password: hashedPassword
})

// * Save user
console.log(user)
await user.save()

// * Login User
Expand Down
10 changes: 5 additions & 5 deletions api/src/tests/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('Authentication Tests', () => {
firstname: 'Clark',
lastname: 'Chen',
email: 'schen237@uic.edu',
password: 'theRealClark1$'
password: 'theRealClark'
})

expect(response.status).toBe(200)
Expand All @@ -53,7 +53,7 @@ describe('Authentication Tests', () => {
firstname: 'Clark',
lastname: 'Chen',
email: 'schen237@uic.edu',
password: 'theRealClark1$'
password: 'theRealClark'
})

expect(response.status).toBe(400)
Expand All @@ -68,7 +68,7 @@ describe('Authentication Tests', () => {
it('Logs user in correctly using email, password', async () => {
const response = await client.post('login', {
email: 'schen237@uic.edu',
password: 'theRealClark1$'
password: 'theRealClark'
})

expect(response.status).toBe(200)
Expand All @@ -92,7 +92,7 @@ describe('Authentication Tests', () => {
it('Cannot login with incorrect email', async () => {
const response = await client.post('login', {
email: 'schen237@acm.cs.uic.edu',
password: 'theRealClark1$'
password: 'theRealClark'
})

expect(response.status).toBe(401)
Expand All @@ -101,7 +101,7 @@ describe('Authentication Tests', () => {
it('Cannot login with incorrect password', async () => {
const response = await client.post('login', {
email: 'schen237@uic.edu',
password: 'theFakeClark1$'
password: 'theFakeClark'
})

expect(response.status).toBe(401)
Expand Down
8 changes: 4 additions & 4 deletions api/src/tests/class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ describe('Class Tests', () => {
const response = await client.post(`auth/signup`, {
firstname: 'Clark',
lastname: 'Chen',
email: 'schen237@uic.edu',
password: 'theRealClark1$'
email: 'schen2370@uic.edu',
password: 'theRealClark'
})

expect(response.status).toBe(200)
})

beforeEach(async () => {
const response = await client.post('auth/login', {
email: 'schen237@uic.edu',
password: 'theRealClark1$'
email: 'schen2370@uic.edu',
password: 'theRealClark'
})
})

Expand Down
101 changes: 23 additions & 78 deletions client/src/components/SignUp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,12 @@ import { signUp } from '../utils/functions/authentication'

const SignUp = () => {
const [show, toggleShow] = useState(false)
const [validated, setValidated] = useState(false)

const [fName, setFName] = useState('')
const [lName, setLName] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')

const handleClick = async () => {
setValidated(true)

const nameRegex = /[a-zA-Z]+[a-zA-Z0-9\s]+[a-zA-Z]/
if (!nameRegex.test(fName) || !nameRegex.test(lName)) {
return
}

// * Verify that the email matches according to W3C standard
if (!/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email)) {
return
}

// * Verify the the password is adhering to out standard
// * Length is atleast than 8
// * Has one lower case and upper case English letter
// * Has one digit and one special character
if (!/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/.test(password)) {
return
}

toggleShow(false)
setFName('')
setLName('')
setEmail('')
setPassword('')

await signUp(fName, lName, email, password)
}

return (
<>
<span onClick={() => toggleShow(!show)}>Register</span>
Expand All @@ -52,99 +21,75 @@ const SignUp = () => {
<Modal.Title>Sign Up</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form validated={validated}>
<Form.Group controlId="validationFirstName">
<Form>
<Form.Group>
<Form.Label>First Name</Form.Label>
<Form.Control
placeholder="Jon"
value={fName}
type="text"
required
pattern="[a-zA-Z]+[a-zA-Z0-9\s]+[a-zA-Z]"
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === ' ') {
e.preventDefault()
setFName(fName + ' ')
}
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value)
setFName(e.target.value)
}}
/>
<Form.Control.Feedback type="invalid">
Your firstname must start with a alphanumeric character and should
not contain any special characters.
</Form.Control.Feedback>
</Form.Group>

<Form.Group controlId="validationLastName">
<Form.Group>
<Form.Label>Last Name</Form.Label>
<Form.Control
placeholder="Doe"
value={lName}
required
pattern="[a-zA-Z]+[a-zA-Z0-9\s]+[a-zA-Z]"
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === ' ') {
e.preventDefault()
setLName(lName + ' ')
}
}}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setLName(e.target.value)
}}
/>
<Form.Control.Feedback type="invalid">
Your lastname must start with a alphanumeric character and should
not contain any special characters.
</Form.Control.Feedback>
</Form.Group>

<Form.Group controlId="validationEmail">
<Form.Group>
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
placeholder="Enter email"
required
value={email}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setEmail(e.target.value)
}}
/>
<Form.Control.Feedback type="invalid">
Please provide a valid email
</Form.Control.Feedback>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>

<Form.Group controlId="validationPassword">
<Form.Group>
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Password"
required
pattern="(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}"
value={password}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setPassword(e.target.value)
}}
/>
<Form.Control.Feedback type="invalid">
Your password must be atleast 8 characters long and have a digit, a
special character, and an uppercase and lowercase English letter
</Form.Control.Feedback>
</Form.Group>

<Form.Group>
<Button variant="primary" onClick={handleClick}>
Sign Up
</Button>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button
variant="primary"
onClick={async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault()

toggleShow(false)
setFName('')
setLName('')
setEmail('')
setPassword('')

await signUp(fName, lName, email, password)
}}
>
Sign Up
</Button>
</Modal.Footer>
</Modal>
</>
)
Expand Down
2 changes: 1 addition & 1 deletion client/src/utils/functions/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const signUp = async (fn: string, ln: string, em: string, pw: string) =>
else if (response.status === 400)
store.dispatch(
userSignUp(null, {
msg: response.data,
msg: 'Email already exist! Please login',
options: {
type: 'info'
}
Expand Down