|
|
@ -19,6 +19,7 @@ app.use(cors()); |
|
|
|
const port = process.env.PORT || 3001; |
|
|
|
// file name also referenced in flyway.conf and potentially in .env files or in environment variables
|
|
|
|
const dbFile = process.env.SQLITE_FILE || './image-db.sqlite'; |
|
|
|
const bucketName = process.env.AWS_BUCKET_NAME || 'gifts-image-test'; |
|
|
|
|
|
|
|
const ethrDidResolver = getResolver; |
|
|
|
const resolver = |
|
|
@ -51,6 +52,10 @@ const uploadMulter = multer({ dest: uploadDir + '/' }); |
|
|
|
|
|
|
|
// POST endpoint to upload an image
|
|
|
|
app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
const reqFile = req.file; |
|
|
|
if (reqFile == null) { |
|
|
|
return res.status(400).send(JSON.stringify({ success: false, message: 'No file uploaded.' })); |
|
|
|
} |
|
|
|
|
|
|
|
// Verify the JWT
|
|
|
|
try { |
|
|
@ -62,7 +67,7 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
const verified = await didJwt.verifyJWT(jwt, { resolver }); |
|
|
|
if (!verified.verified) { |
|
|
|
const errorTime = new Date().toISOString(); |
|
|
|
console.log(errorTime, 'Got invalid JWT in Authorization header:', verified); |
|
|
|
console.error(errorTime, 'Got invalid JWT in Authorization header:', verified); |
|
|
|
return res.status(401).send(JSON.stringify({ success: false, message: 'Got invalid JWT in Authorization header. See server logs at ' + errorTime })); |
|
|
|
} |
|
|
|
const issuerDid = verified.issuer; |
|
|
@ -74,7 +79,7 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
[ issuerDid ], |
|
|
|
(dbErr, row) => { |
|
|
|
if (dbErr) { |
|
|
|
console.error('Error getting user record from database:', dbErr) |
|
|
|
console.error('Error getting user record from database (but continuing):', dbErr) |
|
|
|
// may not matter, so continue
|
|
|
|
} |
|
|
|
resolve(row?.per_week); |
|
|
@ -100,7 +105,7 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
[issuerDid, limitPerWeek], |
|
|
|
(dbErr) => { |
|
|
|
if (dbErr) { |
|
|
|
console.error("Error inserting user record for", issuerDid, "into database:", dbErr); |
|
|
|
console.error("Error inserting user record for", issuerDid, "into database (but continuing):", dbErr); |
|
|
|
// we can continue... it just means we'll check the endorser server again next time
|
|
|
|
} |
|
|
|
resolve(); |
|
|
@ -123,7 +128,7 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
[issuerDid, startOfWeekString], |
|
|
|
(dbErr, row) => { |
|
|
|
if (dbErr) { |
|
|
|
console.error(currentDate, "Error counting records for", issuerDid, "into database:", dbErr); |
|
|
|
console.error(currentDate, "Error counting records for", issuerDid, "into database (but continuing):", dbErr); |
|
|
|
// we can continue... it just means we'll check the endorser server again next time
|
|
|
|
} |
|
|
|
resolve(row?.week_count); |
|
|
@ -135,27 +140,20 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
} |
|
|
|
|
|
|
|
// Read the file from the temporary location
|
|
|
|
fs.readFile(req.file.path, async (err, data) => { |
|
|
|
fs.readFile(reqFile.path, async (err, data) => { |
|
|
|
if (err) throw err; // Handle error
|
|
|
|
|
|
|
|
const hashSum = crypto.createHash('sha256'); |
|
|
|
hashSum.update(data); |
|
|
|
const hashHex = hashSum.digest('hex'); |
|
|
|
|
|
|
|
const bucketName = 'gifts-image'; |
|
|
|
const fileName = hashHex; |
|
|
|
const params = { |
|
|
|
Body: data, |
|
|
|
Bucket: bucketName, // S3 Bucket name
|
|
|
|
ContentType: req.file.mimetype, // File content type
|
|
|
|
Key: fileName, // File name to use in S3
|
|
|
|
}; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// record the upload in the database
|
|
|
|
const currentDate = new Date().toISOString(); |
|
|
|
const localFile = req.file.path.startsWith(uploadDir + '/') ? req.file.path.substring(uploadDir.length + 1) : req.file.path; |
|
|
|
const localFile = reqFile.path.startsWith(uploadDir + '/') ? reqFile.path.substring(uploadDir.length + 1) : reqFile.path; |
|
|
|
const finalUrl = `https://${bucketName}.s3.amazonaws.com/${fileName}`; |
|
|
|
await new Promise((resolve, reject) => { |
|
|
|
db.run( |
|
|
@ -164,7 +162,7 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
currentDate, |
|
|
|
issuerDid, |
|
|
|
localFile, |
|
|
|
req.file.size, |
|
|
|
reqFile.size, |
|
|
|
fileName, |
|
|
|
finalUrl |
|
|
|
], |
|
|
@ -180,6 +178,12 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
}); |
|
|
|
|
|
|
|
// send to AWS
|
|
|
|
const params = { |
|
|
|
Body: data, |
|
|
|
Bucket: bucketName, // S3 Bucket name
|
|
|
|
ContentType: reqFile.mimetype, // File content type
|
|
|
|
Key: fileName, // File name to use in S3
|
|
|
|
}; |
|
|
|
const command = new PutObjectCommand(params); |
|
|
|
const response = await s3Client.send(command); |
|
|
|
if (response.$metadata.httpStatusCode !== 200) { |
|
|
@ -190,9 +194,9 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => { |
|
|
|
message: "Got bad status of " + response.$metadata.httpStatusCode + " from AWS. See server logs at " + errorTime |
|
|
|
})); |
|
|
|
} else { |
|
|
|
fs.rm(req.file.path, (err) => { |
|
|
|
fs.rm(reqFile.path, (err) => { |
|
|
|
if (err) { |
|
|
|
console.error("Error deleting temp file", req.file.path, "with error:", err); |
|
|
|
console.error("Error deleting temp file", reqFile.path, "with error (but continuing):", err); |
|
|
|
} |
|
|
|
}); |
|
|
|
res.send(JSON.stringify({success: true, url: finalUrl})); |
|
|
|