diff options
Diffstat (limited to 'pages/auth.fnl')
| -rw-r--r-- | pages/auth.fnl | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/pages/auth.fnl b/pages/auth.fnl new file mode 100644 index 0000000..fc35be0 --- /dev/null +++ b/pages/auth.fnl @@ -0,0 +1,68 @@ +(import-macros {:compile-html <>} :macros) +(local forms (require :forms)) +(local lib (require :lib)) +(local templates (require :templates)) + +(local auth-form [ + {:title "" + :fields [ + (forms.text-input "name" "Пользователь" true) + (forms.password-input "password" "Пароль" true)]}]) + +(fn content [data errors] + (set data.password nil) + [(<> + [:div {:class "side"} + (templates.header "/auth")]) + (<> + [:section {:class "content"} + [:div {:class "mb-1"} [:a {:href "/"} "⟵ Обратно на главную"]] + [:h2 {} "Войти"] + (forms.render-form auth-form data errors)])]) + +(fn create-session [db user] + (local id (_G.must (luna.crypto.random-string 64))) + (local next-week (os.date "%Y-%m-%d %H:%M:%S" + (+ (os.time) (* 60 60 24 7)))) + (_G.must + (luna.db.exec + db "INSERT INTO auth_sessions (id, user, creation_time, expires_at) + VALUES (?, ?, ?, ?)" + [id user (lib.now) next-week])) + + id) + +(fn check-user [db name entered-pass] + (local users + (_G.must + (luna.db.query db + "SELECT users.password + FROM USERS + WHERE LOWER(users.name) = ? + LIMIT 1" [name]))) + + (if (< 0 (# users)) + (let [password (. users 1 1)] + (_G.must (luna.crypto.check-password entered-pass password))) + false)) + +(fn render [request db authenticated?] + (if authenticated? + (values 302 {:Location "/"} "") + (if request.form + (let [name request.form.name + entered-password request.form.password + correct-creds? (check-user db name entered-password) + errors (if (not correct-creds?) + {:password "Пользователя с таким именем и паролем не существует."} + nil)] + (if correct-creds? + (do + (local session-id (create-session db name)) + (values 302 {:Location "/shop" + :Set-Cookie (.. "auth= " session-id "; HttpOnly; SameSite=strict" + (if luna.debug? "" "; Secure"))} "")) + (values 200 {} (templates.base (content request.form errors))))) + (values 200 {} (templates.base (content {} {})))))) + +{: render} |
