comparison src/login.html.luan @ 54:260abd8f8565

login and register
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 27 Nov 2022 23:46:27 -0700
parents a1db5223ced1
children c57b84f461ae
comparison
equal deleted inserted replaced
53:cac477dd1f82 54:260abd8f8565
1 local Luan = require "luan:Luan.luan" 1 local Luan = require "luan:Luan.luan"
2 local error = Luan.error 2 local error = Luan.error
3 local String = require "luan:String.luan"
4 local trim = String.trim or error()
5 local regex = String.regex or error()
6 local Html = require "luan:Html.luan" 3 local Html = require "luan:Html.luan"
7 local url_encode = Html.url_encode or error() 4 local url_encode = Html.url_encode or error()
8 local Io = require "luan:Io.luan" 5 local Io = require "luan:Io.luan"
9 local output_of = Io.output_of or error()
10 local Http = require "luan:http/Http.luan" 6 local Http = require "luan:http/Http.luan"
11 local Shared = require "site:/lib/Shared.luan" 7 local Shared = require "site:/lib/Shared.luan"
12 local head = Shared.head or error() 8 local head = Shared.head or error()
13 local header = Shared.header or error() 9 local header = Shared.header or error()
14 local footer = Shared.footer or error() 10 local footer = Shared.footer or error()
15 local base_url = Shared.base_url or error()
16 local call_mail_api = Shared.call_mail_api or error()
17 local Forum = require "site:/lib/Forum.luan" 11 local Forum = require "site:/lib/Forum.luan"
18 local forum_title = Forum.title or error() 12 local forum_title = Forum.title or error()
19 local User = require "site:/lib/User.luan" 13 local User = require "site:/lib/User.luan"
20 local Db = require "site:/lib/Db.luan"
21 local run_in_transaction = Db.run_in_transaction or error()
22 14
23
24 local name_regex = regex "^[a-zA-Z0-9_-]+$"
25
26 local function get_user(email,password)
27 local user = User.get_by_email(email)
28 user or error "email not found"
29 user.password == password or error "wrong password"
30 return user
31 end
32
33 local function login(user)
34 Http.response.set_persistent_cookie("user",user.name)
35 Http.response.set_persistent_cookie("password",user.password)
36 Http.request.cookies.user = user.name
37 Http.request.cookies.password = user.password
38 end
39
40 local function register_form(user,name,error_message)
41 if error_message ~= nil then %>
42 <p error>Error: <%= error_message %></p>
43 <% end %>
44 <form>
45 <input type="hidden" name="email" value="<%= user.email %>" >
46 <input type="hidden" name="password" value="<%= user.password %>" >
47 <label>User name for <%= user.email %></label>
48 <input type="text" name="name" value="<%= name or "" %>" autofocus required pattern="[a-zA-Z0-9_-]+">
49 <input type="submit" value="Register">
50 </form>
51 <%
52 end
53 15
54 local function page(contents) 16 local function page(contents)
55 Io.stdout = Http.response.text_writer() 17 Io.stdout = Http.response.text_writer()
56 %> 18 %>
57 <!doctype html> 19 <!doctype html>
58 <html> 20 <html>
59 <head> 21 <head>
60 <% head() %> 22 <% head() %>
61 <title><%=forum_title%> - Login or Register</title> 23 <title><%=forum_title%> - Login</title>
24 <script>
25 function show(checkbox) {
26 document.querySelector('input[name="password"]').type = checkbox.checked ? 'text' : 'password';
27 }
28 </script>
62 </head> 29 </head>
63 <body> 30 <body>
64 <% header() %> 31 <% header() %>
65 <div content> 32 <div content>
66 <h1>Login or Register</h1> 33 <h1>Login</h1>
67 <% 34 <%
68 contents() 35 contents()
69 %> 36 %>
70 </div> 37 </div>
71 <% footer() %> 38 <% footer() %>
75 end 42 end
76 43
77 return function() 44 return function()
78 local email = Http.request.parameters.email 45 local email = Http.request.parameters.email
79 local password = Http.request.parameters.password 46 local password = Http.request.parameters.password
80 local name = Http.request.parameters.name 47 local error_message = nil
81 if email == nil then 48 if Http.request.method == "POST" then
82 page(function() 49 local user = User.get_by_email(email)
50 if user == nil then
51 error_message = "email not found"
52 elseif user.password ~= password then
53 error_message = "wrong password"
54 end
55 if error_message == nil then
56 if user.name == nil then
57 Http.response.send_redirect("/set_name.html?email="..url_encode(email).."&password="..password)
58 return
59 end
60 user.login()
61 page(function()
83 %> 62 %>
84 <form> 63 <p>You are now logged in.</p>
85 <label>Email address</label> 64 <%
86 <input type="email" name="email" autofocus required> 65 end)
87 <input type="submit" value="Login or Register"> 66 return
67 end
68 end
69 page(function()
70 if error_message ~= nil then %>
71 <p error>Error: <%= error_message %></p>
72 <% end %>
73 <form action="login.html" method=post>
74 <p>
75 <label>Email address</label>
76 <input type="email" name="email" value="<%= email or "" %>" autofocus required>
77 </p>
78 <p>
79 <label>Password</label>
80 <input type="password" name="password" value="<%= password or "" %>">
81 <label clickable><input type=checkbox onclick="show(this)">Show</label>
82 </p>
83 <p><input type="submit" value="Login"></p>
88 </form> 84 </form>
89 <% 85 <%
90 end) 86 end)
91 elseif password == nil then
92 local user = User.get_or_create_by_email(email)
93 local result = call_mail_api( "login_email", {
94 base_url = base_url()
95 from = forum_title.." <support@freedit.org>"
96 email = user.email
97 password = user.password
98 } )
99 result.okay or error(result.error)
100 page(function()
101 %>
102 <p>We have sent you an email. Please check your email to login or register.</p>
103 <%
104 end)
105 elseif name == nil then
106 local user = get_user(email,password)
107 if user.name == nil then
108 page(function()
109 register_form(user)
110 end)
111 else
112 login(user)
113 page(function()
114 %>
115 <p>You are now logged in.</p>
116 <%
117 end)
118 end
119 else
120 name = trim(name)
121 name_regex.matches(name) or error "invalid name"
122 local error_message = nil
123 local user
124 run_in_transaction( function()
125 user = get_user(email,password)
126 if user.name ~= name and User.get_by_name(name) ~= nil then
127 error_message = "Name already in use"
128 else
129 user.name = name
130 user.save()
131 end
132 end )
133 if error_message ~= nil then
134 page(function()
135 register_form(user,name,error_message)
136 end)
137 else
138 login(user)
139 page(function()
140 %>
141 <p>You are now registered.</p>
142 <%
143 end)
144 end
145 end
146 end 87 end