diff --git a/vault/public/logo192.png b/vault/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/vault/public/logo192.png and /dev/null differ diff --git a/vault/public/logo512.png b/vault/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/vault/public/logo512.png and /dev/null differ diff --git a/vault/public/manifest.json b/vault/public/manifest.json index 080d6c7..f98d721 100644 --- a/vault/public/manifest.json +++ b/vault/public/manifest.json @@ -8,13 +8,13 @@ "type": "image/x-icon" }, { - "src": "logo192.png", - "type": "image/png", + "src": "vault_logo.jpg", + "type": "image/jpg", "sizes": "192x192" }, { - "src": "logo512.png", - "type": "image/png", + "src": "vault_logo.jpg", + "type": "image/jpg", "sizes": "512x512" } ], diff --git a/vault/src/App.css b/vault/src/App.css index 74b5e05..e09cf1d 100644 --- a/vault/src/App.css +++ b/vault/src/App.css @@ -1,38 +1,39 @@ .App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { + text-align: center; + } + .App-logo { - animation: App-logo-spin infinite 20s linear; + height: 40vmin; + pointer-events: none; + } + + @media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } + } + + .App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); + + .App-link { + color: #61dafb; } - to { - transform: rotate(360deg); + + @keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } -} + \ No newline at end of file diff --git a/vault/src/App.js b/vault/src/App.js index faee776..ce2944f 100644 --- a/vault/src/App.js +++ b/vault/src/App.js @@ -1,9 +1,9 @@ import React from 'react'; -import logo from './logo.svg'; import './App.css'; import { Routes, Route } from 'react-router-dom'; import LoginForm from './Components/LoginForm/LoginForm'; import RegistrationForm from "./Components/RegistrationForm/RegistrationForm"; +import Home from "./Components/Home/Home"; function App() { @@ -12,6 +12,7 @@ function App() { } /> } /> } /> + } /> ); } diff --git a/vault/src/App.test.js b/vault/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/vault/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/vault/src/Components/Home/Home.css b/vault/src/Components/Home/Home.css new file mode 100644 index 0000000..e69de29 diff --git a/vault/src/Components/Home/Home.jsx b/vault/src/Components/Home/Home.jsx new file mode 100644 index 0000000..3204757 --- /dev/null +++ b/vault/src/Components/Home/Home.jsx @@ -0,0 +1,13 @@ +import React, { useState } from 'react'; +import './Home.css'; +import { Link } from 'react-router-dom'; + +const Home = () => { + return ( +
+

Successful!

+
+ ); +}; + +export default Home; \ No newline at end of file diff --git a/vault/src/Components/LoginForm/LoginForm.jsx b/vault/src/Components/LoginForm/LoginForm.jsx index 728fddb..1bc3826 100644 --- a/vault/src/Components/LoginForm/LoginForm.jsx +++ b/vault/src/Components/LoginForm/LoginForm.jsx @@ -2,13 +2,14 @@ import React, { useState } from 'react'; import './LoginForm.css'; import { FaUser } from "react-icons/fa"; import { FaLock } from "react-icons/fa"; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; const LoginForm = () => { // State to store the username and password const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [errorMessage, setErrorMessage] = useState(''); + const navigate = useNavigate(); // Function to handle form submission const handleSubmit = async (e) => { @@ -27,8 +28,10 @@ const LoginForm = () => { if (response.ok) { console.log('Login successful:', data.message); + setErrorMessage(''); + navigate('/home'); } else { - setErrorMessage(data.message); // Show error message to the user + setErrorMessage(data.message); } } catch (error) { console.error('Error during login:', error); @@ -41,7 +44,7 @@ const LoginForm = () => {

Login

- setUsername(e.target.value)} /> + setUsername(e.target.value)} />
diff --git a/vault/src/Components/RegistrationForm/RegistrationForm.jsx b/vault/src/Components/RegistrationForm/RegistrationForm.jsx index ecde2a7..5bb535b 100644 --- a/vault/src/Components/RegistrationForm/RegistrationForm.jsx +++ b/vault/src/Components/RegistrationForm/RegistrationForm.jsx @@ -2,20 +2,51 @@ import React, { useState } from 'react'; import './RegistrationForm.css'; import { FaUser } from "react-icons/fa"; import { FaLock } from "react-icons/fa"; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; const RegistrationForm = () => { const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); + const [email, setEmail] = useState(''); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [confirmedPassword, setConfirmedPassword] = useState(''); const [errorMessage, setErrorMessage] = useState(''); + const navigate = useNavigate(); + + // Function to handle form submission + const handleSubmit = async (e) => { + e.preventDefault(); // Prevents page reload or default form submission + try { + // Send a POST request to backend + const response = await fetch('http://127.0.0.1:5000/register', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ firstName, lastName, email, username, password, confirmedPassword }), // Send user info + }); + + const data = await response.json(); + + if (response.ok) { + console.log('Account created!', data.message); + setErrorMessage(''); + navigate('/home'); + } else { + setErrorMessage(data.message); + } + } catch (error) { + console.error('Error during registration:', error); + setErrorMessage('Something went wrong. Please try again.'); + } + }; + return (
- +

