· 9 years ago · Aug 15, 2017, 02:28 AM
1require "kemal"
2require "kemal-session"
3require "db"
4require "sqlite3"
5require "secure_random"
6require "json"
7
8require "./utils"
9require "./config"
10
11# ======================== CONFIGS =======================================================
12
13# Open a connection to SQLite3
14SQLITE = DB.open("sqlite3:./database.db")
15SQLITE.exec Config::SQL_TABLE # create users table if not exists
16at_exit { SQLITE.close }
17
18# Config sessions and user type
19Kemal::Session.config do |config|
20 config.cookie_name = Config::COOKIE_NAME
21 config.secret = Config::SECRET
22 config.gc_interval = 2.minutes
23end
24
25# =========================== ROUTES =====================================================
26
27get "/" do |env|
28 if env.session && env.session.string?("user")
29 user = JSON.parse(env.session.string("user"))
30 res = SQLITE.query_one?("SELECT id, username, email FROM users WHERE username = ?", user["username"].as_s, as: {String, String, String})
31 if res
32 env.session.string("user", to_json({"id", "username", "email"}, res)) # refresh the session
33 env.set("user", to_json({"id", "username", "email"}, res))
34 user = JSON.parse(env.session.string("user"))
35 end
36 render "views/profile.ecr"
37 else
38 render "views/index.ecr"
39 end
40end
41
42get "/users/signup" do |env|
43 message = nil
44 render "views/register.ecr"
45end
46
47get "/users/login" do |env|
48 message = nil
49 render "views/login.ecr"
50end
51
52post "/users/signup" do |env|
53 form = env.params.body
54 check = Validator.new
55 # do some validation
56 username = check.username?(form["username"], "Invalid username format!")
57 email = check.email?(form["email"], "Wrong email format!")
58 password = check.password?(form["password"], "Password too weak!")
59 check.match?(form["password"], form["confirm"], "Passwords do NOT match!")
60 # check for validation errors
61 if check.validationErrors
62 message = check.validationErrors
63 render "views/register.ecr"
64 else
65 begin # assert for unique fiels
66 SQLITE.exec "INSERT INTO users VALUES (?, ?, ?, ?)", SecureRandom.uuid, username, email, password
67 rescue
68 message = "Field already taken"
69 render "views/register.ecr"
70 else
71 env.redirect "/"
72 end
73 end
74end
75
76post "/users/login" do |env|
77 username = env.params.body["username"]
78 password = env.params.body["password"]
79 # query the database and assert user data
80 res = SQLITE.query_one?("SELECT id, username, email, password FROM users WHERE username = ?", username, as: {String, String, String, String})
81 if !res || res.last != password
82 message = "Invalid username or password"
83 render "views/login.ecr"
84 else
85 user = to_json({"id", "username", "email", "password"}, res)
86 env.session.string("user", user)
87 env.redirect("/")
88 end
89end
90
91get "/logout" do |env|
92 env.session.destroy
93 env.redirect "/"
94end
95
96Kemal.run
97
98# TODO:
99# - redis database
100# - bcrypt