add unenroll to api home page, minor changes

This commit is contained in:
Ean Milligan
2026-04-23 16:51:06 -04:00
parent 1f4c4723d3
commit 8126e6dc95
3 changed files with 23 additions and 5 deletions

7
mod.ts
View File

@@ -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.'); if (!(await verify(body.pin, loginMatch[0].hash))) return genericResponse(STATUS_CODE.Forbidden, 'Invalid name/PIN combination.');
const id = loginMatch[0].id; const id = loginMatch[0].id;
const email = loginMatch[0].email; const email = loginMatch[0].email;
const hasEmail = email.length > 0; const hasEmail = (email ?? '').length > 0;
const deleteCode = loginMatch[0].deleteCode; const deleteCode = loginMatch[0].deleteCode;
const deleteCodeSet = (deleteCode ?? '').length > 0;
switch (req.method) { switch (req.method) {
case 'POST': case 'POST':
if (path === '/auth') { 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') { } else if (path === '/create') {
if (body.planName.trim().length > 200) return genericResponse(STATUS_CODE.BadRequest, 'Name too long.'); 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.'); 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, fromAddress: config.email.address,
toAddress: email, toAddress: email,
subject: 'XIVPlan+DB Delete Code', subject: 'XIVPlan+DB Delete Code',
content: `Notice: account deletion is permanent and will delete all plans saved under your account.<br/><br/>Please use the following Delete Code to delete your account:<br/><br/>${newDeleteCode}`, content: `Notice: Account deletion is permanent and will permanently delete all plans saved under your account.<br/><br/>Please use the following Delete Code to delete your account:<br/><br/>${newDeleteCode}`,
}), }),
}).catch(() => { }).catch(() => {
failed = true; failed = true;

View File

@@ -61,6 +61,22 @@ const link=\`${config.api.publicDomain}share#\${planId}\`;
try{await navigator.clipboard.writeText(link);alert('Link copied to clipboard');} 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);} 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);});}});
}
</script> </script>
<p>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.</p> <p>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.</p>
<p>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.</p> <p>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.</p>
@@ -74,5 +90,6 @@ ${plans.map((plan) => makePlanItem(plan, false)).join('')}
<ul> <ul>
${deletedPlans.map((plan) => makePlanItem(plan, true)).join('')} ${deletedPlans.map((plan) => makePlanItem(plan, true)).join('')}
</ul> </ul>
<button onclick="deleteAccount()">Delete my account</button>
</div>`; </div>`;
}; };