Mercurial Hosting > freedit
changeset 54:260abd8f8565
login and register
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 27 Nov 2022 23:46:27 -0700 |
parents | cac477dd1f82 |
children | c57b84f461ae |
files | src/api/login_email.json.luan src/lib/Shared.luan src/lib/User.luan src/login.html.luan src/register.html.luan src/set_name.html.luan src/site.css |
diffstat | 7 files changed, 225 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/src/api/login_email.json.luan Thu Nov 24 22:54:43 2022 -0700 +++ b/src/api/login_email.json.luan Sun Nov 27 23:46:27 2022 -0700 @@ -22,6 +22,8 @@ To = email Subject = "Login" body = output_of(function() %> +Your password is: <%=password%> + Login or register by clicking this link: <%=base_url%>/login.html?email=<%=url_encode(email)%>&password=<%=password%>
--- a/src/lib/Shared.luan Thu Nov 24 22:54:43 2022 -0700 +++ b/src/lib/Shared.luan Sun Nov 27 23:46:27 2022 -0700 @@ -38,7 +38,10 @@ <div header> <a href="/"><%=forum_title%></a> <% if user == nil then %> - <a href="/login.html">login</a> + <span> + <a href="/login.html">login</a> + / <a href="/register.html">register</a> + </span> <% else %> <a href="/account.html"><%=user.name_html%></a> <% end %>
--- a/src/lib/User.luan Thu Nov 24 22:54:43 2022 -0700 +++ b/src/lib/User.luan Sun Nov 27 23:46:27 2022 -0700 @@ -66,10 +66,26 @@ user.id = doc.id end + function user.reload() + return User.get_by_id(user.id) or error(user.id) + end + + function user.login() + Http.response.set_persistent_cookie("user",user.name) + Http.response.set_persistent_cookie("password",user.password) + Http.request.cookies.user = user.name or error() + Http.request.cookies.password = user.password or error() + end + set_metatable(user,metatable) return user end +function User.get_by_id(id) + local doc = Db.get_document("id:"..id) + return doc and from_doc(doc) +end + function User.get_by_email(email) local doc = Db.get_document("user_email:"..lucene_quote(email)) return doc and from_doc(doc)
--- a/src/login.html.luan Thu Nov 24 22:54:43 2022 -0700 +++ b/src/login.html.luan Sun Nov 27 23:46:27 2022 -0700 @@ -1,56 +1,18 @@ local Luan = require "luan:Luan.luan" local error = Luan.error -local String = require "luan:String.luan" -local trim = String.trim or error() -local regex = String.regex or error() local Html = require "luan:Html.luan" local url_encode = Html.url_encode or error() local Io = require "luan:Io.luan" -local output_of = Io.output_of or error() local Http = require "luan:http/Http.luan" local Shared = require "site:/lib/Shared.luan" local head = Shared.head or error() local header = Shared.header or error() local footer = Shared.footer or error() -local base_url = Shared.base_url or error() -local call_mail_api = Shared.call_mail_api or error() local Forum = require "site:/lib/Forum.luan" local forum_title = Forum.title or error() local User = require "site:/lib/User.luan" -local Db = require "site:/lib/Db.luan" -local run_in_transaction = Db.run_in_transaction or error() -local name_regex = regex "^[a-zA-Z0-9_-]+$" - -local function get_user(email,password) - local user = User.get_by_email(email) - user or error "email not found" - user.password == password or error "wrong password" - return user -end - -local function login(user) - Http.response.set_persistent_cookie("user",user.name) - Http.response.set_persistent_cookie("password",user.password) - Http.request.cookies.user = user.name - Http.request.cookies.password = user.password -end - -local function register_form(user,name,error_message) - if error_message ~= nil then %> - <p error>Error: <%= error_message %></p> -<% end %> - <form> - <input type="hidden" name="email" value="<%= user.email %>" > - <input type="hidden" name="password" value="<%= user.password %>" > - <label>User name for <%= user.email %></label> - <input type="text" name="name" value="<%= name or "" %>" autofocus required pattern="[a-zA-Z0-9_-]+"> - <input type="submit" value="Register"> - </form> -<% -end - local function page(contents) Io.stdout = Http.response.text_writer() %> @@ -58,12 +20,17 @@ <html> <head> <% head() %> - <title><%=forum_title%> - Login or Register</title> + <title><%=forum_title%> - Login</title> + <script> + function show(checkbox) { + document.querySelector('input[name="password"]').type = checkbox.checked ? 'text' : 'password'; + } + </script> </head> <body> <% header() %> <div content> - <h1>Login or Register</h1> + <h1>Login</h1> <% contents() %> @@ -77,70 +44,44 @@ return function() local email = Http.request.parameters.email local password = Http.request.parameters.password - local name = Http.request.parameters.name - if email == nil then - page(function() + local error_message = nil + if Http.request.method == "POST" then + local user = User.get_by_email(email) + if user == nil then + error_message = "email not found" + elseif user.password ~= password then + error_message = "wrong password" + end + if error_message == nil then + if user.name == nil then + Http.response.send_redirect("/set_name.html?email="..url_encode(email).."&password="..password) + return + end + user.login() + page(function() %> - <form> - <label>Email address</label> - <input type="email" name="email" autofocus required> - <input type="submit" value="Login or Register"> + <p>You are now logged in.</p> +<% + end) + return + end + end + page(function() + if error_message ~= nil then %> + <p error>Error: <%= error_message %></p> +<% end %> + <form action="login.html" method=post> + <p> + <label>Email address</label> + <input type="email" name="email" value="<%= email or "" %>" autofocus required> + </p> + <p> + <label>Password</label> + <input type="password" name="password" value="<%= password or "" %>"> + <label clickable><input type=checkbox onclick="show(this)">Show</label> + </p> + <p><input type="submit" value="Login"></p> </form> <% - end) - elseif password == nil then - local user = User.get_or_create_by_email(email) - local result = call_mail_api( "login_email", { - base_url = base_url() - from = forum_title.." <support@freedit.org>" - email = user.email - password = user.password - } ) - result.okay or error(result.error) - page(function() -%> - <p>We have sent you an email. Please check your email to login or register.</p> -<% - end) - elseif name == nil then - local user = get_user(email,password) - if user.name == nil then - page(function() - register_form(user) - end) - else - login(user) - page(function() -%> - <p>You are now logged in.</p> -<% - end) - end - else - name = trim(name) - name_regex.matches(name) or error "invalid name" - local error_message = nil - local user - run_in_transaction( function() - user = get_user(email,password) - if user.name ~= name and User.get_by_name(name) ~= nil then - error_message = "Name already in use" - else - user.name = name - user.save() - end - end ) - if error_message ~= nil then - page(function() - register_form(user,name,error_message) - end) - else - login(user) - page(function() -%> - <p>You are now registered.</p> -<% - end) - end - end + end) end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/register.html.luan Sun Nov 27 23:46:27 2022 -0700 @@ -0,0 +1,66 @@ +local Luan = require "luan:Luan.luan" +local error = Luan.error +local Io = require "luan:Io.luan" +local Http = require "luan:http/Http.luan" +local Shared = require "site:/lib/Shared.luan" +local head = Shared.head or error() +local header = Shared.header or error() +local footer = Shared.footer or error() +local base_url = Shared.base_url or error() +local call_mail_api = Shared.call_mail_api or error() +local Forum = require "site:/lib/Forum.luan" +local forum_title = Forum.title or error() +local User = require "site:/lib/User.luan" + + +local function page(contents) + Io.stdout = Http.response.text_writer() +%> +<!doctype html> +<html> + <head> +<% head() %> + <title><%=forum_title%> - Register or Get Password</title> + </head> + <body> +<% header() %> + <div content> + <h1>Register or Get Password</h1> +<% + contents() +%> + </div> +<% footer() %> + </body> +</html> +<% +end + +return function() + local email = Http.request.parameters.email + if email == nil then + page(function() +%> + <form> + <label>Email address</label> + <input type="email" name="email" autofocus required> + <input type="submit" value="Register or Get Password"> + </form> +<% + end) + else + local user = User.get_or_create_by_email(email) + local result = call_mail_api( "login_email", { + base_url = base_url() + from = forum_title.." <support@freedit.org>" + email = user.email + password = user.password + } ) + result.okay or error(result.error) + page(function() +%> + <p>We have sent you an email. Please check your email to login.</p> +<% + end) + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/set_name.html.luan Sun Nov 27 23:46:27 2022 -0700 @@ -0,0 +1,87 @@ +local Luan = require "luan:Luan.luan" +local error = Luan.error +local String = require "luan:String.luan" +local trim = String.trim or error() +local regex = String.regex or error() +local Io = require "luan:Io.luan" +local Http = require "luan:http/Http.luan" +local Shared = require "site:/lib/Shared.luan" +local head = Shared.head or error() +local header = Shared.header or error() +local footer = Shared.footer or error() +local Forum = require "site:/lib/Forum.luan" +local forum_title = Forum.title or error() +local User = require "site:/lib/User.luan" +local Db = require "site:/lib/Db.luan" +local run_in_transaction = Db.run_in_transaction or error() + + +local name_regex = regex "^[a-zA-Z0-9_-]+$" + +local function page(contents) + Io.stdout = Http.response.text_writer() +%> +<!doctype html> +<html> + <head> +<% head() %> + <title><%=forum_title%> - Set Name</title> + </head> + <body> +<% header() %> + <div content> + <h1>Set Name</h1> +<% + contents() +%> + </div> +<% footer() %> + </body> +</html> +<% +end + +return function() + local email = Http.request.parameters.email + local password = Http.request.parameters.password + local name = Http.request.parameters.name + local user = User.get_by_email(email) + user or error "email not found" + user.password == password or error "wrong password" + local error_message = nil + if Http.request.method == "POST" then + name = trim(name) + name_regex.matches(name) or error "invalid name" + run_in_transaction( function() + user = user.reload() + if user.name ~= name and User.get_by_name(name) ~= nil then + error_message = "Name already in use" + else + user.name = name + user.save() + end + end ) + if error_message == nil then + user.login() + page(function() +%> + <p>You are now logged in.</p> +<% + end) + return + end + end + page(function() + if error_message ~= nil then %> + <p error>Error: <%= error_message %></p> +<% end %> + <form action="set_name.html" method=post> + <input type="hidden" name="email" value="<%= user.email %>" > + <input type="hidden" name="password" value="<%= user.password %>" > + <label>User name for <%= user.email %></label> + <input type="text" name="name" value="<%= name or "" %>" autofocus required pattern="[a-zA-Z0-9_-]+"> + <input type="submit" value="Set"> + </form> +<% + end) +end