public inbox for [email protected]
 help / color / mirror / Atom feed
From: Ammar Faizi <[email protected]>
To: Muhammad Rizki <[email protected]>
Cc: Ammar Faizi <[email protected]>,
	GNU/Weeb Mailing List <[email protected]>,
	Alviro Iskandar Setiawan <[email protected]>
Subject: [PATCH gwmail 2/7] public: Refactor old interface to keep up with new API
Date: Fri, 28 Feb 2025 06:22:29 +0700	[thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>

A preparation work to keep up with new API. This should be a good
example for the frontend developer to start working on new features.
Give only basic functionalities, I don't touch CSS much, I will let
Muhammad Rizki handle it.

Signed-off-by: Ammar Faizi <[email protected]>
---
 public/assets/js/api.js | 168 +++++++++++++++++++++++++---------------
 public/home.html        |  53 ++++++++-----
 public/index.html       |  20 +++--
 3 files changed, 151 insertions(+), 90 deletions(-)

diff --git a/public/assets/js/api.js b/public/assets/js/api.js
index 9a9cc7ef5af6..6593198aab2a 100644
--- a/public/assets/js/api.js
+++ b/public/assets/js/api.js
@@ -1,57 +1,83 @@
-
-const GWM_API_URL = "https://mail.gnuweeb.org/api.php?action=";
+const GWM_API_URL = "https://mail.gnuweeb.org/api2.php?action=";
 const LS = localStorage;
 
+function gid(i)
+{
+	return document.getElementById(i);
+}
+
+function escape_html(s)
+{
+	return s.replace(/&/g, "&amp;")
+		.replace(/</g, "&lt;")
+		.replace(/>/g, "&gt;");
+}
+
+function gwm_auth_get_token()
+{
+	return LS.getItem("gwm_token");
+}
+
 function gwm_exec_api(p)
 {
 	let xhr = new XMLHttpRequest();
 	xhr.open(p.method, p.url);
-	xhr.setRequestHeader("Content-Type", "application/json");
+	xhr.withCredentials = true;
+
+	if (p.ct === "json")
+		xhr.setRequestHeader("Content-Type", "application/json");
 
 	if (p.token)
 		xhr.setRequestHeader("Authorization", "Bearer " + p.token);
 
 	xhr.onreadystatechange = function() {
-		if (xhr.readyState == 4) {
-			if (p.callback)
-				p.callback(JSON.parse(xhr.responseText));
+		let res;
+
+		if (xhr.readyState !== 4)
+			return;
+
+		try {
+			res = JSON.parse(xhr.responseText);
+		} catch (e) {
+			res = xhr.responseText;
 		}
-	}
-	xhr.send(JSON.stringify(p.data));
+
+		if (p.callback)
+			p.callback(res, xhr);
+	};
+	xhr.send(p.data);
 }
 
-function gwm_api_get_user_info(tkn, cbk)
+function gwm_exec_api_multipart(p)
 {
-	gwm_exec_api({
-		method: "GET",
-		url: GWM_API_URL + "get_user_info",
-		token: tkn,
-		callback: cbk
-	});
+	p.ct = "multipart";
+	gwm_exec_api(p);
+}
+
+function gwm_exec_api_json(p)
+{
+	p.ct = "json";
+	p.data = JSON.stringify(p.data);
+	gwm_exec_api(p);
 }
 
-function gwm_api_login(user, pass, cbk)
+function gwm_api_get_user_info(cb)
 {
 	gwm_exec_api({
-		method: "POST",
-		url: GWM_API_URL + "login",
-		data: { user: user, pass: pass },
-		callback: cbk
+		method: "GET",
+		url: GWM_API_URL + "get_user_info&renew_token=1",
+		token: LS.getItem("gwm_token"),
+		callback: cb
 	});
 }
 
-function gwm_api_change_password(tkn, cur_pass, new_pass, cbk)
+function gwm_api_login(cb, user, pass)
 {
-	gwm_exec_api({
+	gwm_exec_api_json({
 		method: "POST",
-		url: GWM_API_URL + "change_password",
-		token: tkn,
-		data: {
-			cur_pass: cur_pass,
-			new_pass: new_pass,
-			retype_new_pass: new_pass
-		},
-		callback: cbk
+		url: GWM_API_URL + "login",
+		data: { user: user, pass: pass },
+		callback: cb
 	});
 }
 
@@ -70,71 +96,87 @@ function gwm_cb_login(j)
 	window.location.href = "/home.html";
 }
 
-function gwm_fn_login(user, pass)
+function gwm_fn_login(cb, user, pass)
 {
-	gwm_api_login(user, pass, gwm_cb_login);
+	gwm_api_login(cb, user, pass);
 }
 
-function gwm_cb_change_pass(j)
+function gwm_cb_change_password(j)
 {
-	if (j.code === 200) {
-		alert("Password changed successfully!");
-		window.location.href = "?";
-	} else {
-		alert("Failed to change password: " + JSON.stringify(j.res));
+	if (j.code !== 200) {
+		alert("Password change failed: " + JSON.stringify(j.res));
+		return false;
 	}
-}
 
-function gwm_fn_change_pass(cur_pass, new_pass)
-{
-	let tkn = LS.getItem("gwm_token");
-	gwm_api_change_password(tkn, cur_pass, new_pass, gwm_cb_change_pass);
+	alert("Password changed successfully!");
+	return true;
 }
 
-function gwm_redirect_if_authorized()
+function gwm_fn_change_password(cb, cur_pass, new_pass, retype_new_pass)
 {
-	if (LS.getItem("gwm_token"))
-		window.location.href = "/home.html";
+	gwm_exec_api_json({
+		method: "POST",
+		url: GWM_API_URL + "change_password",
+		data: {
+			cur_pass: cur_pass,
+			new_pass: new_pass,
+			retype_new_pass: retype_new_pass
+		},
+		callback: cb,
+		token: gwm_auth_get_token()
+	});
 }
 
-function gwm_do_logout()
+function gwm_fn_logout()
 {
 	LS.clear();
 	window.location.href = "/";
 }
 
-function gwm_gu_cb(j)
+function gwm_auth_get_user()
 {
-	if (j.code === 200) {
-		LS.setItem("gwm_uinfo", JSON.stringify(j.res));
-	} else {
-		alert("Your session has expired. Please login again.");
-		gwm_do_logout();
+	return JSON.parse(LS.getItem("gwm_uinfo"));
+}
+
+function gwm_auth_redirect_if_authorized()
+{
+	if (LS.getItem("gwm_token")) {
+		window.location.href = "/home.html";
+		return true;
 	}
+
+	return false;
 }
 
-function gwm_redirect_if_not_authorized()
+function gwm_auth_redirect_if_not_authorized()
 {
 	let tkn = LS.getItem("gwm_token");
 	let uio = LS.getItem("gwm_uinfo");
 	let tkn_exp_at = LS.getItem("gwm_token_exp_at");
 
 	if (!tkn || !uio) {
-		gwm_do_logout();
-		return;
+		gwm_fn_logout();
+		return true;
 	}
 
 	let unix = Math.round((new Date()).getTime() / 1000);
 	if (unix >= tkn_exp_at) {
 		alert("Your session has expired. Please login again.");
-		gwm_do_logout();
-		return;
+		gwm_fn_logout();
+		return true;
 	}
 
-	gwm_api_get_user_info(tkn, gwm_gu_cb);
-}
+	gwm_api_get_user_info(function(j) {
+		if (j.code !== 200) {
+			alert("Your session has expired. Please login again.");
+			gwm_fn_logout();
+			return;
+		}
 
-function gwm_get_user_info()
-{
-	return JSON.parse(LS.getItem("gwm_uinfo"));
+		let rt = j.res.renew_token;
+		LS.setItem("gwm_uinfo", JSON.stringify(j.res.user_info));
+		LS.setItem("gwm_token", rt.token);
+		LS.setItem("gwm_token_exp_at", rt.token_exp_at);
+	});
+	return false;
 }
diff --git a/public/home.html b/public/home.html
index 1eb61c2d369f..baaf067c8f20 100644
--- a/public/home.html
+++ b/public/home.html
@@ -37,7 +37,7 @@ body {
 </head>
 <body>
 	<div class="main-cage">
-		<a href="javascript:gwm_do_logout();">
+		<a href="javascript:gwm_fn_logout();">
 			<button class="cg-btn">Logout</button>
 		</a>
 		<h1>GNU/Weeb Mail Dashboard</h1>
@@ -50,7 +50,7 @@ body {
 					<tbody>
 						<tr><td>Current	Password</td><td>:</td><td><input type="password" name="cur_pass" required/></td></tr>
 						<tr><td>New Password</td><td>:</td><td><input type="password" name="new_pass" required/></td></tr>
-						<tr><td>Retype New Password</td><td>:</td><td><input type="password" name="retyped_new_pass" required/></td></tr>
+						<tr><td>Retype New Password</td><td>:</td><td><input type="password" name="retype_new_pass" required/></td></tr>
 						<tr><td colspan="3" align="center"><button type="submit" class="cg-btn">Change Password</button></td></tr>
 					</tbody>
 				</table>
@@ -80,23 +80,38 @@ Auth: Normal Password
 	</div>
 </body>
 <script>
-gwm_redirect_if_not_authorized();
-let u = gwm_get_user_info();
-function gid(id) { return document.getElementById(id); }
-function escape_html(s) { return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); }
 
-gid("uinfo_full_name").innerHTML = escape_html(u.full_name);
-let fr = gid("change_pass_form");
-fr.onsubmit = function() {
-	let cur_pass = fr.cur_pass.value;
-	let new_pass = fr.new_pass.value;
-	let retyped_new_pass = fr.retyped_new_pass.value;
-	if (new_pass !== retyped_new_pass) {
-		alert("New password and retyped new password does not match!");
-		return false;
-	}
-	
-	gwm_fn_change_pass(cur_pass, new_pass);
-};
+function toggle_disable_inputs(form, disable)
+{
+	for (let i = 0; i < form.length; i++)
+		form[i].disabled = disable;
+}
+
+function main()
+{
+	let u, cpf;
+
+	if (gwm_auth_redirect_if_not_authorized())
+		return;
+
+	u = gwm_auth_get_user();
+	gid("uinfo_full_name").innerText = escape_html(u.full_name);
+	cpf = gid("change_pass_form");
+	cpf.onsubmit = function(e) {
+		e.preventDefault();
+
+		toggle_disable_inputs(cpf, true);
+		let cb = function (j) {
+			toggle_disable_inputs(cpf, false);
+			if (gwm_cb_change_password(j))
+				cpf.reset();
+		};
+
+		gwm_fn_change_password(cb, cpf.cur_pass.value,
+				       cpf.new_pass.value,
+				       cpf.retype_new_pass.value);
+	};
+}
+main();
 </script>
 </html>
diff --git a/public/index.html b/public/index.html
index ed300eba0964..b46da5787ea4 100644
--- a/public/index.html
+++ b/public/index.html
@@ -41,13 +41,17 @@
 	</div>
 </body>
 <script>
-gwm_redirect_if_authorized();
-let fr = document.getElementById("login-form");
-fr.onsubmit = function(e) {
-	e.preventDefault();
-	let user = fr.user.value;
-	let pass = fr.pass.value;
-	gwm_fn_login(user, pass);
-};
+function main()
+{
+	if (gwm_auth_redirect_if_authorized())
+		return;
+
+	let fr = gid("login-form");
+	fr.onsubmit = function(e) {
+		e.preventDefault();
+		gwm_fn_login(gwm_cb_login, fr.user.value, fr.pass.value);
+	};
+}
+main();
 </script>
 </html>
-- 
Ammar Faizi


  parent reply	other threads:[~2025-02-27 23:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-27 23:22 [PATCH gwmail 0/7] User Profile Page Ammar Faizi
2025-02-27 23:22 ` [PATCH gwmail 1/7] settings/account: Add header 'change password' Ammar Faizi
2025-02-27 23:22 ` Ammar Faizi [this message]
2025-02-27 23:22 ` [PATCH gwmail 3/7] Rename 'public' to 'old' Ammar Faizi
2025-02-27 23:22 ` [PATCH gwmail 4/7] old: Add profile page Ammar Faizi
2025-02-27 23:22 ` [PATCH gwmail 5/7] old: Add photo profile support Ammar Faizi
2025-02-27 23:22 ` [PATCH gwmail 6/7] routes: layout: Adjust field with new API Ammar Faizi
2025-02-27 23:22 ` [PATCH gwmail 7/7] old: Use relative path to redirect Ammar Faizi
2025-02-27 23:28 ` [PATCH gwmail 0/7] User Profile Page Ammar Faizi
2025-02-27 23:31   ` Ammar Faizi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox