mirror of
https://github.com/MrUnknownDE/unknownbin.git
synced 2026-04-06 00:32:08 +02:00
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// A simple key regex to prevent path traversal
|
|
const validKeyRegex = /^[a-zA-Z0-9]+$/;
|
|
|
|
// handles saving and retrieving all documents
|
|
class FileDocumentStore {
|
|
constructor(options) {
|
|
this.basePath = options.path || './data';
|
|
this.logger = options.logger;
|
|
this.logger.info('Path to data: ' + this.basePath);
|
|
// Create directory if it does not exist
|
|
if (!fs.existsSync(this.basePath)) {
|
|
fs.mkdirSync(this.basePath, { recursive: true, mode: '700' });
|
|
}
|
|
}
|
|
|
|
// saves a new file to the filesystem
|
|
set(key, data, callback) {
|
|
if (!validKeyRegex.test(key)) {
|
|
this.logger.warn(`Invalid key provided for set: ${key}`);
|
|
return callback(false);
|
|
}
|
|
|
|
const resolvedBasePath = path.resolve(this.basePath);
|
|
const filePath = path.resolve(resolvedBasePath, key);
|
|
|
|
// Security check to ensure we are not writing outside of the data directory
|
|
if (path.dirname(filePath) !== resolvedBasePath) {
|
|
this.logger.error(`Path traversal attempt detected for key: ${key}`);
|
|
return callback(false);
|
|
}
|
|
|
|
fs.writeFile(filePath, data, 'utf8', (err) => {
|
|
if (err) {
|
|
this.logger.error('Error writing file:', err);
|
|
callback(false);
|
|
} else {
|
|
callback(true);
|
|
}
|
|
});
|
|
}
|
|
|
|
// gets an existing file from the filesystem
|
|
get(key, callback) {
|
|
if (!validKeyRegex.test(key)) {
|
|
this.logger.warn(`Invalid key provided for get: ${key}`);
|
|
return callback(false);
|
|
}
|
|
|
|
const resolvedBasePath = path.resolve(this.basePath);
|
|
const filePath = path.resolve(resolvedBasePath, key);
|
|
|
|
// Security check to ensure we are not reading outside of the data directory
|
|
if (path.dirname(filePath) !== resolvedBasePath) {
|
|
this.logger.error(`Path traversal attempt detected for key: ${key}`);
|
|
return callback(false);
|
|
}
|
|
|
|
fs.readFile(filePath, 'utf8', (err, data) => {
|
|
if (err) {
|
|
// Don't log error if file just doesn't exist
|
|
if (err.code !== 'ENOENT') {
|
|
this.logger.error('Error reading file:', err);
|
|
}
|
|
callback(false);
|
|
} else {
|
|
callback(data);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = FileDocumentStore; |