From 0793e8d200fa09b796b55d1c3083c9bb039689e8 Mon Sep 17 00:00:00 2001
From: Darla Maestas <dnm66@drexel.edu>
Date: Fri, 3 May 2024 16:26:13 -0400
Subject: [PATCH] darla final push

---
 backend/db.sqlite3                            | Bin 561152 -> 561152 bytes
 backend/requirements.txt                      |   3 +-
 backend/watchstone_backend/urls.py            |   3 +-
 frontend/src/_nav.js                          |  60 +------
 .../components/header/AppHeaderDropdown.js    |  47 -----
 frontend/src/scss/_custom.scss                |  41 +++++
 frontend/src/scss/_variables.scss             |  13 +-
 frontend/src/scss/style.scss                  |   5 +
 .../NetworkScanner/RecommendationComponent.js |  46 ++---
 frontend/src/views/dashboard/CVEUpdates.js    |  35 ++--
 frontend/src/views/emails/BreachesEmails.js   |  72 +++++---
 frontend/src/views/pages/login/Login.js       |   4 +-
 frontend/src/views/pages/register/Register.js |   2 +-
 .../src/views/passwords/BreachesPasswords.js  |  25 ++-
 frontend/src/views/shodan/shodanscan.js       | 169 +++++++++---------
 frontend/src/views/widgets/WidgetsDropdown.js |  69 +++++--
 16 files changed, 335 insertions(+), 259 deletions(-)

diff --git a/backend/db.sqlite3 b/backend/db.sqlite3
index 2640fc9a9b2d3bcc229cdaa25a55f92addba7a93..35040fd9bd153f9ce7316d0ce69219812facd16b 100644
GIT binary patch
delta 925
zcmZozpwzHHX@WGP;Y1l{Rzn88vd)bu?0Sp>lXLXy8D%EF(KBTWk>_J}W}IfnEX}4W
z&CP7hIGxX)S-d%3e|x+><I)QPY<ve9_|Njs;LqSU<om&QaI;{;T0S;YRTgVUhUphB
zFp5hV85o)98kp)D7%Lc>TNxNz85`&s7?@j{nr#2U$HWuJ#m1k^!2g23o<DgzPXbdY
zKZ`WT8jxN_)$R59OsxvcGTi&8vrk|$W#N9#y??WzLOpkYnhXnrtYb(~scDIEiXyTl
zmR1IaR;Ffp#%31ghDK`AAax~p)EOF?SQr^>=byv$)tFg^Z_9M{3rw;yd|UY4_%HJB
z;$Of&kw1%HnEwku2Y(gcLH_mpt(yfKO8BIBm}MDZ_RD}cFiWJjpS#CoCdkXm=+D4?
zmZO%nh`FC}yPyD*9V1tZZ3sJqwW4N+G&poLj0_CTbqx%44Ge=a%TkM+GfOIcQ&Tb%
zJ@XX267xzEiz*dBN_3`Y|7X$+G&e9YGBdC+F)%gK&nPJ=D7Mnq&rM9uPE9RHEz(QQ
z&(%-L$xqiW$S*F@H#WA^EiOpR%}p&zPb^8*Ey+mLO-szl(alfOP0Z6x%`M0*N}X=F
ziAm8dQ6V?6xHz*cRiUIPzbsWDKTRPeu_RF;ttdZN0qiaXki!(fE>kE^ELKR%FU?C)
zNUbQyFHTKS$j{5k%uAi_*u^9q43R0xS4hs!D@n}EQ%KCo%`YxdFw`?qNXpE~$;{7F
zC`wJvFG?v^$jnR5DNV`DOIJwEP0Y+uNX$!7@C;B$Oi3w9EiO(i)=|hy%uOwx&MU(t
z8JC!o19Dh-MrLvb*bSv1s}qYA3KEM-Kr)GW3aNSdMY;K<#R?#gE94iX7A2Ns=I7}t
z_~#|3Dx{?9rj!=sWF{w;q^9U7lw_n9r7Dzz2xH6X2LG58mC7?qGBWc(GH}0v0z$7j
zAs7^EvTeEGSlccp&2*TNlOu?o!B|nU+jF|$MMmN6{a=|%xtIm`*{8BI%d+r`^0RLi
yY`D)S!y~}LAj<(uDLnij9xSP}EAunAEAz9oEAz9qEAz9pEAz8&SLWxq+W-KJg%ZsG

delta 260
zcmZozpwzHHX@WGP)<hX+RxJj-aIcLi?0SrRlXLXy8Kow_(KBTWlILS~W}IfnEX}4O
z&CP7hIGxX)S-d%3e|x+><I)R!tb9Kh_|Njs;LqSU<omH%u;Cfs_8)vqJb@gn{Phg{
zFZk=X^Cd8a@=tb9klS9L&(x~GEXBh=oqYn6>1IQP%iP=f=P-RWW|rbRH=X?gldJ^4
z8~;WAUHl99C-P_U3-f>B=ism6U(esVS+HRe-}ZC&n9KyZm|2S$xX*IbvKDPNR7hdv
zYU2oEXE0Wj?Dm{4c#%<fd;eFaQZ8mbe&wm`%(9yW8~*dPEAunAEAz9oEAz9qEAz9p
OEAz8&SLWxq+W-J7xJbbO

diff --git a/backend/requirements.txt b/backend/requirements.txt
index e5169064d..278b0d548 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -14,4 +14,5 @@ shodan
 openai==1.25.0
 requests
 netifaces
-python-nmap
\ No newline at end of file
+python-nmap
+feedparser
\ No newline at end of file
diff --git a/backend/watchstone_backend/urls.py b/backend/watchstone_backend/urls.py
index e8a725864..eee0c2e8b 100644
--- a/backend/watchstone_backend/urls.py
+++ b/backend/watchstone_backend/urls.py
@@ -13,6 +13,7 @@ urlpatterns = [
     path('haveibeenpwned/passwords/<str:identifier>/', breached_password_info, name='breached_password_info'),
     path('', include('shodan_scan.urls')),
     path('api/networkscanner/', include('network_scanner.urls')),
-    path('', include('rssfeeds.urls')),  # Include the rssfeeds app URLs
+    path('', include('rssfeeds.urls')),  
+    # Include the rssfeeds app URLs
     # Add other URL patterns as needed
 ]
diff --git a/frontend/src/_nav.js b/frontend/src/_nav.js
index fa233e420..5360df4df 100644
--- a/frontend/src/_nav.js
+++ b/frontend/src/_nav.js
@@ -9,11 +9,14 @@ import {
   cilDrop,
   cilNotes,
   cilPencil,
+  cilSearch,
   cilPuzzle,
   cilSpeedometer,
   cilStar,
   cilShieldAlt,
   cilEnvelopeLetter,
+  cilLibraryAdd,
+  cilEnvelopeOpen,
 } from '@coreui/icons'
 import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
 
@@ -25,7 +28,7 @@ const _nav = [
     icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />,
     badge: {
       color: 'info',
-      text: 'NEW',
+      text: '',
     },
   },
   {
@@ -36,13 +39,13 @@ const _nav = [
     component: CNavItem,
     name: 'Add Email',
     to: '/email-breaches/add',
-    icon: <CIcon icon={cilShieldAlt} customClassName="nav-icon" />,
+    icon: <CIcon icon={cilLibraryAdd} customClassName="nav-icon" />,
   },
   {
     component: CNavItem,
     name: 'Tracked Emails',
     to: '/email-breaches/view',
-    icon: <CIcon icon={cilShieldAlt} customClassName="nav-icon" />,
+    icon: <CIcon icon={cilSearch} customClassName="nav-icon" />,
   },
   {
     component: CNavTitle,
@@ -52,13 +55,13 @@ const _nav = [
     component: CNavItem,
     name: 'Add Password',
     to: '/password-breaches/add',
-    icon: <CIcon icon={cilShieldAlt} customClassName="nav-icon" />,
+    icon: <CIcon icon={cilLibraryAdd} customClassName="nav-icon" />,
   },
   {
     component: CNavItem,
     name: 'Tracked Passwords',
     to: '/password-breaches/view',
-    icon: <CIcon icon={cilShieldAlt} customClassName="nav-icon" />,
+    icon: <CIcon icon={cilSearch} customClassName="nav-icon" />,
   },
   {
     component: CNavTitle,
@@ -80,53 +83,6 @@ const _nav = [
     to: '/recommendations',
     icon: <CIcon icon={cilEnvelopeLetter} customClassName="nav-icon" />,
   },
-  {
-    component: CNavItem,
-    name: 'Widgets',
-    to: '/widgets',
-    icon: <CIcon icon={cilCalculator} customClassName="nav-icon" />,
-    badge: {
-      color: 'info',
-      text: 'NEW',
-    },
-  },
-  {
-    component: CNavTitle,
-    name: 'Extras',
-  },
-  {
-    component: CNavGroup,
-    name: 'Pages',
-    icon: <CIcon icon={cilStar} customClassName="nav-icon" />,
-    items: [
-      {
-        component: CNavItem,
-        name: 'Login',
-        to: '/login',
-      },
-      {
-        component: CNavItem,
-        name: 'Register',
-        to: '/register',
-      },
-      {
-        component: CNavItem,
-        name: 'Error 404',
-        to: '/404',
-      },
-      {
-        component: CNavItem,
-        name: 'Error 500',
-        to: '/500',
-      },
-    ],
-  },
-  {
-    component: CNavItem,
-    name: 'Docs',
-    href: 'https://coreui.io/react/docs/templates/installation/',
-    icon: <CIcon icon={cilDescription} customClassName="nav-icon" />,
-  },
 ]
 
 export default _nav
diff --git a/frontend/src/components/header/AppHeaderDropdown.js b/frontend/src/components/header/AppHeaderDropdown.js
index 12dc4f0e9..3c4d65c06 100644
--- a/frontend/src/components/header/AppHeaderDropdown.js
+++ b/frontend/src/components/header/AppHeaderDropdown.js
@@ -30,58 +30,11 @@ const AppHeaderDropdown = () => {
         <CAvatar src={avatar8} size="md" />
       </CDropdownToggle>
       <CDropdownMenu className="pt-0" placement="bottom-end">
-        <CDropdownHeader className="bg-light fw-semibold py-2">Account</CDropdownHeader>
-        <CDropdownItem href="#">
-          <CIcon icon={cilBell} className="me-2" />
-          Updates
-          <CBadge color="info" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilEnvelopeOpen} className="me-2" />
-          Messages
-          <CBadge color="success" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilTask} className="me-2" />
-          Tasks
-          <CBadge color="danger" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilCommentSquare} className="me-2" />
-          Comments
-          <CBadge color="warning" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
         <CDropdownHeader className="bg-light fw-semibold py-2">Settings</CDropdownHeader>
         <CDropdownItem href="#/profile">
           <CIcon icon={cilUser} className="me-2" />
           Profile
         </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilSettings} className="me-2" />
-          Settings
-        </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilCreditCard} className="me-2" />
-          Payments
-          <CBadge color="secondary" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
-        <CDropdownItem href="#">
-          <CIcon icon={cilFile} className="me-2" />
-          Projects
-          <CBadge color="primary" className="ms-2">
-            42
-          </CBadge>
-        </CDropdownItem>
         <CDropdownDivider />
         <CDropdownItem href="#">
           <CIcon icon={cilLockLocked} className="me-2" />
diff --git a/frontend/src/scss/_custom.scss b/frontend/src/scss/_custom.scss
index 8b1378917..759402d69 100644
--- a/frontend/src/scss/_custom.scss
+++ b/frontend/src/scss/_custom.scss
@@ -1 +1,42 @@
+.w-15{
+    width:15%!important;
+}
 
+.table-responsive-1 {
+    overflow: scroll!important;
+}
+
+.scroll-hint {
+    display: none;
+  }
+
+::-webkit-scrollbar {
+    height: 4px;              /* height of horizontal scrollbar ← You're missing this */
+    width: 4px;               /* width of vertical scrollbar */
+    border: 1px solid #d5d5d5;
+  }
+
+  @media (max-width: 787px) {
+    .scroll-hint {
+      display: block;
+      text-align: center;
+      padding: 10px;
+      background-color: #f8f9fa;
+    }
+
+
+  }
+  
+  .tertiary-background {
+    background-color: $tertiary!important;
+  }
+
+  .input-group-text {
+    color:$tertiary!important;
+  }
+
+  
+  .form-control:focus {
+border-color: $tertiary!important;
+box-shadow: 0 0 0 0.25rem rgb(142 82 245 / 22%);
+  }
\ No newline at end of file
diff --git a/frontend/src/scss/_variables.scss b/frontend/src/scss/_variables.scss
index 961322c7b..0fc31e5ae 100644
--- a/frontend/src/scss/_variables.scss
+++ b/frontend/src/scss/_variables.scss
@@ -76,15 +76,18 @@
 
 // fusv-disable
 // $primary-dark:  #1f1498 !default;
-// $primary-base:  #321fdb !default;
+$primary-base:  #122C5A !default;
 // $primary-50:    #988fed !default;
 // $primary-25:    #ccc7f6 !default;
 
 // $secondary-dark:  #212233 !default;
-// $secondary-base:  #9da5b1 !default;
+$secondary-base:  #00C0A1 !default;
 // $secondary-50:    #9da5b1 !default;
 // $secondary-25:    #ced2d8 !default;
 
+$tertiary: #8E52F5 !default;
+
+
 // $success-dark:  #1b9e3e !default;
 // $success-base:  #2eb85c !default;
 // $success-50:    #96dbad !default;
@@ -119,6 +122,7 @@
 // scss-docs-start theme-color-variables
 // $primary:       $primary-base !default;
 // $secondary:     $secondary-base !default;
+
 // $success:       $success-base !default;
 // $info:          $info-base !default;
 // $warning:       $warning-base !default;
@@ -131,6 +135,7 @@
 // $theme-colors: (
 //   "primary":    $primary,
 //   "secondary":  $secondary,
+
 //   "success":    $success,
 //   "info":       $info,
 //   "warning":    $warning,
@@ -1789,3 +1794,7 @@ $sidebar-bg:                               #122C5A;
 // $kbd-bg:                            $gray-900 !default;
 
 // $pre-color:                         unset !default;
+
+
+
+
diff --git a/frontend/src/scss/style.scss b/frontend/src/scss/style.scss
index 02f199c40..7736af273 100644
--- a/frontend/src/scss/style.scss
+++ b/frontend/src/scss/style.scss
@@ -15,3 +15,8 @@ $enable-rtl: true;
 
 // If you want to add custom CSS you can put it here.
 @import "custom";
+
+// style.scss
+
+
+  
diff --git a/frontend/src/views/NetworkScanner/RecommendationComponent.js b/frontend/src/views/NetworkScanner/RecommendationComponent.js
index 9ccdf2e6a..a2dd970b9 100644
--- a/frontend/src/views/NetworkScanner/RecommendationComponent.js
+++ b/frontend/src/views/NetworkScanner/RecommendationComponent.js
@@ -1,8 +1,10 @@
 import React, { useState, useEffect } from 'react'
 import axios from 'axios'
+import { useNavigate } from 'react-router-dom'
 
 const RecommendationsPage = () => {
   const [recommendations, setRecommendations] = useState([])
+  const navigate = useNavigate()
 
   useEffect(() => {
     const fetchRecommendations = async () => {
@@ -25,36 +27,40 @@ const RecommendationsPage = () => {
         setRecommendations(response.data)
       } catch (error) {
         console.error('Error fetching recommendations:', error)
-        if (error.response) {
-          console.error('Error status:', error.response.status)
+        if (error.response && error.response.status === 401) {
+          console.error('Unauthorized access to the API')
+          navigate('/login') // Redirect to login page
         }
       }
     }
 
     fetchRecommendations()
-  }, [])
+  }, [navigate])
 
   return (
     <div>
       <h2>Network Security Recommendations</h2>
-      <table className="table table-striped table-responsive mt-3">
-        <thead>
-          <tr>
-            <th>IP Address</th>
-            <th>Scan Date</th>
-            <th>Recommendation</th>
-          </tr>
-        </thead>
-        <tbody>
-          {recommendations.map((rec) => (
-            <tr key={rec.id}>
-              <td>{rec.ip_address}</td>
-              <td>{rec.scan_date}</td>
-              <td style={{ whiteSpace: 'pre-wrap' }}>{rec.recommendation_text}</td>
+      <div className="scroll-hint">Scroll horizontally to view the columns</div>
+      <div className="table-responsive overflow-x-auto">
+        <table className="table table-striped mt-3">
+          <thead>
+            <tr>
+              <th>IP Address</th>
+              <th className="w-15">Scan Date</th>
+              <th>Recommendation</th>
             </tr>
-          ))}
-        </tbody>
-      </table>
+          </thead>
+          <tbody>
+            {recommendations.map((rec) => (
+              <tr key={rec.id}>
+                <td>{rec.ip_address}</td>
+                <td>{rec.scan_date}</td>
+                <td style={{ whiteSpace: 'pre-wrap' }}>{rec.recommendation_text}</td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
+      </div>
     </div>
   )
 }
diff --git a/frontend/src/views/dashboard/CVEUpdates.js b/frontend/src/views/dashboard/CVEUpdates.js
index 6df254345..186659af1 100644
--- a/frontend/src/views/dashboard/CVEUpdates.js
+++ b/frontend/src/views/dashboard/CVEUpdates.js
@@ -21,23 +21,30 @@ const CVEUpdates = () => {
   return (
     <div>
       {cveItems.length > 0 ? (
-        <div>
-          {cveItems.map((cveItem, index) => (
-            <CCard key={index} className="mb-3">
-              <CCardBody>
-                <CCardTitle>ID: {cveItem.cve.id}</CCardTitle>
-                <p>Date: {cveItem.cve.published}</p>
-                <p>Summary: {cveItem.cve.descriptions[0].value}</p>
-                <p>
-                  Details:{' '}
+        cveItems.map((cveItem, index) => (
+          <CCard key={index} className="mb-3">
+            <CCardBody>
+              <CCardTitle>ID: {cveItem.cve?.id}</CCardTitle>
+              <p>Date: {cveItem.cve?.published}</p>
+              <p>
+                Summary:{' '}
+                {cveItem.cve?.descriptions && cveItem.cve.descriptions.length > 0
+                  ? cveItem.cve.descriptions[0].value
+                  : 'No summary available'}
+              </p>
+              <p>
+                Details:{' '}
+                {cveItem.cve?.references && cveItem.cve.references.length > 0 ? (
                   <a href={cveItem.cve.references[0].url} target="_blank" rel="noopener noreferrer">
                     View More
                   </a>
-                </p>
-              </CCardBody>
-            </CCard>
-          ))}
-        </div>
+                ) : (
+                  'No details available'
+                )}
+              </p>
+            </CCardBody>
+          </CCard>
+        ))
       ) : (
         <p>No CVE data available.</p>
       )}
diff --git a/frontend/src/views/emails/BreachesEmails.js b/frontend/src/views/emails/BreachesEmails.js
index 11eff4d26..99b445d9d 100644
--- a/frontend/src/views/emails/BreachesEmails.js
+++ b/frontend/src/views/emails/BreachesEmails.js
@@ -1,10 +1,12 @@
-// BreachesPasswords.js
 import React, { useState, useEffect } from 'react'
 import { useNavigate } from 'react-router-dom'
 
 const BreachesEmails = () => {
   const [breachResults, setBreachResults] = useState([])
+  const [sortOrder, setSortOrder] = useState('asc') // Default sorting order
+  const [sortedColumn, setSortedColumn] = useState('breach_date') // Default sorted column
   const navigate = useNavigate()
+
   useEffect(() => {
     fetchBreachResultsData()
   }, [])
@@ -31,34 +33,60 @@ const BreachesEmails = () => {
     }
   }
 
+  const handleSort = (column) => {
+    if (sortedColumn === column) {
+      // Toggle sorting order if the same column is clicked again
+      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc')
+    } else {
+      // Default to ascending order for a new column
+      setSortOrder('asc')
+      setSortedColumn(column)
+    }
+  }
+
+  const sortedResults = [...breachResults].sort((a, b) => {
+    // Custom sorting logic based on column and sortOrder
+    if (sortOrder === 'asc') {
+      return a[sortedColumn].localeCompare(b[sortedColumn])
+    } else {
+      return b[sortedColumn].localeCompare(a[sortedColumn])
+    }
+  })
+
   return (
     <div>
       <h2>List of Breached Emails</h2>
-      <table className="table table-striped table-responsive mt-3">
-        <thead>
-          <tr>
-            <th>Email</th>
-            <th>Breach Name</th>
-            <th>Breach Date</th>
-            <th>Description</th>
-          </tr>
-        </thead>
-        <tbody>
-          {breachResults.map((result) => (
-            <tr key={result.id}>
-              <td>{result.email}</td>
-              <td>{result.name}</td>
-              <td>{result.breach_date}</td>
-              <td style={{ padding: '10px' }}>
-                <div dangerouslySetInnerHTML={{ __html: result.description }} />
-              </td>
+      <div className="scroll-hint">Scroll horizontally to view the columns</div>
+      <div className="table-responsive overflow-x-auto">
+        <table className="table table-striped mt-3">
+          <thead>
+            <tr>
+              <th onClick={() => handleSort('email')}>Email</th>
+              <th onClick={() => handleSort('name')}>Breach Name</th>
+              <th className="w-15" onClick={() => handleSort('breach_date')}>
+                Breach Date {sortedColumn === 'breach_date' && (sortOrder === 'asc' ? '↑' : '↓')}
+              </th>
+              <th>Description</th>
             </tr>
-          ))}
-        </tbody>
-      </table>
+          </thead>
+          <tbody>
+            {sortedResults.map((result) => (
+              <tr key={result.id}>
+                <td>{result.email}</td>
+                <td>{result.name}</td>
+                <td>{result.breach_date}</td>
+                <td style={{ padding: '10px' }}>
+                  <div dangerouslySetInnerHTML={{ __html: result.description }} />
+                </td>
+              </tr>
+            ))}
+          </tbody>
+        </table>
+      </div>
     </div>
   )
 }
+
 const countUniqueEmails = (results) => {
   const uniqueEmails = new Set(results.map((result) => result.email))
   return uniqueEmails.size
diff --git a/frontend/src/views/pages/login/Login.js b/frontend/src/views/pages/login/Login.js
index 8d08d6122..1d6be7c0d 100644
--- a/frontend/src/views/pages/login/Login.js
+++ b/frontend/src/views/pages/login/Login.js
@@ -97,13 +97,13 @@ const Login = () => {
                   </CForm>
                 </CCardBody>
               </CCard>
-              <CCard className="text-white bg-primary py-5" style={{ width: '44%' }}>
+              <CCard className="text-white bg-primary py-5">
                 <CCardBody className="text-center">
                   <div>
                     <h2>New here?</h2>
                     <p>Create an account to begin your journey of guarding your data.</p>
                     <Link to="/register">
-                      <CButton color="primary" className="mt-3" active tabIndex={-1}>
+                      <CButton color="secondary" className="mt-3 text-white" active tabIndex={-1}>
                         Register Now!
                       </CButton>
                     </Link>
diff --git a/frontend/src/views/pages/register/Register.js b/frontend/src/views/pages/register/Register.js
index 8a6fe6105..8263011e9 100644
--- a/frontend/src/views/pages/register/Register.js
+++ b/frontend/src/views/pages/register/Register.js
@@ -122,7 +122,7 @@ const Register = () => {
                     />
                   </CInputGroup>
                   <div className="d-grid">
-                    <CButton color="success" type="submit">
+                    <CButton color="primary" type="submit">
                       Create Account
                     </CButton>
                   </div>
diff --git a/frontend/src/views/passwords/BreachesPasswords.js b/frontend/src/views/passwords/BreachesPasswords.js
index 9b6882575..bded33aec 100644
--- a/frontend/src/views/passwords/BreachesPasswords.js
+++ b/frontend/src/views/passwords/BreachesPasswords.js
@@ -1,13 +1,17 @@
-// BreachesPasswords.js
 import React, { useState, useEffect } from 'react'
+import PropTypes from 'prop-types'
+import { useNavigate } from 'react-router-dom'
 
-const BreachesPasswords = () => {
+const BreachesPasswords = ({ onCountChange }) => {
   const [breachResults, setBreachResults] = useState([])
+  const [breachedPasswordsCount, setBreachedPasswordsCount] = useState(0)
 
   useEffect(() => {
     fetchBreachResultsData()
   }, [])
 
+  const navigate = useNavigate()
+
   const fetchBreachResultsData = async () => {
     try {
       const token = localStorage.getItem('token')
@@ -19,11 +23,19 @@ const BreachesPasswords = () => {
 
       if (response.status === 401) {
         console.error('Unauthorized access to the API')
+        navigate('/login') // Redirect to login page
         return
       }
 
       const data = await response.json()
       setBreachResults(data)
+
+      // Calculate count of breached passwords with more than 0 breaches
+      const breachedCount = data.filter((result) => result.count > 0).length
+      setBreachedPasswordsCount(breachedCount)
+
+      // Pass the count to the parent component
+      onCountChange(breachedCount)
     } catch (error) {
       console.error('Error fetching breach results:', error)
     }
@@ -51,10 +63,15 @@ const BreachesPasswords = () => {
     </div>
   )
 }
+
+BreachesPasswords.propTypes = {
+  onCountChange: PropTypes.func.isRequired,
+}
+
 const countUniquePasswords = (results) => {
-  return results.filter((result) => result.count === 0).length
+  return results.filter((result) => result.count > 0).length
 }
 
-export { countUniquePasswords } // Correct export statement
+export { countUniquePasswords }
 
 export default BreachesPasswords
diff --git a/frontend/src/views/shodan/shodanscan.js b/frontend/src/views/shodan/shodanscan.js
index 8b35c2774..cb15ea72f 100644
--- a/frontend/src/views/shodan/shodanscan.js
+++ b/frontend/src/views/shodan/shodanscan.js
@@ -43,88 +43,95 @@ const ShodanScanner = () => {
   }
 
   return (
-    <CRow>
-      <CCol lg={12}>
-        <CCard className={'mb-4'}>
-          <CCardHeader>Shodan Scanner</CCardHeader>
-          <CCardBody>
-            <CForm>
-              {ipAddresses.map((ip, index) => (
-                <CInputGroup key={index} className="mb-3">
-                  <CFormInput
-                    type="text"
-                    placeholder="Enter IP Address"
-                    value={ip.address}
-                    onChange={(e) => {
-                      const newIpAddresses = [...ipAddresses]
-                      newIpAddresses[index].address = e.target.value
-                      setIpAddresses(newIpAddresses)
-                    }}
-                  />
-                  <CButton
-                    type="button"
-                    color="danger"
-                    variant="outline"
-                    onClick={() => handleRemoveIpAddress(index)}
-                  >
-                    <CIcon icon={cilTrash} />
-                  </CButton>
-                </CInputGroup>
-              ))}
-              <CButton color="primary" className="mb-3" onClick={handleAddIpAddress}>
-                <CIcon icon={cilPlus} /> Add Another IP Address
-              </CButton>
-
-              <div className="d-grid gap-2">
-                <CButton color="info" onClick={handleScan}>
-                  Scan
-                </CButton>
-              </div>
-            </CForm>
-            {scanResults.length > 0 && (
-              <div className="scan-results">
-                <h3>Scan Results</h3>
-                {scanResults.map((result, index) => (
-                  <div key={index} className="result">
-                    <h4>IP Address: {result.ip_address}</h4>
-                    <div>
-                      Geolocation: {result.geolocation.country}, {result.geolocation.city}
-                    </div>
-                    <div>
-                      Latitude: {result.geolocation.latitude}, Longitude: {''}
-                      {result.geolocation.longitude}
-                    </div>
-                    <div>
-                      <h5>Open Ports</h5>
-                      {result.open_ports.map((port, portIndex) => (
-                        <p key={portIndex}>
-                          {port.port}/{port.protocol} - {port.banner}
-                        </p>
-                      ))}
-                    </div>
-                    <div>
-                      <h5>Vulnerabilities</h5>
-                      {result.vulnerabilities.map((vuln, vulnIndex) => (
-                        <p key={vulnIndex}>
-                          <a
-                            href={`https://nvd.nist.gov/vuln/detail/${vuln.cve}`}
-                            target="_blank"
-                            rel="noopener noreferrer"
-                          >
-                            {vuln.cve}
-                          </a>
-                          {vuln.cve}: {vuln.summary} (CVSS: {vuln.cvss || 'N/A'})
-                        </p>
-                      ))}
-                    </div>
-                  </div>
+    <div>
+      <CRow>
+        <CCol lg={12}>
+          <CCard className="mb-4">
+            <CCardHeader>Shodan Scanner</CCardHeader>
+            <CCardBody>
+              <CForm>
+                {ipAddresses.map((ip, index) => (
+                  <CInputGroup key={index} className="mb-3">
+                    <CFormInput
+                      type="text"
+                      placeholder="Enter IP Address"
+                      value={ip.address}
+                      onChange={(e) => {
+                        const newIpAddresses = [...ipAddresses]
+                        newIpAddresses[index].address = e.target.value
+                        setIpAddresses(newIpAddresses)
+                      }}
+                    />
+                    <CButton
+                      type="button"
+                      color="danger"
+                      variant="outline"
+                      onClick={() => handleRemoveIpAddress(index)}
+                    >
+                      <CIcon icon={cilTrash} />
+                    </CButton>
+                  </CInputGroup>
                 ))}
-              </div>
-            )}
-          </CCardBody>
-        </CCard>
-      </CCol>
-    </CRow>
+                <CButton color="primary" className="mb-3" onClick={handleAddIpAddress}>
+                  <CIcon icon={cilPlus} /> Add Another IP Address
+                </CButton>
+
+                <div className="d-grid gap-2">
+                  <CButton color="info" onClick={handleScan}>
+                    Scan
+                  </CButton>
+                </div>
+              </CForm>
+              {scanResults.length > 0 && (
+                <CCard className="mt-4" style={{ backgroundColor: '#f8f9fa' }}>
+                  <CCardHeader>Scan Results</CCardHeader>
+                  <CCardBody className="p-0">
+                    {scanResults.map((result, index) => (
+                      <div key={index} className="result">
+                        <div className="bg-light p-3">
+                          <h4>IP Address: {result.ip_address}</h4>
+                          <div>
+                            Geolocation: {result.geolocation.country}, {result.geolocation.city}
+                          </div>
+                          <div>
+                            Latitude: {result.geolocation.latitude}, Longitude:
+                            {result.geolocation.longitude}
+                          </div>
+                        </div>
+                        <div className="bg-white p-3">
+                          <h5>Open Ports</h5>
+                          {result.open_ports.map((port, portIndex) => (
+                            <p key={portIndex}>
+                              {port.port}/{port.protocol} - {port.banner}
+                            </p>
+                          ))}
+                        </div>
+                        <div className="bg-light p-3">
+                          <h5>Vulnerabilities</h5>
+                          {result.vulnerabilities.map((vuln, vulnIndex) => (
+                            <p key={vulnIndex}>
+                              <a
+                                href={`https://nvd.nist.gov/vuln/detail/${vuln.cve}`}
+                                target="_blank"
+                                rel="noopener noreferrer"
+                              >
+                                {vuln.cve}
+                              </a>
+                              <br></br>
+                              {vuln.cve}: {vuln.summary} (CVSS: {vuln.cvss || 'N/A'})
+                            </p>
+                          ))}
+                        </div>
+                      </div>
+                    ))}
+                  </CCardBody>
+                </CCard>
+              )}
+            </CCardBody>
+          </CCard>
+        </CCol>
+      </CRow>
+    </div>
   )
 }
 
diff --git a/frontend/src/views/widgets/WidgetsDropdown.js b/frontend/src/views/widgets/WidgetsDropdown.js
index 4914227d6..c7fe5917e 100644
--- a/frontend/src/views/widgets/WidgetsDropdown.js
+++ b/frontend/src/views/widgets/WidgetsDropdown.js
@@ -10,11 +10,14 @@ import {
   CWidgetStatsA,
 } from '@coreui/react'
 import CIcon from '@coreui/icons-react'
-import { cilArrowTop, cilOptions } from '@coreui/icons'
+import { cilOptions } from '@coreui/icons'
+import { countUniqueEmails } from '../../views/emails/BreachesEmails'
+import { countUniquePasswords } from '../../views/passwords/BreachesPasswords'
 
 const WidgetsDropdown = () => {
   const [breachResults, setBreachResults] = useState([])
   const [recommendationCount, setRecommendationCount] = useState(0)
+  const [breachedPasswordCount, setBreachedPasswordCount] = useState(0)
   const navigate = useNavigate()
 
   useEffect(() => {
@@ -47,6 +50,19 @@ const WidgetsDropdown = () => {
         )
         const recommendationsData = await recommendationsResponse.json()
         setRecommendationCount(recommendationsData.total_recommendations)
+
+        // Fetch breached passwords count
+        const breachedPasswordsResponse = await fetch(
+          'http://localhost:8000/api/breaches/passwords/details/',
+          {
+            headers: {
+              Authorization: `Bearer ${token}`,
+            },
+          },
+        )
+        const breachedPasswordsData = await breachedPasswordsResponse.json()
+        const breachedPasswordsCount = countUniquePasswords(breachedPasswordsData)
+        setBreachedPasswordCount(breachedPasswordsCount)
       } catch (error) {
         console.error('Error fetching data:', error)
       }
@@ -56,20 +72,31 @@ const WidgetsDropdown = () => {
   }, [navigate])
 
   const handleViewBreachesClick = () => {
-    window.location.href = '/breaches-emails#/view'
+    window.location.href = '#/email-breaches/view'
   }
 
   const handleAddBreachesClick = () => {
-    window.location.href = '/breaches-emails#/add'
+    window.location.href = '#/email-breaches/add'
+  }
+
+  const handleViewPasswordsClick = () => {
+    window.location.href = '#/password-breaches/view'
+  }
+  const handleAddPasswordsClick = () => {
+    window.location.href = '#/password-breaches/add'
+  }
+
+  const handleViewRecommendationsClick = () => {
+    window.location.href = '#/recommendations'
   }
 
   return (
     <CRow>
-      <CCol sm={6} lg={3}>
+      <CCol sm={6} lg={4}>
         <CWidgetStatsA
           className="my-4 pb-4"
-          color="primary"
-          value={<>{breachResults.length}</>}
+          color="secondary"
+          value={<>{countUniqueEmails(breachResults)}</>}
           title="Emails Breached"
           action={
             <CDropdown alignment="end">
@@ -84,11 +111,30 @@ const WidgetsDropdown = () => {
           }
         />
       </CCol>
-      <CCol sm={6} lg={3}>
+      <CCol sm={6} lg={4}>
+        <CWidgetStatsA
+          className="my-4 pb-4 tertiary-background"
+          color="tertiary"
+          value={breachedPasswordCount}
+          title="Breached Passwords"
+          action={
+            <CDropdown alignment="end">
+              <CDropdownToggle color="transparent" caret={false} className="p-0">
+                <CIcon icon={cilOptions} className="text-high-emphasis-inverse" />
+              </CDropdownToggle>
+              <CDropdownMenu>
+                <CDropdownItem onClick={handleViewPasswordsClick}>View Passwords</CDropdownItem>
+                <CDropdownItem onClick={handleAddPasswordsClick}>Add Password</CDropdownItem>
+              </CDropdownMenu>
+            </CDropdown>
+          }
+        />
+      </CCol>
+      <CCol sm={6} lg={4}>
         <CWidgetStatsA
           className="my-4 pb-4"
           color="info"
-          value={<> {recommendationCount}</>}
+          value={recommendationCount}
           title="Total Network Recommendations"
           action={
             <CDropdown alignment="end">
@@ -96,10 +142,9 @@ const WidgetsDropdown = () => {
                 <CIcon icon={cilOptions} className="text-high-emphasis-inverse" />
               </CDropdownToggle>
               <CDropdownMenu>
-                <CDropdownItem>Action</CDropdownItem>
-                <CDropdownItem>Another action</CDropdownItem>
-                <CDropdownItem>Something else here...</CDropdownItem>
-                <CDropdownItem disabled>Disabled action</CDropdownItem>
+                <CDropdownItem onClick={handleViewRecommendationsClick}>
+                  View Recommendations
+                </CDropdownItem>
               </CDropdownMenu>
             </CDropdown>
           }
-- 
GitLab