diff --git a/public/style.css b/public/style.css
index 1a014ce..8b7e8f1 100644
--- a/public/style.css
+++ b/public/style.css
@@ -89,4 +89,23 @@ pre {
}
.dir-header a {
text-decoration: none;
+}
+
+.fancy-button {
+ outline: 0;
+ border: none;
+ background-color: var(--accent-color);
+ color: #000;
+ font-size: 1.2rem;
+ padding: 0.4em 0.8em;
+ margin: 0.5em;
+ border-radius: 16px;
+
+ cursor: pointer;
+
+ transition: 0.1s background-color;
+}
+
+.fancy-button:hover {
+ background-color: var(--accent-color-bri);
}
\ No newline at end of file
diff --git a/public/template/account_management.ecr b/public/template/account_management.ecr
index a4d22ba..5ada715 100644
--- a/public/template/account_management.ecr
+++ b/public/template/account_management.ecr
@@ -6,9 +6,20 @@
Account Management
+
-
- Account Management
- hewwo
+
+ hewwo, <%= username %>!
+
+ Nothing is implemented right now for account management
+ This is just a test list
+ Did you know your account ID is <%= account_id %>?
+
diff --git a/public/template/login.ecr b/public/template/login.ecr
new file mode 100644
index 0000000..7b3ac50
--- /dev/null
+++ b/public/template/login.ecr
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ Login
+
+
+
+
+
+
diff --git a/shard.lock b/shard.lock
index a259202..d071c03 100644
--- a/shard.lock
+++ b/shard.lock
@@ -8,6 +8,10 @@ shards:
git: https://github.com/gdotdesign/cr-dotenv.git
version: 1.0.0
+ http-session:
+ git: https://github.com/straight-shoota/http-session.git
+ version: 0.2.0+git.commit.7bd278a5567f89cdc348e3d468bd25d561319492
+
migrate:
git: https://github.com/oatmealine/migrate.cr.git
version: 0.5.0+git.commit.a4a24df3d05d0481c76ccd42e45cc48fa3fc1e73
diff --git a/shard.yml b/shard.yml
index c9e5b4b..d351ad7 100644
--- a/shard.yml
+++ b/shard.yml
@@ -21,6 +21,8 @@ dependencies:
toml:
github: crystal-community/toml.cr
branch: master
+ http-session:
+ github: straight-shoota/http-session
crystal: 1.6.2
diff --git a/src/lib/templates.cr b/src/lib/templates.cr
index 6dd0999..2a3c99c 100644
--- a/src/lib/templates.cr
+++ b/src/lib/templates.cr
@@ -1,3 +1,5 @@
+require "http-session"
+
module CrystalGauntlet::Templates
extend self
@@ -14,3 +16,22 @@ module CrystalGauntlet::Templates
)
end
end
+
+module CrystalGauntlet
+ record UserSession, username : String, account_id : Int32, user_id : Int32
+
+ # todo: replace memory storage with sqlite maybe? has to be hand-written but oh well
+ @@session_storage = HTTPSession::Storage::Memory(UserSession).new
+ @@sessions : HTTPSession::Manager(UserSession) = HTTPSession::Manager.new(@@session_storage, HTTP::Cookie.new("surveillance_device", "", secure: false, http_only: true, max_age: 365.days))
+
+ spawn do
+ session_storage.run_gc_loop
+ end
+
+ def self.session_storage
+ @@session_storage
+ end
+ def self.sessions
+ @@sessions
+ end
+end
diff --git a/src/template_endpoints/account_management.cr b/src/template_endpoints/account_management.cr
index e5371ee..3b62329 100644
--- a/src/template_endpoints/account_management.cr
+++ b/src/template_endpoints/account_management.cr
@@ -1,5 +1,5 @@
require "uri"
-require "compress/gzip"
+require "http-session"
include CrystalGauntlet
@@ -10,5 +10,55 @@ CrystalGauntlet.template_endpoints["/#{config_get("general.append_path").as(Stri
CrystalGauntlet.template_endpoints["/accounts"] = ->(context : HTTP::Server::Context) {
context.response.content_type = "text/html"
- ECR.embed("./public/template/account_management.ecr", context.response)
+
+ if session = CrystalGauntlet.sessions.get(context)
+ logged_in = true
+ account_id = session.account_id
+ user_id = session.user_id
+ username = session.username
+ else
+ logged_in = false
+ account_id = nil
+ user_id = nil
+ username = nil
+ end
+
+ body = context.request.body
+ if body
+ begin
+ params = URI::Params.parse(body.gets_to_end)
+ username = params["username"].strip
+ password = params["password"].strip
+
+ if username.empty? || password.empty?
+ raise "Invalid username or password"
+ end
+
+ # todo: dedup this code with the login account endpoint maybe
+ result = DATABASE.query_all("select id, password from accounts where username = ?", username, as: {Int32, String})
+ if result.size > 0
+ account_id, hash = result[0]
+ bcrypt = Crypto::Bcrypt::Password.new(hash)
+
+ if bcrypt.verify(password)
+ user_id = Accounts.get_user_id(account_id)
+ logged_in = true
+ LOG.debug { "#{username} logged in" }
+ CrystalGauntlet.sessions.set(context, UserSession.new(username, account_id, user_id))
+ else
+ raise "Invalid password"
+ end
+ else
+ raise "No such user exists"
+ end
+ rescue error
+ LOG.error(exception: error) {"whar...."}
+ end
+ end
+
+ if logged_in
+ ECR.embed("./public/template/account_management.ecr", context.response)
+ else
+ ECR.embed("./public/template/login.ecr", context.response)
+ end
}