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
|
||||
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 });
|
||||
if (!user.success) return _r(false, "User not found");
|
||||
|
@ -109,22 +109,35 @@ async function editUser({ requester_id, user_id, user_content }) {
|
|||
|
||||
// TODO:
|
||||
// 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 (setting_name == 'password'){
|
||||
if (setting_name == "password") {
|
||||
// Check if current password value is correct
|
||||
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
|
||||
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 = {};
|
||||
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);
|
||||
}
|
||||
async function deleteUser({ user_id }) {
|
||||
|
@ -683,4 +696,4 @@ const _r = (s, 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) {
|
||||
// TODO: Permissions for uploading images
|
||||
// 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) {
|
||||
// TODO: Permissions for deleting image
|
||||
|
|
|
@ -45,14 +45,16 @@ async function login(request, response) {
|
|||
response.render(_getThemePage("login"), await getDefaults(request));
|
||||
}
|
||||
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
|
||||
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
|
||||
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) {
|
||||
let author = await core.getBiography({ author_id: request.params.author_id });
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
import globals from "globals";
|
||||
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 {
|
||||
margin: auto;
|
||||
max-height: 200px;
|
||||
max-width: 200px;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
.page .page-center .about .displayname {
|
||||
font-size: 1.4rem;
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
|
||||
img {
|
||||
margin: auto;
|
||||
max-height: 200px;
|
||||
max-width: 200px;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<%- post.content %>
|
||||
</div>
|
||||
<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>
|
||||
<!-- TODO: Format Date/time -->
|
||||
<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 = {
|
||||
setting_name: setting_name,
|
||||
value: element.value,
|
||||
value: value,
|
||||
id: window.location.href.split("/")[4],
|
||||
};
|
||||
const response = await request(`/api/web/user`, "PATCH", form);
|
||||
|
@ -31,7 +31,7 @@ function changePasswordInputUpdate() {
|
|||
|
||||
async function sendPasswordUpdate() {
|
||||
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 = {
|
||||
setting_name: "password",
|
||||
|
@ -45,3 +45,38 @@ async function sendPasswordUpdate() {
|
|||
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
|
||||
password String
|
||||
display_name String?
|
||||
profile_image String?
|
||||
|
||||
role Role @default(USER)
|
||||
|
||||
|
|
Loading…
Reference in New Issue