Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ad1e261a4 | ||
|
|
05442af050 | ||
|
|
25d538504c | ||
|
|
e823533809 | ||
|
|
a03996d54b |
No files matched your search
@@ -83,24 +83,45 @@ class UserService {
|
|||||||
|
|
||||||
loginUser = async (email, password) => {
|
loginUser = async (email, password) => {
|
||||||
// Check if user exists
|
// Check if user exists
|
||||||
const user = await this.db.userModule.getUserByEmail(email);
|
try {
|
||||||
// Compare password
|
const user = await this.db.userModule.getUserByEmail(email);
|
||||||
const match = await user.comparePassword(password);
|
|
||||||
if (match !== true) {
|
// Add null check before password comparison
|
||||||
|
if (!user || !user.comparePassword) {
|
||||||
|
throw this.errorService.createAuthenticationError(this.stringService.authIncorrectPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare password
|
||||||
|
const match = await user.comparePassword(password);
|
||||||
|
if (match !== true) {
|
||||||
|
throw this.errorService.createAuthenticationError(this.stringService.authIncorrectPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove password from user object. Should this be abstracted to DB layer?
|
||||||
|
const userWithoutPassword = { ...user._doc };
|
||||||
|
delete userWithoutPassword.password;
|
||||||
|
delete userWithoutPassword.avatarImage;
|
||||||
|
|
||||||
|
// Happy path, return token
|
||||||
|
const appSettings = await this.settingsService.getSettings();
|
||||||
|
const token = this.issueToken(userWithoutPassword, appSettings);
|
||||||
|
// reset avatar image
|
||||||
|
userWithoutPassword.avatarImage = user.avatarImage;
|
||||||
|
return { user: userWithoutPassword, token };
|
||||||
|
} catch (error) {
|
||||||
|
// Log specific errors while returning generic message for security
|
||||||
|
this.logger.error({
|
||||||
|
message: "Login attempt failed",
|
||||||
|
service: SERVICE_NAME,
|
||||||
|
method: "loginUser",
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
});
|
||||||
|
|
||||||
|
// If user is not found, throw a generic authentication error for security
|
||||||
|
// Don't reveal whether user exists or password is wrong
|
||||||
throw this.errorService.createAuthenticationError(this.stringService.authIncorrectPassword);
|
throw this.errorService.createAuthenticationError(this.stringService.authIncorrectPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove password from user object. Should this be abstracted to DB layer?
|
|
||||||
const userWithoutPassword = { ...user._doc };
|
|
||||||
delete userWithoutPassword.password;
|
|
||||||
delete userWithoutPassword.avatarImage;
|
|
||||||
|
|
||||||
// Happy path, return token
|
|
||||||
const appSettings = await this.settingsService.getSettings();
|
|
||||||
const token = this.issueToken(userWithoutPassword, appSettings);
|
|
||||||
// reset avatar image
|
|
||||||
userWithoutPassword.avatarImage = user.avatarImage;
|
|
||||||
return { user: userWithoutPassword, token };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
editUser = async (updates, file, currentUser) => {
|
editUser = async (updates, file, currentUser) => {
|
||||||
@@ -111,6 +132,12 @@ class UserService {
|
|||||||
updates.email = currentUser.email;
|
updates.email = currentUser.email;
|
||||||
// Get user
|
// Get user
|
||||||
const user = await this.db.userModule.getUserByEmail(currentUser.email);
|
const user = await this.db.userModule.getUserByEmail(currentUser.email);
|
||||||
|
|
||||||
|
// Add null check before password comparison
|
||||||
|
if (!user || !user.comparePassword) {
|
||||||
|
throw this.errorService.createAuthorizationError(this.stringService.authIncorrectPassword);
|
||||||
|
}
|
||||||
|
|
||||||
// Compare passwords
|
// Compare passwords
|
||||||
const match = await user.comparePassword(updates?.password);
|
const match = await user.comparePassword(updates?.password);
|
||||||
// If not a match, throw a 403
|
// If not a match, throw a 403
|
||||||
|
|||||||
@@ -1,21 +1,12 @@
|
|||||||
import sharp from "sharp";
|
|
||||||
/**
|
/**
|
||||||
* Generates a 64 * 64 pixel image from a given image
|
* Converts image to base64 string without resizing
|
||||||
|
* CSS handles the 64x64 display sizing client-side
|
||||||
* @param {} file
|
* @param {} file
|
||||||
*/
|
*/
|
||||||
const GenerateAvatarImage = async (file) => {
|
const GenerateAvatarImage = async (file) => {
|
||||||
try {
|
try {
|
||||||
// Resize to target 64 * 64
|
// Simply convert to base64 - let CSS handle the 64x64 display
|
||||||
let resizedImageBuffer = await sharp(file.buffer)
|
const base64Image = file.buffer.toString("base64");
|
||||||
.resize({
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
fit: "cover",
|
|
||||||
})
|
|
||||||
.toBuffer();
|
|
||||||
|
|
||||||
//Get b64 string
|
|
||||||
const base64Image = resizedImageBuffer.toString("base64");
|
|
||||||
return base64Image;
|
return base64Image;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
Reference in new issue
Block a user