Password changing

Signed-off-by: Armored Dragon <publicmail@armoreddragon.com>
feature/profile
Armored Dragon 2024-07-09 14:15:44 -05:00
parent e39fce5f40
commit 299c1de74e
Signed by: ArmoredDragon
GPG Key ID: C7207ACC3382AD8B
7 changed files with 180 additions and 77 deletions

View File

@ -7,6 +7,7 @@ let s3;
const crypto = require("crypto"); const crypto = require("crypto");
const validate = require("../form_validation"); const validate = require("../form_validation");
const permissions = require("../permissions"); const permissions = require("../permissions");
const bcrypt = require("bcrypt");
const md = require("markdown-it")() const md = require("markdown-it")()
.use(require("markdown-it-underline")) .use(require("markdown-it-underline"))
.use(require("markdown-it-footnote")) .use(require("markdown-it-footnote"))
@ -100,23 +101,25 @@ async function getUser({ user_id, username, include_password = false }) {
} }
// TODO: Rename patchUser // TODO: Rename patchUser
async function editUser({ requester_id, user_id, user_content }) { async function editUser({ requester_id, user_id, user_content }) {
const valid_settings = ['display_name', 'password', 'role']; // Valid settings that can be changed
let user = await getUser({ user_id: user_id }); let user = await getUser({ user_id: user_id });
if (!user.success) return _r(false, "User not found"); if (!user.success) return _r(false, "User not found");
user = user.data; user = user.data;
// TODO: // TODO:
// If there was a role change, see if the acting user can make these changes // If there was a role change, see if the acting user can make these changes
const setting_name = user_content.setting_name
if (!valid_settings.includes(setting_name)) return _r(false, "Invalid setting.");
// TODO: if (setting_name == 'password'){
// If there was a password change, user_content.value = await bcrypt.hash(user_content.value, 10);
// check to see if the user can make these changes }
// Hash the password
// FIXME: Not secure. ASAP!
let formatted = {}; let formatted = {};
formatted[user_content.setting_name] = user_content.value; formatted[setting_name] = user_content.value;
await prisma.user.update({ where: { id: user.id }, data: formatted }); await prisma.user.update({ where: { id: user.id }, data: formatted })
return _r(true); return _r(true);
} }
async function deleteUser({ user_id }) { async function deleteUser({ user_id }) {

View File

@ -1,4 +1,4 @@
import globals from "globals"; import globals from "globals";
import pluginJs from "@eslint/js"; import pluginJs from "@eslint/js";
export default [{ files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } }, { languageOptions: { globals: globals.browser } }, { rules: { "no-unused-vars": "error", "no-undef": "error", indent: ["error", "tab", { tabWidth: 4 }] } }, pluginJs.configs.recommended]; export default [{ files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } }, { languageOptions: { globals: globals.browser } }, { rules: { "no-unused-vars": "error", "no-undef": "error", "indent": ["error", "tab", { tabWidth: 4 }], "semi-style": ["error", "last"], } }, pluginJs.configs.recommended];

View File

@ -159,4 +159,42 @@ input:checked + .slider:before {
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
}
dialog {
border-radius: 5px;
border: 0;
min-width: 300px;
}
dialog .title {
font-size: 1.1rem;
text-align: center;
margin-bottom: 1rem;
}
dialog .entry {
width: 100%;
margin-bottom: 0.5rem;
}
dialog .entry input {
width: 100%;
margin: 0;
box-sizing: border-box;
font-size: 1.1rem;
}
dialog .status {
margin-bottom: 1rem;
color: red;
text-align: center;
}
dialog .horizontal-button-container {
display: flex;
flex-direction: row;
}
dialog .horizontal-button-container * {
flex-grow: 1;
margin: 0 0.1rem;
}
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
} }

View File

@ -171,3 +171,44 @@ input:checked + .slider:before {
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
} }
dialog {
border-radius: 5px;
border: 0;
min-width: 300px;
.title {
font-size: 1.1rem;
text-align: center;
margin-bottom: 1rem;
}
.entry {
width: 100%;
margin-bottom: 0.5rem;
input {
width: 100%;
margin: 0;
box-sizing: border-box;
font-size: 1.1rem;
}
}
.status {
margin-bottom: 1rem;
color: red;
text-align: center;
}
.horizontal-button-container {
display: flex;
flex-direction: row;
* {
flex-grow: 1;
margin: 0 0.1rem;
}
}
}
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}

View File

@ -8,6 +8,29 @@
<title>Yet-Another-Blog</title> <title>Yet-Another-Blog</title>
</head> </head>
<body> <body>
<dialog id="change-password-dialog">
<div class="title">
<span>Change Password</span>
</div>
<div class="entry">
<div>Current password</div>
<input id="cp-current" type="password" oninput="changePasswordInputUpdate()" />
</div>
<div class="entry">
<div>New password</div>
<input id="cp-new-1" type="password" oninput="changePasswordInputUpdate()" />
</div>
<div class="entry">
<div>Confirm password</div>
<input id="cp-new-2" type="password" oninput="changePasswordInputUpdate()" />
</div>
<div class="status">Please enter your current password.</div>
<div class="horizontal-button-container">
<button class="button good" onclick="sendPasswordUpdate()">Accept</button>
<button id="cp-cancel" class="button bad">Cancel</button>
</div>
</dialog>
<%- include("partials/header.ejs") %> <%- include("partials/header.ejs") %>
<div class="page"> <div class="page">
<div class="page-center"> <div class="page-center">
@ -21,7 +44,7 @@
</div> </div>
<div class="setting"> <div class="setting">
<div class="title">Change Password</div> <div class="title">Change Password</div>
<button class="button bad"><span>Open Dialog</span></button> <button id="change-password-button" class="button bad"><span>Open Dialog</span></button>
</div> </div>
<div class="setting"> <div class="setting">
<div class="title">Change Profile Picture</div> <div class="title">Change Profile Picture</div>

View File

@ -1,12 +1,37 @@
async function changeValue(setting_name, element) { async function changeValue(setting_name, element) {
const form = { const form = {
setting_name: setting_name, setting_name: setting_name,
value: element.value, value: element.value,
id: window.location.href.split("/")[4], id: window.location.href.split("/")[4],
}; };
const response = await request(`/api/web/user`, "PATCH", form); const response = await request(`/api/web/user`, "PATCH", form);
// TODO: On failure, notify the user // TODO: On failure, notify the user
if (response.body.success) { if (response.body.success) {
} alert("Successfully changed password");
}
} }
const change_password_dialog = qs("#change-password-dialog");
qs("#change-password-button").addEventListener("click", () => change_password_dialog.showModal());
qs("#cp-cancel").addEventListener("click", () => change_password_dialog.close());
function changePasswordInputUpdate() {
const status = qs("#change-password-dialog .status");
const current_password = qs("#cp-current");
const new_password_1 = qs("#cp-new-1");
const new_password_2 = qs("#cp-new-2");
if (current_password.value === "") return (status.innerText = "Please enter your current password.");
if (new_password_1.value !== new_password_2.value) return (status.innerText = "New password does not match.");
return (status.innerHTML = "&nbsp;");
}
function sendPasswordUpdate() {
const new_password_1 = qs("#cp-new-1");
// Check fields match
// Send post update
changeValue("password", new_password_1);
}

91
package-lock.json generated
View File

@ -2112,12 +2112,13 @@
} }
}, },
"node_modules/braces": { "node_modules/braces": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.1.1"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@ -2350,9 +2351,10 @@
} }
}, },
"node_modules/cookie": { "node_modules/cookie": {
"version": "0.5.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"license": "MIT",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@ -2480,9 +2482,10 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
}, },
"node_modules/ejs": { "node_modules/ejs": {
"version": "3.1.9", "version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"jake": "^10.8.5" "jake": "^10.8.5"
}, },
@ -2744,16 +2747,17 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.18.2", "version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"license": "MIT",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
"body-parser": "1.20.1", "body-parser": "1.20.2",
"content-disposition": "0.5.4", "content-disposition": "0.5.4",
"content-type": "~1.0.4", "content-type": "~1.0.4",
"cookie": "0.5.0", "cookie": "0.6.0",
"cookie-signature": "1.0.6", "cookie-signature": "1.0.6",
"debug": "2.6.9", "debug": "2.6.9",
"depd": "2.0.0", "depd": "2.0.0",
@ -2823,33 +2827,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}, },
"node_modules/express/node_modules/body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/express/node_modules/debug": { "node_modules/express/node_modules/debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": { "dependencies": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -2857,21 +2839,8 @@
"node_modules/express/node_modules/ms": { "node_modules/express/node_modules/ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
}, "license": "MIT"
"node_modules/express/node_modules/raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
}, },
"node_modules/fast-deep-equal": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
@ -2982,10 +2951,11 @@
} }
}, },
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
}, },
@ -3456,6 +3426,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=0.12.0" "node": ">=0.12.0"
} }
@ -4729,9 +4700,10 @@
} }
}, },
"node_modules/tar": { "node_modules/tar": {
"version": "6.2.0", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
"integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"license": "ISC",
"dependencies": { "dependencies": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
"fs-minipass": "^2.0.0", "fs-minipass": "^2.0.0",
@ -4787,6 +4759,7 @@
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"is-number": "^7.0.0" "is-number": "^7.0.0"
}, },