Skip to content
Snippets Groups Projects
Commit c812a743 authored by Darla Maestas's avatar Darla Maestas
Browse files

added required packages to requirements.txt and added password crack estimation to pass module

parent 900fd114
No related branches found
No related tags found
No related merge requests found
No preview for this file type
......@@ -11,3 +11,7 @@ tzdata==2023.4
requests==2.26.0
django-truncate
shodan
openai==1.25.0
requests
netifaces
python-nmap
\ No newline at end of file
......@@ -41,7 +41,8 @@
"react-redux": "^8.1.1",
"react-router-dom": "^6.22.2",
"redux": "4.2.1",
"simplebar-react": "^2.4.3"
"simplebar-react": "^2.4.3",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
......
.psc-wrapper {
width: 90%;
text-align: left;
margin: 10px auto 10px 5px;
}
.pwd-checker-bar {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 10px;
}
.pwd-checker-bar::-webkit-progress-bar {
background-color: rgb(246, 241, 241);
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
}
.pwd-label {
font-size: 12px;
}
.pwd-checker-bar::-webkit-progress-value {
border-radius: 4px;
background-size: 30px 18px, 100% 100%, 100% 100%;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
}
.label {
margin-top: 10px;
margin-bottom: 0px;
}
.strength-weak::-webkit-progress-value {
background-color: #e20b07;
}
.strength-fair::-webkit-progress-value {
background-color: #ebbd04;
}
.strength-good::-webkit-progress-value {
background-color: #0b75ed;
}
.strength-strong::-webkit-progress-value {
background-color: #01a917;
}
.weak span {
color: #e20b07;
}
.strength-fair span {
color: #ebbd04;
}
.strength-good span {
color: #0b75ed;
}
.strength-strong span {
color: #01a917;
}
\ No newline at end of file
import React from 'react'
import PropTypes from 'prop-types'
import zxcvbn from 'zxcvbn'
import './PasswordStrength.css'
const StrengthMeter = ({ password, actions }) => {
const result = zxcvbn(password)
actions(result.score.toString())
const timeToCrack = () => {
if (result.score === 0 && password.length === 0) return 'N/A'
if (result.score === 0) return 'immediately'
const time = result.crack_times_display.offline_slow_hashing_1e4_per_second
return `${time} (for slow hashing)`
}
return (
<>
<div className="psc-wrapper">
<progress
className={`pwd-checker-bar strength-${result.score}`}
value={result.score}
max="4"
/>
<br />
<div className="pwd-label">
{password && (
<>
<p className={`label strength-${result.score}`}>
Password strength:&nbsp;
<strong>{['Weak', 'Fair', 'Good', 'Strong', 'Very Strong'][result.score]}</strong>
</p>
<p className={`label strength-${result.score}`}>
Estimated time to crack: <strong>{timeToCrack()}</strong>
</p>
</>
)}
</div>
</div>
</>
)
}
StrengthMeter.propTypes = {
password: PropTypes.string.isRequired,
actions: PropTypes.func.isRequired,
}
export default StrengthMeter
import React, { useState } from 'react'
import {
CButton,
CCard,
CCardBody,
CCardHeader,
CCol,
CForm,
CFormInput,
CInputGroup,
CInputGroupText,
CRow,
} from '@coreui/react'
import CIcon from '@coreui/icons-react'
import { cilTrash, cilPlus, cilCloudDownload } from '@coreui/icons'
import axios from 'axios'
import PasswordStrengthChecker from 'src/components/PasswordStrength'
const Breaches = () => {
const [password, setPassword] = useState('')
const [file, setFile] = useState(null)
const [accounts, setAccounts] = useState([{ password: '' }])
const [result, setResult] = useState(null)
const handlePasswordChange = (e) => setPassword(e.target.value)
const handleFileChange = (e) => setFile(e.target.files[0])
const handleAccountChange = (index, e) => {
const newAccounts = [...accounts]
newAccounts[index].password = e.target.value
setAccounts(newAccounts)
}
const handleAddAccount = () => setAccounts([...accounts, { password: '' }])
const handleRemoveAccount = (index) => {
const newAccounts = [...accounts]
newAccounts.splice(index, 1)
setAccounts(newAccounts)
}
const handleDownloadTemplate = () => {
const templateData = 'Password\nexample@example.com'
const blob = new Blob([templateData], { type: 'text/csv;charset=utf-8' })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = 'password_template.csv'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
const handleAddToDatabase = async (e) => {
e.preventDefault()
const token = localStorage.getItem('token')
console.log('Token retrieved from local storage:', token)
const formData = new FormData()
if (password) formData.append('password', password)
if (file) formData.append('file', file)
accounts.forEach((account, index) => {
if (account.password) formData.append(`passwords[${index}]`, account.password)
})
// Log the form data before sending
console.log('Form Data:', formData)
const headers = {
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/form-data',
}
try {
await axios.post('http://localhost:8000/api/breaches/upload/passwords/', formData, {
headers,
})
alert('Data submitted successfully')
setPassword('')
setFile(null)
setAccounts([{ password: '' }])
} catch (error) {
console.error('Error uploading data:', error)
alert('Error submitting data')
}
}
const handleSubmitCheck = async (e) => {
e.preventDefault()
if (password) {
try {
const apiUrl = `http://localhost:8000/haveibeenpwned/passwords/${password}/`
const response = await fetch(apiUrl)
const data = await response.json()
console.log('Result from API:', data) // Log the result
if (data.error) {
// No breach detected
setResult([])
setCount(0)
} else {
// Breach detected
let _ct = data.count
setCount(_ct)
setResult(data.response)
console.log(breachCount)
}
} catch (error) {
console.error('Error fetching data:', error)
}
}
}
const [isStrong, initRobustPassword] = useState(null)
const initPwdInput = async (childData) => {
initRobustPassword(childData)
}
const [breachCount, setCount] = useState(null)
return (
<CRow>
<CCol lg={12}>
<CCard className={'mb-4'}>
<CCardHeader>Quick Check</CCardHeader>
<CCardBody>
<CForm>
<CInputGroup className="mb-3">
<CFormInput
placeholder="Enter Your Password"
type="password"
value={password}
onChange={handlePasswordChange}
/>
</CInputGroup>
<PasswordStrengthChecker password={password} actions={initPwdInput} />
<CButton color="success" onClick={handleSubmitCheck}>
Check
</CButton>
</CForm>
{/* Conditional rendering for results */}
{breachCount !== null && (
<h2 style={{ margin: '12px 0' }}>
The Password has been breached {breachCount.toLocaleString()} times
</h2>
)}
{result && result.length > 0 ? (
<div>
<table className="table table-striped table-responsive table-bordered mt-3">
<thead>
<tr>
<th style={{ padding: '10px' }}>Breach Name</th>
<th style={{ padding: '10px' }}>Breach Date</th>
{/* Add more table headers if needed */}
</tr>
</thead>
<tbody>
{result.map((breach) => (
<tr key={breach.Name}>
<td style={{ padding: '10px' }}>{breach.Name}</td>
<td style={{ padding: '10px' }}>{breach.BreachDate}</td>
{/* Add more table cells if needed */}
</tr>
))}
</tbody>
</table>
</div>
) : result && result.length === 0 ? (
<h4 className={'mt-3'}>No breach detected for the provided password</h4>
) : null}
</CCardBody>
</CCard>
<CCard>
<CCardHeader>Monitor Passwords</CCardHeader>
<CCardBody>
{accounts.map((account, index) => (
<CInputGroup key={index} className="mb-3">
<CFormInput
type="password"
placeholder="Add/check Password"
name="password"
value={account.password}
onChange={(e) => handleAccountChange(index, e)}
/>
<CButton
type="button"
color="danger"
variant="outline"
onClick={() => handleRemoveAccount(index)}
>
<CIcon icon={cilTrash} />
</CButton>
</CInputGroup>
))}
<CButton color="primary" className="mb-3" onClick={handleAddAccount}>
<CIcon icon={cilPlus} /> Add Another Account
</CButton>
<CInputGroup className="mb-3">
<CFormInput type="file" id="fileInput" onChange={handleFileChange} accept=".csv" />
</CInputGroup>
<CButton color="secondary" className="mb-3" onClick={handleDownloadTemplate}>
<CIcon icon={cilCloudDownload} /> Download CSV Template
</CButton>
<div className="d-grid gap-2">
<CButton color="info" onClick={handleAddToDatabase}>
Add to Database
</CButton>
</div>
</CCardBody>
</CCard>
</CCol>
</CRow>
)
}
export default Breaches
......@@ -14,13 +14,13 @@ import {
import CIcon from '@coreui/icons-react'
import { cilTrash, cilPlus, cilCloudDownload } from '@coreui/icons'
import axios from 'axios'
import PasswordStrengthChecker from 'src/components/PasswordStrength'
const Breaches = () => {
const [password, setPassword] = useState('')
const [file, setFile] = useState(null)
const [accounts, setAccounts] = useState([{ password: '' }])
const [result, setResult] = useState(null)
const [breachCount, setCount] = useState(0)
const handlePasswordChange = (e) => setPassword(e.target.value)
const handleFileChange = (e) => setFile(e.target.files[0])
......@@ -107,6 +107,11 @@ const Breaches = () => {
}
}
const [isStrong, initRobustPassword] = useState(null)
const initPwdInput = async (childData) => {
initRobustPassword(childData)
}
const [breachCount, setCount] = useState(null)
return (
<CRow>
<CCol lg={12}>
......@@ -122,14 +127,17 @@ const Breaches = () => {
onChange={handlePasswordChange}
/>
</CInputGroup>
<PasswordStrengthChecker password={password} actions={initPwdInput} />
<CButton color="success" onClick={handleSubmitCheck}>
Check
</CButton>
</CForm>
{/* Conditional rendering for results */}
{breachCount !== null && (
<h2 style={{ margin: '12px 0' }}>
The Password has been breached {breachCount.toLocaleString()} times
</h2>
)}
{result && result.length > 0 ? (
<div>
<table className="table table-striped table-responsive table-bordered mt-3">
......@@ -164,11 +172,12 @@ const Breaches = () => {
<CInputGroup key={index} className="mb-3">
<CFormInput
type="password"
placeholder="Add Password"
placeholder="Add/check Password"
name="password"
value={account.password}
onChange={(e) => handleAccountChange(index, e)}
/>
<CButton
type="button"
color="danger"
......
// BreachesPasswords.js
import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
const BreachesPasswords = () => {
const [breachResults, setBreachResults] = useState([])
const navigate = useNavigate()
useEffect(() => {
fetchBreachResultsData()
}, [])
......@@ -12,7 +11,6 @@ const BreachesPasswords = () => {
const fetchBreachResultsData = async () => {
try {
const token = localStorage.getItem('token')
const response = await fetch('http://localhost:8000/api/breaches/passwords/details/', {
headers: {
Authorization: `Bearer ${token}`,
......@@ -21,7 +19,6 @@ const BreachesPasswords = () => {
if (response.status === 401) {
console.error('Unauthorized access to the API')
navigate('/login')
return
}
......@@ -55,8 +52,7 @@ const BreachesPasswords = () => {
)
}
const countUniquePasswords = (results) => {
const uniquePasswords = new Set(results.map((result) => result.password))
return uniquePasswords.size
return results.filter((result) => result.count === 0).length
}
export { countUniquePasswords } // Correct export statement
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment