201 lines
5.2 KiB
JavaScript
201 lines
5.2 KiB
JavaScript
const express = require('express');
|
|
const fs = require('fs');
|
|
const protobuf = require('protobufjs');
|
|
const glob = require('glob');
|
|
const { healthCheck } = require('./bot');
|
|
const app = express();
|
|
const port = 3000;
|
|
|
|
function generateNoteId(length) {
|
|
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
let result = '';
|
|
for (let i = 0; i < length; i++) {
|
|
const randomIndex = Math.floor(Math.random() * characters.length);
|
|
result += characters.charAt(randomIndex);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
let noteList = [];
|
|
let flag = process.env.FLAG;
|
|
if(!flag){
|
|
flag='{"title":"flag","content":"bi0sctf{fake_flag}"}';
|
|
}
|
|
else{
|
|
flag=`{"title":"flag","content":"${flag}"}`;
|
|
}
|
|
const flagid = generateNoteId(16);
|
|
const healthCheckId='Healthcheck';
|
|
fs.writeFileSync(`./notes/${flagid}.json`, flag);
|
|
fs.writeFileSync(`./notes/${healthCheckId}.json`, '{"title":"Healthcheck","content":"success"}');
|
|
|
|
app.use(express.json());
|
|
|
|
app.set('view engine', 'ejs');
|
|
app.set('views', __dirname + '/views');
|
|
|
|
const restrictToLocalhost = (req, res, next) => {
|
|
const remoteAddress = req.connection.remoteAddress;
|
|
if (remoteAddress === '::1' || remoteAddress === '127.0.0.1' || remoteAddress === '::ffff:127.0.0.1') {
|
|
next();
|
|
} else {
|
|
res.status(403).json({ Message: 'Access denied' });
|
|
}
|
|
};
|
|
|
|
const cleanserver = () => {
|
|
Object.keys(require.cache).forEach(i => {
|
|
delete require.cache[i];
|
|
});
|
|
};
|
|
|
|
app.use('/search', restrictToLocalhost);
|
|
|
|
app.get('/delete', (req,res) => {
|
|
cleanserver();
|
|
return res.json({Message: 'Notes deleted successfully!'});
|
|
});
|
|
|
|
app.get('/search/:noteId', (req, res) => {
|
|
const noteId = req.params.noteId;
|
|
const notes=glob.sync(`./notes/${noteId}*`);
|
|
if(notes.length === 0){
|
|
return res.json({Message: "Not found"});
|
|
}
|
|
else{
|
|
try{
|
|
fs.accessSync(`./notes/${noteId}.json`);
|
|
return res.json({Message: "Note found"});
|
|
}
|
|
catch(err){
|
|
return res.status(500).json({ Message: 'Internal server error' });
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
app.get('/customise', (req, res) => {
|
|
return res.render('customise');
|
|
});
|
|
|
|
app.post('/customise',(req, res) => {
|
|
try {
|
|
const { data } = req.body;
|
|
|
|
let author = data.pop()['author'];
|
|
|
|
let title = data.pop()['title'];
|
|
|
|
let protoContents = fs.readFileSync('./settings.proto', 'utf-8').split('\n');
|
|
|
|
if (author) {
|
|
protoContents[5] = ` ${author} string author = 3 [default="user"];`;
|
|
}
|
|
|
|
if (title) {
|
|
protoContents[3] = ` ${title} string title = 1 [default="user"];`;
|
|
}
|
|
|
|
fs.writeFileSync('./settings.proto', protoContents.join('\n'), 'utf-8');
|
|
|
|
return res.json({ Message: 'Settings changed' });
|
|
} catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({ Message: 'Internal server error' });
|
|
}
|
|
})
|
|
|
|
app.get('/create', (req, res) => {
|
|
return res.render('create', { noteList, Message: false });
|
|
});
|
|
|
|
app.post('/create', (req, res) => {
|
|
requestBody=req.body
|
|
try{
|
|
schema = fs.readFileSync('./settings.proto', 'utf-8');
|
|
root = protobuf.parse(schema).root;
|
|
Note = root.lookupType('Note');
|
|
errMsg = Note.verify(requestBody);
|
|
|
|
if (errMsg){
|
|
return res.json({ Message: `Verification failed: ${errMsg}` });
|
|
}
|
|
buffer = Note.encode(Note.create(requestBody)).finish();
|
|
decodedData = Note.decode(buffer).toJSON();
|
|
|
|
const noteId = generateNoteId(16);
|
|
fs.writeFileSync(`./notes/${noteId}.json`, JSON.stringify(decodedData));
|
|
noteList.push(noteId);
|
|
|
|
return res.json({Message: 'Note created successfully!',Noteid: noteId });
|
|
}
|
|
catch (error) {
|
|
console.error(error);
|
|
res.status(500).json({Message: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
|
|
app.get('/view/:noteId', (req, res) => {
|
|
const noteId = req.params.noteId;
|
|
|
|
try {
|
|
let note=require.resolve(`./notes/${noteId}`);
|
|
if(!note.endsWith(".json")){
|
|
return res.status(500).json({ Message: 'Internal Server Error' });
|
|
}
|
|
|
|
let noteData = require(`./notes/${noteId}`);
|
|
for (var key in module.constructor._pathCache) {
|
|
if (key.startsWith("./notes/"+noteId)){
|
|
if (!module.constructor._pathCache[key].endsWith(noteId+".json")){
|
|
if (noteId===healthCheckId){
|
|
cleanserver();
|
|
}
|
|
delete module.constructor._pathCache[key];
|
|
return res.status(500).json({ Message: 'Internal Server Error' });
|
|
}
|
|
}
|
|
}
|
|
if(req.query.temp !== undefined){
|
|
fs.unlink(`./notes/${noteId}.json`, (unlinkError) => {
|
|
if (unlinkError) {
|
|
console.error('File missing');
|
|
}
|
|
noteList=noteList.filter((value)=>value!=noteId);
|
|
});
|
|
}
|
|
return res.render('view', { noteData });
|
|
|
|
} catch (error) {
|
|
console.log(error)
|
|
return res.status(500).json({ Message: 'Internal Server Error' });
|
|
}
|
|
});
|
|
|
|
|
|
app.get('/healthcheck',async(req,res)=>{
|
|
try {
|
|
await healthCheck();
|
|
|
|
return res.json({ Message: 'healthcheck successful' });
|
|
} catch (error) {
|
|
console.error(error);
|
|
return res.json({ Message: 'healthcheck failed' });
|
|
}
|
|
});
|
|
|
|
app.get('/', (req, res) => {
|
|
return res.redirect('/create');
|
|
});
|
|
|
|
|
|
app.use((err, req, res, next) => {
|
|
console.error(err.stack);
|
|
res.status(500).json({ error: 'Internal Server Error' });
|
|
});
|
|
|
|
app.listen(port, () => {
|
|
console.log(`Server running on port ${port}`);
|
|
});
|