Create an Account

{ onChange={(e) => setLastName(e.target.value)}/>
+
+ setEmail(e.target.value)}/> + +
setUsername(e.target.value)}/> diff --git a/vault/src/backend/app.py b/vault/src/backend/app.py index 39cc44b..46c3fcb 100644 --- a/vault/src/backend/app.py +++ b/vault/src/backend/app.py @@ -16,8 +16,10 @@ def init_db(): CREATE TABLE IF NOT EXISTS users ( user_id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, - email TEXT UNIQUE, + email TEXT UNIQUE NOT NULL, password TEXT NOT NULL, + first_name TEXT NOT NULL, + last_name TEXT NOT NULL, profile_pic TEXT, bio TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, @@ -57,18 +59,6 @@ def get_db_connection(): connection = sqlite3.connect('vault_database.db', timeout=10.0) return connection -def insert_new_user(username, password): - conn = get_db_connection() - cursor = conn.cursor() - - cursor.execute(''' - INSERT INTO users (username, password) VALUES (?, ?) - ''', (username, password)) - - conn.commit() - conn.close() - - # Initializes the database (will only need to be run when first creating the DB and anytime we add new fields/schemas to the tables @app.route('/init', methods=['GET']) def initialize_database(): @@ -95,10 +85,16 @@ def login(): conn = get_db_connection() cursor = conn.cursor() - # Checking if username is in database and if password is correct - cursor.execute("SELECT username, password FROM users WHERE username = ? AND password = ?", (username, password)) - user = cursor.fetchone() - conn.close() + if '@' not in username: + # Checking if username is in database and if password is correct + cursor.execute("SELECT username, password FROM users WHERE username = ? AND password = ?", (username, password)) + user = cursor.fetchone() + conn.close() + else: + # Checking if email is in database and if password is correct + cursor.execute("SELECT email, password FROM users WHERE email = ? AND password = ?", (username, password)) + user = cursor.fetchone() + conn.close() if user: return jsonify({"status": "success", "message": "Login successful!"}), 200 @@ -109,8 +105,13 @@ def login(): @app.route('/register', methods=['POST']) def register(): data = request.json + + firstName = data['firstName'] + lastName = data['lastName'] + email = data['email'] username = data['username'] password = data['password'] + confirmedPassword = data['confirmedPassword'] conn = get_db_connection() cursor = conn.cursor() @@ -121,15 +122,19 @@ def register(): if existing_user: # Username is already in database/is taken conn.close() - return jsonify({"error": "Username already taken"}), 409 + return jsonify({"status": "failure", "message": "Username already taken"}), 409 + + # Checking if passwords match + if password != confirmedPassword: + return jsonify({"status": "failure", "message": "Passwords do not match."}), 401 - # Adding username and password into the database - cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password)) + # Adding user info into the database + cursor.execute("INSERT INTO users (username, email, password, first_name, last_name) VALUES (?, ?, ?, ?, ?)", + (username, email, password, firstName, lastName)) conn.commit() conn.close() return jsonify({"status": "success", "message": "Account created!"}), 201 - # Retrieve single user by ID @app.route('/users/', methods=['GET']) def get_user(user_id): diff --git a/vault/src/backend/vault_database.db b/vault/src/backend/vault_database.db index b64ec47..7eeac5c 100644 Binary files a/vault/src/backend/vault_database.db and b/vault/src/backend/vault_database.db differ diff --git a/vault/src/index.js b/vault/src/index.js index 65b1962..99809da 100644 --- a/vault/src/index.js +++ b/vault/src/index.js @@ -2,7 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; -import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot(document.getElementById('root')); @@ -13,8 +12,3 @@ root.render( ); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/vault/src/logo.svg b/vault/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/vault/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/vault/src/reportWebVitals.js b/vault/src/reportWebVitals.js deleted file mode 100644 index 5253d3a..0000000 --- a/vault/src/reportWebVitals.js +++ /dev/null @@ -1,13 +0,0 @@ -const reportWebVitals = onPerfEntry => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } -}; - -export default reportWebVitals; diff --git a/vault/src/setupTests.js b/vault/src/setupTests.js deleted file mode 100644 index 8f2609b..0000000 --- a/vault/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom';