diff --git a/WebServer/Components/Pages/Home.razor b/WebServer/Components/Pages/Home.razor
index bef96989..71c325ed 100644
--- a/WebServer/Components/Pages/Home.razor
+++ b/WebServer/Components/Pages/Home.razor
@@ -3,46 +3,70 @@
Home
-
-
-
- @foreach (stockPredictionPair cur in predictions){
-
-
Symbol: @cur.Symbol
- @if (cur.Movement == -1){
-
Sell
- } else if (cur.Movement == 1){
-
Buy
- } else{
-
Hold
- }
+
+ @if (Session == null){
+
+
LOGIN
+
+
+
+
+
+
+
+ @loginError
+
+
+
+
+ }else{
+
+ UserName: @Session.UserName
}
+
+
+
+
+
+
+
+
+ @foreach (stockPredictionPair cur in predictions){
+
+
Symbol: @cur.Symbol
+ @if (cur.Movement == -1){
+
Sell
+ } else if (cur.Movement == 1){
+
Buy
+ } else{
+
Hold
+ }
+
+ }
+
+
@code {
- string button1Text = "Train AI";
- string button2Text = "Predict AI";
+ // User Stuff
+ loginSession? Session = null;
+ // Login Stuff
+ string userName = "";
+ string passWord = "";
+ string loginError = "";
List
predictions = new List(){
new stockPredictionPair(){ Symbol = "AAPL" },
@@ -51,6 +75,36 @@
new stockPredictionPair(){ Symbol = "FUN" }
};
+ async Task LoginSession(){
+ string dbPrefix = $"[{userName.ToLower()}]:"; // Set the DB prefix for the get and set
+ string passwordhash = dbDriver.Get( dbPrefix + "password" ); // Pull the password hash
+ if (BCrypt.Verify( passWord, passwordhash )){ // If the password is valid
+ Session = new loginSession(){
+ UserName = userName.ToLower()
+ };
+ }else{
+ loginError = "wrong password";
+ }
+ }
+
+ async Task registerSession(){
+ string dbPrefix = $"[{userName.ToLower()}]:";
+ string passwordhash = dbDriver.Get( dbPrefix + "password" );
+ if (string.IsNullOrEmpty(passwordhash)){
+ dbDriver.Set( dbPrefix + "password", BCrypt.HashPassword( passWord, BCrypt.GenerateSalt() ) );
+ Session = new loginSession(){
+ UserName = userName.ToLower()
+ };
+ }else{
+ loginError = "account is taken";
+ }
+ }
+
+ // AI Stuff
+
+ string button1Text = "Train AI";
+ string button2Text = "Predict AI";
+
async Task pullandtrain(){
button1Text = "Do not refresh the page. The data is refreshing.";
await Task.Delay(1);
@@ -76,9 +130,15 @@
await Task.Delay(1);
}
- class stockPredictionPair{
- public string Symbol = "";
- public int Movement = 0;
+ // Data Types
+
+ class stockPredictionPair {
+ public string Symbol { get; set; } = "";
+ public int Movement { get; set; } = 0;
+ }
+
+ class loginSession {
+ public string UserName { get; set; } = "";
}
}
\ No newline at end of file
diff --git a/WebServer/Components/Pages/Home.razor.css b/WebServer/Components/Pages/Home.razor.css
index 9d8e445d..54a0f148 100644
--- a/WebServer/Components/Pages/Home.razor.css
+++ b/WebServer/Components/Pages/Home.razor.css
@@ -1,25 +1,62 @@
-.card-holder {
- display: flex;
- float: left;
- flex-direction: column;
- background-color: red;
- width: 300px;
- height: calc(100vh - 3.5rem);
-}
-
-.card {
- background-color: blue;
- margin: 5px;
- height: 45px;
- color: white;
- align-items: center;
- display: flex;
- justify-content: center;
-}
-
.main-area {
- float: left;
- background-color: aqua;
- height: calc(100vh - 3.5rem);
- width: calc(100vw - 300px);
+ display: grid;
+ gap: 20px;
+ padding: 20px;
+ grid-auto-columns: auto;
+ grid-auto-flow: column;
+ grid-template-columns: max-content;
+ overflow: scroll;
+}
+
+.gridFrame {
+ background: #eee;
+ border-radius: 12px;
+ padding: 1.5rem;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ transition: 0.5s ease-in-out;
+ height: fit-content;
+ display: grid;
+ grid-row-gap: 10px;
+ border: 1px solid black;
+}
+
+.gridFrame h2 {
+ text-align: center;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+
+.gridFrame:hover {
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
+}
+
+.loginRow {
+ width: 300px;
+ height: 40px;
+ padding-bottom: 10px;
+}
+
+.loginRow input {
+ width: calc(100% - 6px);
+ border: 1px solid black;
+ padding: 1px 2px;
+}
+
+ .loginRow input:focus {
+ border-color: brown;
+ }
+
+.loginRow button {
+ width: calc(50% - 15px);
+ background-color: darkblue;
+ border: 0;
+ margin: 0;
+ padding: 0;
+ color: white;
+ height: 30px;
+}
+
+.loginRow button:last-of-type{
+ float: right;
}
\ No newline at end of file
diff --git a/WebServer/Components/_Imports.razor b/WebServer/Components/_Imports.razor
index c8c4e4eb..22b16ca2 100644
--- a/WebServer/Components/_Imports.razor
+++ b/WebServer/Components/_Imports.razor
@@ -10,6 +10,7 @@
@using PythonInterop
@using WebServer
@using WebServer.Components
+@using BCrypt.Net;
@inject DbDriver dbDriver
@inject AIModule aiModule
diff --git a/WebServer/Controllers/Database.cs b/WebServer/Controllers/Database.cs
index a97a7fcd..196d9deb 100644
--- a/WebServer/Controllers/Database.cs
+++ b/WebServer/Controllers/Database.cs
@@ -2,52 +2,67 @@ using Microsoft.Data.Sqlite;
namespace DataBase {
- public class DbDriver : IDisposable {
+ public class DbDriver {
- static SqliteConnection? singletonConnector = null;
+ static bool Initilized = false;
public DbDriver() {
// Load in the datastore if not already loaded
- if (singletonConnector == null) {
- singletonConnector = new SqliteConnection("Data Source=test.db");
- singletonConnector.Open();
-
- // Create the key value store if not exist
- using var command = singletonConnector.CreateCommand();
- command.CommandText = """
- CREATE TABLE IF NOT EXISTS KeyValuePair (
- key TEXT NOT NULL,
- value TEXT,
- PRIMARY KEY(key)
- );
- """;
- command.ExecuteReader();
+ if (!Initilized) {
+ // Open a connection with auto dispose when done
+ using (SqliteConnection sqlite = new SqliteConnection("Data Source=test.db")) {
+ // Open the connection
+ sqlite.Open();
+ // Create the key value store if not exist
+ using var command = sqlite.CreateCommand();
+ command.CommandText = """
+ CREATE TABLE IF NOT EXISTS KeyValuePair (
+ key TEXT NOT NULL,
+ value TEXT,
+ PRIMARY KEY(key)
+ );
+ """;
+ // Run the command
+ command.ExecuteReader();
+ }
}
}
// Return Values from keys
public string Get(string Key) {
- if (singletonConnector != null) {
- using var command = singletonConnector.CreateCommand();
+ // Open a connection with auto dispose when done
+ using (SqliteConnection sqlite = new SqliteConnection("Data Source=test.db")) {
+ // Open the connection
+ sqlite.Open();
+ // Create the key value store if not exist
+ using var command = sqlite.CreateCommand();
command.CommandText = """
SELECT value
FROM KeyValuePair
Where key = $key;
""";
+ // Add the parameter to prevent sql injection
command.Parameters.AddWithValue("$key", Key);
- command.ExecuteReader();
+ // Run the command
using var reader = command.ExecuteReader();
+ // Read off the result if exists
if (reader.Read()) {
+ // Return the results
return reader.GetString(0);
}
+ // Return something if nothing existed
+ return "";
}
- return "";
}
// Set a key value pair in the store
public void Set(string Key, string Value) {
- if (singletonConnector != null) {
- using var command = singletonConnector.CreateCommand();
+ // Open a connection with auto dispose when done
+ using (SqliteConnection sqlite = new SqliteConnection("Data Source=test.db")) {
+ // Open the connection
+ sqlite.Open();
+ // Create the key value store if not exist
+ using var command = sqlite.CreateCommand();
command.CommandText = """
INSERT INTO KeyValuePair
(key,value)
@@ -57,24 +72,14 @@ namespace DataBase {
DO UPDATE
SET value = excluded.value;
""";
+ // Add the parameters to prevent sql injection
command.Parameters.AddWithValue("$key", Key);
command.Parameters.AddWithValue("$value", Value);
+ // Process the command
command.ExecuteReader();
}
}
- // Deconstructor
- ~DbDriver() {
- Dispose();
- }
-
- // Deconstructor
- public void Dispose() {
- if (singletonConnector != null) {
- singletonConnector.Close();
- singletonConnector = null;
- }
- }
}
}
\ No newline at end of file
diff --git a/WebServer/Program.cs b/WebServer/Program.cs
index da72e72f..3448ff19 100644
--- a/WebServer/Program.cs
+++ b/WebServer/Program.cs
@@ -19,7 +19,7 @@ if (args.Contains("Pull-Stock-Data")) {
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
// Insert the DB driver for Dependency Injection
- builder.Services.AddSingleton();
+ builder.Services.AddScoped();
// Insert the python modlue for Dependency Injection
builder.Services.AddSingleton(interopModule);
diff --git a/WebServer/WebServer.csproj b/WebServer/WebServer.csproj
index 74369535..5695abb4 100644
--- a/WebServer/WebServer.csproj
+++ b/WebServer/WebServer.csproj
@@ -7,6 +7,7 @@
+