changeset 57:169ac5fdb320

add change email
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 28 Nov 2022 23:47:19 -0700
parents 7ce54f6d93f2
children 31c895b73bd0
files src/account.html.luan src/api/change_email.json.luan src/api/forms.html src/change_email.html.luan src/change_name.html.luan src/lib/User.luan
diffstat 6 files changed, 143 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.html.luan	Mon Nov 28 22:00:43 2022 -0700
+++ b/src/account.html.luan	Mon Nov 28 23:47:19 2022 -0700
@@ -25,6 +25,7 @@
 			<h1>Your Account</h1>
 
 			<p><a href="/change_name.html">Change Name</a></p>
+			<p><a href="/change_email.html">Change Email</a></p>
 			<p><a href="/logout.html">Logout</a></p>
 		</div>
 <%		footer() %>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/api/change_email.json.luan	Mon Nov 28 23:47:19 2022 -0700
@@ -0,0 +1,33 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.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 Mail = require "site:/lib/Mail.luan"
+local Api = require "site:/api/Api.luan"
+local api = Api.api or error()
+local user_error = Api.user_error or error()
+
+
+return api(function()
+	local base_url = Http.request.parameters.base_url or user_error "missing base_url param"
+	local from = Http.request.parameters.from or user_error "missing from param"
+	local email = Http.request.parameters.email or user_error "missing email param"
+	local password = Http.request.parameters.password or user_error "missing password param"
+	local mailer = Mail.sender() or user_error "mail not configured"
+	mailer.send{
+		From = from
+		To = email
+		Subject = "Change Email"
+		body = output_of(function() %>
+Change your email address to this email by clicking this link:
+
+<%=base_url%>/change_email.html?email=<%=url_encode(email)%>&password=<%=password%>
+<%		end)
+	}
+	return {
+		okay = true
+	}
+end)
--- a/src/api/forms.html	Mon Nov 28 22:00:43 2022 -0700
+++ b/src/api/forms.html	Mon Nov 28 23:47:19 2022 -0700
@@ -15,5 +15,14 @@
 			<p><input type=submit></p>
 		</form>
 		<hr>
+		<form action="change_email.json">
+			<h3>change_email</h3>
+			<p>base_url: <input name=base_url type=url required></p>
+			<p>from: <input name=from required></p>
+			<p>email: <input name=email type=email required></p>
+			<p>password: <input name=password required></p>
+			<p><input type=submit></p>
+		</form>
+		<hr>
 	</body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/change_email.html.luan	Mon Nov 28 23:47:19 2022 -0700
@@ -0,0 +1,96 @@
+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 Db = require "site:/lib/Db.luan"
+local run_in_transaction = Db.run_in_transaction or error()
+
+
+local function page(contents)
+	Io.stdout = Http.response.text_writer()
+%>
+<!doctype html>
+<html>
+	<head>
+<%		head() %>
+		<title><%=forum_title%> - Change Email</title>
+	</head>
+	<body>
+<%		header() %>
+		<div content>
+			<h1>Change Email</h1>
+<%
+			contents()
+%>
+		</div>
+<%		footer() %>
+	</body>
+</html>
+<%
+end
+
+return function()
+	local user = User.current_required()
+	if user==nil then return end
+	local email = Http.request.parameters.email
+	local password = Http.request.parameters.password
+	if email == nil then
+		page(function()
+%>
+			<form>
+				<p>Your current email is <b><%=user.email%></b>.</p>
+				<p>
+					<label>Change email to</label>
+					<input type="email" name="email" autofocus required>
+				</p>
+				<p><input type="submit"></p>
+			</form>
+<%
+		end)
+	elseif password == nil then
+		run_in_transaction( function()
+			user = user.reload()
+			user.hidden_password = User.new_password()
+			user.save()
+		end )
+		local result = call_mail_api( "change_email", {
+			base_url = base_url()
+			from = forum_title.." <support@freedit.org>"
+			email = email
+			password = user.hidden_password
+		} )
+		result.okay or error(result.error)
+		page(function()
+%>
+			<p>We have sent an email to your new email address.  Click on the link in that email to complete the change.</p>
+<%
+		end)
+	elseif password ~= user.hidden_password then
+		page(function()
+%>
+			<p>This link is no longer valid.  Please <a href="/change_email.html">try again</a>.</p>
+<%
+		end)
+	else
+		run_in_transaction( function()
+			user = user.reload()
+			user.email = email
+			user.hidden_password = nil
+			user.save()
+		end )
+		page(function()
+%>
+			<p>Your email has been change to <b><%=user.email%></b>.</p>
+<%
+		end)
+	end
+end
--- a/src/change_name.html.luan	Mon Nov 28 22:00:43 2022 -0700
+++ b/src/change_name.html.luan	Mon Nov 28 23:47:19 2022 -0700
@@ -41,6 +41,7 @@
 
 return function()
 	local user = User.current_required()
+	if user==nil then return end
 	local name = user.name or error()
 	local error_message = nil
 	if Http.request.method == "POST" then
--- a/src/lib/User.luan	Mon Nov 28 22:00:43 2022 -0700
+++ b/src/lib/User.luan	Mon Nov 28 23:47:19 2022 -0700
@@ -39,6 +39,7 @@
 		password = doc.password
 		name = doc.user_name
 		created = doc.created
+		hidden_password = doc.hidden_password
 	}
 	set_local_only(users_by_id,user.id,user)
 	return user
@@ -53,6 +54,7 @@
 		password = user.password
 		user_name = user.name
 		created = user.created or time_now()
+		hidden_password = user.hidden_password
 	}
 end
 
@@ -150,6 +152,7 @@
 	end
 	return concat(t)
 end
+User.new_password = new_password
 
 function User.get_or_create_by_email(email,change_password)
 	local user = User.get_by_email(email)