Skip to content

Commit

Permalink
Merge branch 'main' into AssetCleanUp
Browse files Browse the repository at this point in the history
  • Loading branch information
Gee2563 authored Aug 22, 2024
2 parents d087442 + 4f8b0ed commit 88ebda3
Show file tree
Hide file tree
Showing 27 changed files with 1,496 additions and 212 deletions.
2 changes: 2 additions & 0 deletions API/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const usersRouter = require('./routes/users');
const assetsRouter = require('./routes/assets');
const portfoliosRouter = require('./routes/portfolios');
const portfolioAssetsRouter = require('./routes/portfolioAssets');
const profieImagesRouter = require('./routes/profiles');
const tokenChecker = require('./middleware/tokenChecker');


Expand Down Expand Up @@ -44,6 +45,7 @@ app.use('/users', tokenChecker, usersRouter);
app.use('/assets', tokenChecker, assetsRouter);
app.use('/portfolios',tokenChecker, portfoliosRouter);
app.use('/portfolio_assets', tokenChecker, portfolioAssetsRouter);
app.use('/profiles', profieImagesRouter);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerFile));

// catch 404 and forward to error handler
Expand Down
14 changes: 9 additions & 5 deletions API/controllers/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,31 @@ exports.getUserById = async (req, res) => {
exports.updateUser = async (req, res) => {
try {
const { id } = req.params;
const { name, surname, email, password, gender, birth_date } = req.body;
const { name, surname, email, password, gender, birth_date, terms } = req.body;
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json({ message: '[USERS-007] User not found' });
}
// Making sure the email is unique
const exisingEmail = await User.findOne({ where: {email: email }});
if (exisingEmail) {
res.status(409).json({ message: '[USERS-012] Email already exists', exisingEmail });
};
if (email) {
const exisingEmail = await User.findOne({ where: {email: email }});
if (exisingEmail) {
return res.status(409).json({ message: '[USERS-012] Email already exists', exisingEmail });
};
}
await user.update({
name: name || user.name,
surname: surname || user.surname,
email: email || user.email,
password: password || user.password,
gender: gender || user.gender,
birth_date:birth_date || user.birth_date,
terms_accepted: terms || user.terms,
});
res.status(200).json({ message: '[USERS-008] User updated successfully', user });
} catch (error) {
res.status(500).json({ message: '[USERS-009] Error updating user', error: error.message });
console.log(error);
}
};

Expand Down
83 changes: 83 additions & 0 deletions API/controllers/profileImages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const AWS = require('aws-sdk');
require('dotenv').config();
const multer = require('multer');
const { v4: uuidv4 } = require('uuid');
const User = require('../models/User');
// const upload = multer({ storage: multer.memoryStorage() });


exports.uploadProfileImage = async (req, res) => {
// Set up the S3 client for iDrive E2 (compatible with S3)
const s3 = new AWS.S3({
endpoint: new AWS.Endpoint('https://k2y7.c15.e2-3.dev'),
accessKeyId: process.env.IDRIVE_E2_ACCESS_KEY,
secretAccessKey: process.env.IDRIVE_E2_SECRET_KEY,
region: 'London',
s3ForcePathStyle: true,
});

try {
const { id } = req.params;

// Check if a file is provided
if (!req.file) {
return res.status(400).json({ message: '[USERS-013] No file uploaded' });
}

// Generate a unique filename
const filename = `${uuidv4()}-${req.file.originalname}`;

// Find the user by ID
const user = await User.findByPk(id);
console.log("User: ", user);
if (!user) {
return res.status(404).json({ message: '[USERS-007] User not found' });
}

// Upload the image to S3
const uploadResult = await s3.upload({
Bucket: 'profiles', // E2 bucket name
Key: `images/${filename}`, // Folder within the bucket
Body: req.file.buffer, // The image buffer
ContentType: req.file.mimetype, // Set the content type for the image
ACL: 'public-read', // Make the file publicly accessible
}).promise();

// Store only the image URL in the PostgreSQL database
await user.update({
photo: uploadResult.Location,
});

res.status(200).json({ message: 'Image updated successfully!' });
} catch (error) {
console.error("Error:",error.message);
res.status(500).json({ message: "Can't upload image", error: error.message });
}
};


exports.getProfileImage = async (req, res) => {
try {
const { id } = req.params;

// Find the user by ID
const user = await User.findByPk(id);
if (!user) {
return res.status(404).json({ message: '[USERS-007] User not found' });
}

// Check if the user has a profile image
if (!user.photo) {
return res.status(404).json({ message: '[USERS-014] Profile image not found' });
}

// Respond with the image URL
res.status(200).json({
message: 'Profile image retrieved successfully!',
imageUrl: user.photo, // This is the S3 URL of the image
});
} catch (error) {
console.error(error);
res.status(500).json({ message: "[USERS-015] Can't retrieve profile image", error: error.message });
}
};
18 changes: 16 additions & 2 deletions API/db/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,24 @@ dbConnection();
const syncDatabase = async (force_mode=false) => {
try {
await sequelize.sync({ force: force_mode }); // Use `force: true` to drop and recreate tables; remove it to only create missing tables
console.log("Database synced successfully.");
console.log("[DB-003] Database synced successfully.");
} catch (error) {
console.error("Error syncing database:", error);
console.error("[DB-004] Error syncing database:", error);
}
};

const dropConstraintOnStart = async () => {
try {
await sequelize.query(`
ALTER TABLE portfolio_assets
DROP CONSTRAINT IF EXISTS portfolio_assets_portfolio_id_asset_id_key;
`);
console.log('[DB-005] Constraint dropped successfully.');
} catch (error) {
console.error('[DB-006] Error dropping constraint:', error);
}
};

dropConstraintOnStart();

module.exports = { sequelize, syncDatabase };
10 changes: 8 additions & 2 deletions API/models/PortfolioAssets.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,16 @@ const PortfolioAsset = sequelize.define('PortfolioAsset', {
}, {
tableName: 'portfolio_assets',
timestamps: false,
indexes: [
{
fields: ['portfolio_id', 'asset_id'],
unique: false, // Ensure there is no unique constraint on these fields
},
],
});

Portfolio.belongsToMany(Asset, { through: PortfolioAsset, foreignKey: 'portfolio_id' });
Asset.belongsToMany(Portfolio, { through: PortfolioAsset, foreignKey: 'asset_id' });
Portfolio.belongsToMany(Asset, { through: PortfolioAsset, foreignKey: 'portfolio_id', unique: false });
Asset.belongsToMany(Portfolio, { through: PortfolioAsset, foreignKey: 'asset_id', unique: false });

PortfolioAsset.belongsTo(Portfolio, { foreignKey: 'portfolio_id' });
PortfolioAsset.belongsTo(Asset, { foreignKey: 'asset_id' });
Expand Down
23 changes: 18 additions & 5 deletions API/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,30 @@ const User = sequelize.define('User', {
allowNull: false,
},
photo: {
type: DataTypes.BLOB,
type: DataTypes.TEXT,
},
gender: {
type: DataTypes.STRING(1),
},
birth_date: {
type: DataTypes.DATE,
get() {
const rawDate = this.getDataValue('birth_date');
return rawDate ? rawDate.toISOString().split('T')[0] : null;
},
},
registred_at: {
type: DataTypes.DATE,
allowNull: false,
get() {
const rawDate = this.getDataValue('registred_at');
return rawDate ? rawDate.toISOString().split('T')[0] : null;
},
},
terms_accepted: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
}
}, {
tableName: 'users',
Expand All @@ -48,10 +61,10 @@ const User = sequelize.define('User', {
}
},
beforeUpdate: async (user) => {
if (user.password) {
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
}
if (user.changed('password')) {
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
}
},
}
});
Expand Down
Loading

0 comments on commit 88ebda3

Please sign in to comment.