Created profile pictures.
Signed-off-by: Armored Dragon <publicmail@armoreddragon.com>feature/profile
parent
f56cfc0e6b
commit
411d108813
|
@ -101,7 +101,7 @@ 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
|
const valid_settings = ["display_name", "password", "role", "profile_image"]; // Valid settings that can be changed
|
||||||
|
|
||||||
let user = await getUser({ user_id: user_id, include_password: true });
|
let user = await getUser({ user_id: user_id, include_password: true });
|
||||||
if (!user.success) return _r(false, "User not found");
|
if (!user.success) return _r(false, "User not found");
|
||||||
|
@ -109,22 +109,35 @@ async function editUser({ requester_id, user_id, user_content }) {
|
||||||
|
|
||||||
// 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
|
const setting_name = user_content.setting_name;
|
||||||
if (!valid_settings.includes(setting_name)) return _r(false, "Invalid setting.");
|
if (!valid_settings.includes(setting_name)) return _r(false, "Invalid setting.");
|
||||||
|
|
||||||
if (setting_name == 'password'){
|
if (setting_name == "password") {
|
||||||
// Check if current password value is correct
|
// Check if current password value is correct
|
||||||
const password_match = await bcrypt.compare(user_content.original_password, user.password);
|
const password_match = await bcrypt.compare(user_content.original_password, user.password);
|
||||||
if (!password_match) return _r(false, "Incorrect password")
|
if (!password_match) return _r(false, "Incorrect password");
|
||||||
|
|
||||||
// If successful, compute new password hash
|
// If successful, compute new password hash
|
||||||
user_content.value = await bcrypt.hash(user_content.value, 10);
|
user_content.value = await bcrypt.hash(user_content.value, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setting_name == "profile_image") {
|
||||||
|
const folder_params = { Bucket: process.env.S3_BUCKET_NAME, Prefix: `${process.env.ENVIRONMENT}/user/${user.id}` };
|
||||||
|
const listed_objects = await s3.send(new ListObjectsCommand(folder_params));
|
||||||
|
|
||||||
|
const all_media = listed_objects.Contents;
|
||||||
|
for (let i = 0; all_media.length > i; i++) {
|
||||||
|
if (all_media[i].Key.includes(user_content.value)) continue;
|
||||||
|
|
||||||
|
// Delete other profile pictures
|
||||||
|
deleteMedia({ parent_id: user.id, parent_type: "user", file_name: all_media[i].Key.split("/")[3] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let formatted = {};
|
let formatted = {};
|
||||||
formatted[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 }) {
|
||||||
|
@ -683,4 +696,4 @@ const _r = (s, m) => {
|
||||||
return { success: s, message: m };
|
return { success: s, message: m };
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { settings, newUser, getUser, editUser, getPost, newPost, editPost, deletePost, getBiography, updateBiography, uploadMedia, getTags, postSetting, getSetting, installTheme, deleteTheme };
|
module.exports = { settings, newUser, getUser, editUser, getPost, newPost, editPost, deletePost, getBiography, updateBiography, uploadMedia, getTags, postSetting, getSetting, installTheme, deleteTheme, getMedia };
|
||||||
|
|
|
@ -46,7 +46,8 @@ async function postSetting(request, response) {
|
||||||
async function postImage(request, response) {
|
async function postImage(request, response) {
|
||||||
// TODO: Permissions for uploading images
|
// TODO: Permissions for uploading images
|
||||||
// TODO: Verification for image uploading
|
// TODO: Verification for image uploading
|
||||||
return response.json(await core.uploadMedia({ parent_id: request.body.post_id, parent_type: request.body.parent_type, file_buffer: request.body.buffer, content_type: request.body.content_type }));
|
// FIXME: Naming
|
||||||
|
return response.json(await core.uploadMedia({ parent_id: request.body.post_id || request.body.parent_id, parent_type: request.body.parent_type, file_buffer: request.body.buffer, content_type: request.body.content_type }));
|
||||||
}
|
}
|
||||||
async function deleteImage(req, res) {
|
async function deleteImage(req, res) {
|
||||||
// TODO: Permissions for deleting image
|
// TODO: Permissions for deleting image
|
||||||
|
|
|
@ -45,14 +45,16 @@ async function login(request, response) {
|
||||||
response.render(_getThemePage("login"), await getDefaults(request));
|
response.render(_getThemePage("login"), await getDefaults(request));
|
||||||
}
|
}
|
||||||
async function author(req, res) {
|
async function author(req, res) {
|
||||||
const user = await core.getUser({ user_id: req.params.author_id });
|
let user = await core.getUser({ user_id: req.params.author_id });
|
||||||
// FIXME: Bandage fix for author get error
|
// FIXME: Bandage fix for author get error
|
||||||
if (!user.success) return res.redirect("/");
|
if (!user.success) return res.redirect("/");
|
||||||
const profile = await core.getBiography({ author_id: user.data.id });
|
user = user.data;
|
||||||
|
const profile = await core.getBiography({ author_id: user.id });
|
||||||
// TODO: Check for success
|
// TODO: Check for success
|
||||||
const posts = await core.getPost({ requester_id: user.data.id });
|
const posts = await core.getPost({ requester_id: user.id });
|
||||||
|
const profile_image = await core.getMedia({ parent_id: user.id, parent_type: "user", file_name: user.profile_image });
|
||||||
|
|
||||||
res.render(_getThemePage("author"), { ...(await getDefaults(req)), post: { ...profile.data, post_count: posts.data.length } });
|
res.render(_getThemePage("author"), { ...(await getDefaults(req)), post: { ...profile.data, post_count: posts.data.length, profile_image: profile_image } });
|
||||||
}
|
}
|
||||||
async function authorEdit(request, response) {
|
async function authorEdit(request, response) {
|
||||||
let author = await core.getBiography({ author_id: request.params.author_id });
|
let author = await core.getBiography({ author_id: request.params.author_id });
|
||||||
|
|
|
@ -1,4 +1,18 @@
|
||||||
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 }], "semi-style": ["error", "last"], } }, pluginJs.configs.recommended];
|
export default [
|
||||||
|
{
|
||||||
|
files: ["**/*.js"],
|
||||||
|
languageOptions: { sourceType: "commonjs" },
|
||||||
|
},
|
||||||
|
{ languageOptions: { globals: globals.browser } },
|
||||||
|
pluginJs.configs.recommended,
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
"no-unused-vars": "error",
|
||||||
|
"semi-style": ["error", "last"],
|
||||||
|
indent: ["error", "tab"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
}
|
}
|
||||||
.page .page-center .about .profile-picture img {
|
.page .page-center .about .profile-picture img {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-height: 200px;
|
height: 200px;
|
||||||
max-width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
.page .page-center .about .displayname {
|
.page .page-center .about .displayname {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
|
|
|
@ -43,8 +43,8 @@
|
||||||
|
|
||||||
img {
|
img {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-height: 200px;
|
height: 200px;
|
||||||
max-width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<%- post.content %>
|
<%- post.content %>
|
||||||
</div>
|
</div>
|
||||||
<div class="about">
|
<div class="about">
|
||||||
<div class="profile-picture"><img src="<%= post.profile_picture %>" /></div>
|
<div class="profile-picture"><img src="<%= post.profile_image || "/img/hourglass.svg" %>" /></div>
|
||||||
<div class="displayname"><%= post.owner.display_name || post.owner.username %></div>
|
<div class="displayname"><%= post.owner.display_name || post.owner.username %></div>
|
||||||
<!-- TODO: Format Date/time -->
|
<!-- TODO: Format Date/time -->
|
||||||
<div class="stat">Registered <%= post.created_date.toLocaleString('en-US', { dateStyle:'medium' }) || "Null" %></div>
|
<div class="stat">Registered <%= post.created_date.toLocaleString('en-US', { dateStyle:'medium' }) || "Null" %></div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
async function changeValue(setting_name, element) {
|
async function changeValue(setting_name, value) {
|
||||||
const form = {
|
const form = {
|
||||||
setting_name: setting_name,
|
setting_name: setting_name,
|
||||||
value: element.value,
|
value: 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);
|
||||||
|
@ -31,7 +31,7 @@ function changePasswordInputUpdate() {
|
||||||
|
|
||||||
async function sendPasswordUpdate() {
|
async function sendPasswordUpdate() {
|
||||||
const new_password_1 = qs("#cp-new-1");
|
const new_password_1 = qs("#cp-new-1");
|
||||||
const original_password_value = qs("#cp-current").value
|
const original_password_value = qs("#cp-current").value;
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
setting_name: "password",
|
setting_name: "password",
|
||||||
|
@ -44,4 +44,39 @@ async function sendPasswordUpdate() {
|
||||||
if (response.body.success) {
|
if (response.body.success) {
|
||||||
alert("Successfully changed password");
|
alert("Successfully changed password");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileInput = qs("#profile_picture");
|
||||||
|
fileInput.addEventListener("change", uploadProfileImage);
|
||||||
|
|
||||||
|
async function uploadProfileImage(event) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
const image_object = {
|
||||||
|
data_blob: new Blob([await file.arrayBuffer()]),
|
||||||
|
content_type: file.type,
|
||||||
|
};
|
||||||
|
|
||||||
|
let form_data = {
|
||||||
|
buffer: await _readFile(image_object.data_blob),
|
||||||
|
content_type: image_object.content_type,
|
||||||
|
parent_id: window.location.href.split("/")[4],
|
||||||
|
parent_type: "user",
|
||||||
|
};
|
||||||
|
|
||||||
|
const image_uploading_request = await request("/api/web/image", "POST", form_data);
|
||||||
|
|
||||||
|
if (image_uploading_request.status == 200) {
|
||||||
|
// Update profile picture link
|
||||||
|
changeValue("profile_image", image_uploading_request.body);
|
||||||
|
// alert(image_uploading_request.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readFile(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ model User {
|
||||||
username String @unique
|
username String @unique
|
||||||
password String
|
password String
|
||||||
display_name String?
|
display_name String?
|
||||||
|
profile_image String?
|
||||||
|
|
||||||
role Role @default(USER)
|
role Role @default(USER)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue