From 8126e6dc95ed7a488180e8a11f97cc7e9b78d1ee Mon Sep 17 00:00:00 2001 From: Ean Milligan Date: Thu, 23 Apr 2026 16:51:06 -0400 Subject: [PATCH] add unenroll to api home page, minor changes --- mod.ts | 7 ++++--- ssr/buildHome.ts | 17 +++++++++++++++++ ssr/buildLogin.ts | 4 ++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/mod.ts b/mod.ts index 1e9b4d6..501a39f 100644 --- a/mod.ts +++ b/mod.ts @@ -131,13 +131,14 @@ Deno.serve({ port: config.api.port }, async (req) => { if (!(await verify(body.pin, loginMatch[0].hash))) return genericResponse(STATUS_CODE.Forbidden, 'Invalid name/PIN combination.'); const id = loginMatch[0].id; const email = loginMatch[0].email; - const hasEmail = email.length > 0; + const hasEmail = (email ?? '').length > 0; const deleteCode = loginMatch[0].deleteCode; + const deleteCodeSet = (deleteCode ?? '').length > 0; switch (req.method) { case 'POST': if (path === '/auth') { - return genericResponse(STATUS_CODE.OK, JSON.stringify({ id, hasEmail })); + return genericResponse(STATUS_CODE.OK, JSON.stringify({ id, hasEmail, deleteCodeSet })); } else if (path === '/create') { if (body.planName.trim().length > 200) return genericResponse(STATUS_CODE.BadRequest, 'Name too long.'); if (body.folder.trim() && body.folder.trim().length > 200) return genericResponse(STATUS_CODE.BadRequest, 'Folder name too long.'); @@ -258,7 +259,7 @@ Deno.serve({ port: config.api.port }, async (req) => { fromAddress: config.email.address, toAddress: email, subject: 'XIVPlan+DB Delete Code', - content: `Notice: account deletion is permanent and will delete all plans saved under your account.

Please use the following Delete Code to delete your account:

${newDeleteCode}`, + content: `Notice: Account deletion is permanent and will permanently delete all plans saved under your account.

Please use the following Delete Code to delete your account:

${newDeleteCode}`, }), }).catch(() => { failed = true; diff --git a/ssr/buildHome.ts b/ssr/buildHome.ts index 9b15089..cbae338 100644 --- a/ssr/buildHome.ts +++ b/ssr/buildHome.ts @@ -61,6 +61,22 @@ const link=\`${config.api.publicDomain}share#\${planId}\`; try{await navigator.clipboard.writeText(link);alert('Link copied to clipboard');} catch (error){prompt('Failed to copy to clipboard, please select and copy the link below:',link);} } +function deleteAccount(){ +const userName=prompt('Please enter your username:') +if(!userName.trim()){return;} +const userPin=prompt('Please enter your PIN:'); +if(!userPin.trim()){return;} +if(!confirm('Are you sure you want to delete your account? This is permanent and irreversible, and will delete all plans saved to your account as well.')){return;} +fetch('/api/auth',{method:'POST',body:JSON.stringify({name:userName.trim(),pin:userPin.trim()})}) +.catch((e)=>{e.text().then((text)=>{alert(text);});}) +.then((r) => {if(r.status===200){r.json().then((j)=>{ +let deleteCode='';if(j.hasEmail&&j.deleteCodeSet)deleteCode=prompt('Please enter the Delete Code emailed to you (if you don\'t see it, please check your spam folder):'); +if(j.hasEmail&&j.deleteCodeSet&&!deleteCode){alert('Delete code required.');return;} +fetch('/api/unenroll',{method:'DELETE',body:JSON.stringify({name:userName.trim(),pin:userPin.trim(),deleteCode:deleteCode.trim()})}) +.catch((e)=>{e.text().then((text)=>{alert(text);});}) +.then((r) => {if(r.status===200){alert('Account and plans deleted.');window.location.reload();}else{r.text().then((text)=>{alert(text);});}}); +});}else{r.text().then((text)=>{alert(text);});}}); +}

This is a very basic management page. Please excuse the number of alert/prompts that will come up when you click on things as it was the quickest way to build it out.

Please note: anything modifying data will require you to enter your PIN again as both the web view you are looking at and server behind it are completely stateless for simplicity.

@@ -74,5 +90,6 @@ ${plans.map((plan) => makePlanItem(plan, false)).join('')} + `; }; diff --git a/ssr/buildLogin.ts b/ssr/buildLogin.ts index ed477e9..f7cf581 100644 --- a/ssr/buildLogin.ts +++ b/ssr/buildLogin.ts @@ -1,10 +1,10 @@ export default `