add "image-limits" and "ping" endpoints
This commit is contained in:
190
server.js
190
server.js
@@ -53,6 +53,23 @@ const s3Client = new S3Client({
|
|||||||
const uploadDir = 'uploads';
|
const uploadDir = 'uploads';
|
||||||
const uploadMulter = multer({ dest: uploadDir + '/' });
|
const uploadMulter = multer({ dest: uploadDir + '/' });
|
||||||
|
|
||||||
|
app.get('/ping', async (req, res) => {
|
||||||
|
res.send('pong');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/image-limits', async (req, res) => {
|
||||||
|
limitsResult = await retrievelimits(req, res);
|
||||||
|
if (!limitsResult.success) {
|
||||||
|
return limitsResult.result;
|
||||||
|
}
|
||||||
|
return res.status(200).send(JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
doneImagesThisWeek: limitsResult.doneImagesThisWeek,
|
||||||
|
maxImagesPerWeek: limitsResult.maxImagesPerWeek,
|
||||||
|
nextWeekBeginDateTime: limitsResult.nextWeekBeginDateTime
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
// POST endpoint to upload an image
|
// POST endpoint to upload an image
|
||||||
app.post('/image', uploadMulter.single('image'), async (req, res) => {
|
app.post('/image', uploadMulter.single('image'), async (req, res) => {
|
||||||
const reqFile = req.file;
|
const reqFile = req.file;
|
||||||
@@ -69,78 +86,16 @@ app.post('/image', uploadMulter.single('image'), async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const decoded = await decodeJwt(req, res)
|
limitsResult = await retrievelimits(req, res);
|
||||||
if (!decoded.success) {
|
if (!limitsResult.success) {
|
||||||
return decoded.result;
|
return limitsResult.result;
|
||||||
}
|
}
|
||||||
const issuerDid = decoded.issuerDid;
|
const doneImagesThisWeek = limitsResult.doneImagesThisWeek;
|
||||||
const jwt = decoded.jwt;
|
const maxImagesPerWeek = limitsResult.maxImagesPerWeek;
|
||||||
|
const issuerDid = limitsResult.issuerDid;
|
||||||
|
|
||||||
// Check the user's limits, first from the DB and then from the server
|
if (doneImagesThisWeek >= maxImagesPerWeek) {
|
||||||
let limitPerWeek = await new Promise((resolve, reject) => {
|
return res.status(400).send(JSON.stringify({ success: false, message: 'You have reached your weekly limit of ' + maxImagesPerWeek + ' images.' }));
|
||||||
db.get(
|
|
||||||
'SELECT per_week FROM user WHERE did = ?',
|
|
||||||
[ issuerDid ],
|
|
||||||
(dbErr, row) => {
|
|
||||||
if (dbErr) {
|
|
||||||
console.error('Error getting user record from database (but continuing):', dbErr)
|
|
||||||
// may not matter, so continue
|
|
||||||
}
|
|
||||||
resolve(row?.per_week);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if (limitPerWeek == null) {
|
|
||||||
const headers = {
|
|
||||||
'Authorization': `Bearer ${jwt}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
const response = await fetch(endorserApiUrl + '/api/report/rateLimits', { headers });
|
|
||||||
if (response.status !== 200) {
|
|
||||||
console.error("Got bad response of", response.status, "when checking rate limits for", issuerDid);
|
|
||||||
return res.status(400).send(JSON.stringify({ success: false, message: 'Got bad status of ' + response.status + ' when checking limits with endorser server. Verify that the account exists and that the JWT works for that server.'}));
|
|
||||||
} else {
|
|
||||||
const body = await response.json();
|
|
||||||
limitPerWeek = body.maxClaimsPerWeek / 4; // allowing fewer images than claims
|
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
db.run(
|
|
||||||
'INSERT INTO user (did, per_week) VALUES (?, ?)',
|
|
||||||
[issuerDid, limitPerWeek],
|
|
||||||
(dbErr) => {
|
|
||||||
if (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();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (limitPerWeek == null) {
|
|
||||||
return res.status(400).send(JSON.stringify({ success: false, message: 'Unable to determine rate limits for this user. Verify that the account exists and that the JWT works for that server.' }));
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the user's claims so far this week
|
|
||||||
const startOfWeekDate = DateTime.utc().startOf('week') // luxon weeks start on Mondays
|
|
||||||
const startOfWeekString = startOfWeekDate.toISO()
|
|
||||||
const imagesCount = await new Promise((resolve, reject) => {
|
|
||||||
db.get(
|
|
||||||
'SELECT COUNT(*) AS week_count FROM image WHERE did = ? AND time >= ?',
|
|
||||||
[issuerDid, startOfWeekString],
|
|
||||||
(dbErr, row) => {
|
|
||||||
if (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);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if (imagesCount >= limitPerWeek) {
|
|
||||||
return res.status(400).send(JSON.stringify({ success: false, message: 'You have reached your weekly limit of ' + limitPerWeek + ' images.' }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the file from the temporary location
|
// Read the file from the temporary location
|
||||||
@@ -350,6 +305,96 @@ app.delete('/image/:url', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function retrievelimits(req, res) {
|
||||||
|
const decoded = await decodeJwt(req, res)
|
||||||
|
if (!decoded.success) {
|
||||||
|
return decoded.result;
|
||||||
|
}
|
||||||
|
const issuerDid = decoded.issuerDid;
|
||||||
|
const jwt = decoded.jwt;
|
||||||
|
|
||||||
|
// Check the user's limits, first from the DB and then from the server
|
||||||
|
let maxImagesPerWeek = await new Promise((resolve, reject) => {
|
||||||
|
db.get(
|
||||||
|
'SELECT per_week FROM user WHERE did = ?',
|
||||||
|
[ issuerDid ],
|
||||||
|
(dbErr, row) => {
|
||||||
|
if (dbErr) {
|
||||||
|
console.error('Error getting user record from database (but continuing):', dbErr)
|
||||||
|
// may not matter, so continue
|
||||||
|
}
|
||||||
|
resolve(row?.per_week);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (maxImagesPerWeek == null) {
|
||||||
|
const headers = {
|
||||||
|
'Authorization': `Bearer ${jwt}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
const response = await fetch(endorserApiUrl + '/api/report/rateLimits', { headers });
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.error("Got bad response of", response.status, "when checking rate limits for", issuerDid);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
result: res.status(400).send(JSON.stringify({ success: false, message: 'Got bad status of ' + response.status + ' when checking limits with endorser server. Verify that the account exists and that the JWT works for that server.'}))
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const body = await response.json();
|
||||||
|
maxImagesPerWeek = body.maxClaimsPerWeek / 4; // allowing fewer images than claims
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
db.run(
|
||||||
|
'INSERT INTO user (did, per_week) VALUES (?, ?)',
|
||||||
|
[issuerDid, maxImagesPerWeek],
|
||||||
|
(dbErr) => {
|
||||||
|
if (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();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxImagesPerWeek == null) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
result: res.status(400).send(JSON.stringify({ success: false, message: 'Unable to determine rate limits for this user. Verify that the account exists and that the JWT works for that server.' }))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the user's claims so far this week
|
||||||
|
const startOfWeekDate = DateTime.utc().startOf('week') // luxon weeks start on Mondays
|
||||||
|
const startOfWeekString = startOfWeekDate.toISO()
|
||||||
|
const imagesCount = await new Promise((resolve, reject) => {
|
||||||
|
db.get(
|
||||||
|
'SELECT COUNT(*) AS week_count FROM image WHERE did = ? AND time >= ?',
|
||||||
|
[issuerDid, startOfWeekString],
|
||||||
|
(dbErr, row) => {
|
||||||
|
if (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);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextWeekBeginDateTime = startOfWeekDate.plus({ week: 1 }); // luxon weeks start on Mondays
|
||||||
|
const nextWeekBeginDateTimeString = nextWeekBeginDateTime.toISO()
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
doneImagesThisWeek: imagesCount,
|
||||||
|
maxImagesPerWeek: maxImagesPerWeek,
|
||||||
|
nextWeekBeginDateTime: nextWeekBeginDateTimeString,
|
||||||
|
issuerDid: issuerDid,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve Bearer JWT from Authorization header and return either:
|
* retrieve Bearer JWT from Authorization header and return either:
|
||||||
* { success: true, issuerDid: string, jwt: string }
|
* { success: true, issuerDid: string, jwt: string }
|
||||||
@@ -371,10 +416,7 @@ async function decodeJwt(req, res) {
|
|||||||
console.error(errorTime, 'Got invalid JWT in Authorization header:', verified);
|
console.error(errorTime, 'Got invalid JWT in Authorization header:', verified);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
result: res.status(401).send(JSON.stringify({
|
result: res.status(401).send(JSON.stringify({ success: false, message: 'Got invalid JWT in Authorization header. See server logs at ' + errorTime }))
|
||||||
success: false,
|
|
||||||
message: 'Got invalid JWT in Authorization header. See server logs at ' + errorTime
|
|
||||||
}))
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { success: true, issuerDid: verified.issuer, jwt: jwt };
|
return { success: true, issuerDid: verified.issuer, jwt: jwt };
|
||||||
|
|||||||
Reference in New Issue
Block a user