view src/login.html.luan @ 35:1ce75c5ab0f7

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 03 Aug 2022 14:13:12 -0600
parents a1db5223ced1
children 260abd8f8565
line wrap: on
line source

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()
%>
<!doctype html>
<html>
	<head>
<%		head() %>
		<title><%=forum_title%> - Login or Register</title>
	</head>
	<body>
<%		header() %>
		<div content>
			<h1>Login or Register</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
	if email == nil then
		page(function()
%>
			<form>
				<label>Email address</label>
				<input type="email" name="email" autofocus required>
				<input type="submit" value="Login or Register">
			</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