utility-api/index.js
sairaj mote 39bcec9fb2 Bug fix
2023-12-06 20:27:17 +05:30

144 lines
4.6 KiB
JavaScript

require('dotenv').config();
const express = require('express');
const https = require('https');
const fs = require('fs');
const axios = require('axios');
const { createHash } = require('crypto');
const archiver = require('archiver');
const rateLimit = require('express-rate-limit');
const app = express();
const port = process.env.PORT || 3000;
// Middleware to parse JSON requests
app.use(express.json());
// Set up the allowed domains (replace with your specific domains)
const allowedDomains = process.env.ALLOWED_DOMAINS.split(',');
// Middleware to allow requests only from specified domains
app.use((req, res, next) => {
const { origin } = req.headers;
// Check if the requesting origin is in the allowedDomains array
if (allowedDomains.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
// Other headers for handling preflight requests and allowing credentials if needed
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', 'true');
// Continue to the next middleware or route handler
next();
});
app.use(
rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 1, // limit each IP to 1 request per windowMs
})
);
// hashContent function to hash the content of a file
async function hashContent(content) {
const hash = createHash('sha256');
hash.update(content);
return hash.digest('hex');
}
// API endpoint to start the recursive download and hashing
app.post('/hash', async (req, res) => {
try {
console.log('Request:', req.body);
let { url } = req.body;
if (!url) {
return res.status(400).json({ error: 'Missing URL in the request parameters' });
}
if (!Array.isArray(url))
url = [url];
const promises = url.map(async (url) => {
const response = await axios.get(url, { responseType: 'arraybuffer', timeout: 10000 });
const fileHash = await hashContent(response.data);
return { url, fileHash };
})
let results = await Promise.all(promises);
results = results.reduce((acc, { url, fileHash }) => {
acc[url] = fileHash;
return acc;
}, {});
res.json(results);
} catch (error) {
console.error('Error:', error.message);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// Function to download a GitHub repo as a zip file
async function downloadGitHubRepo(owner, repo) {
if (!owner || !repo) {
throw new Error('Missing owner or repo');
}
const zipUrl = `https://github.com/${owner}/${repo}/archive/refs/heads/master.zip`;
const response = await axios.get(zipUrl, { responseType: 'arraybuffer' });
return response.data;
}
// Endpoint to download and zip GitHub repositories
app.post('/download-repos', async (req, res) => {
try {
let { urls } = req.body;
if (!urls) {
return res.status(400).json({ error: 'Missing urls in the request parameters' });
}
if (!Array.isArray(urls)) {
urls = [urls];
}
const archive = archiver('zip');
res.attachment('repos.zip');
// Create an array of promises for each repository download
const downloadPromises = urls.map(async (url) => {
const [owner, name] = url.split('/').slice(-2);
if (!owner || !name) {
console.error(`Invalid url format: ${url}`);
return;
}
const zipBuffer = await downloadGitHubRepo(owner, name);
// Add the zip file to the archiver
archive.append(zipBuffer, { name: `${owner}-${name}.zip` });
});
// Wait for all promises to complete
await Promise.all(downloadPromises);
// Finalize the zip file
archive.finalize();
// Pipe the zip file to the response
archive.pipe(res);
} catch (error) {
console.error('Error:', error.message);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// HTTPS options (provide the paths to your SSL/TLS certificate and private key)
const httpsOptions = {
key: fs.readFileSync('./server-key.pem'),
cert: fs.readFileSync('./server-cert.pem'),
};
// Create HTTPS server
const server = https.createServer(httpsOptions, app);
// Start the server
server.listen(port, () => {
console.log(`Server is running at https://localhost:${port}`);
});
// Export the Express API
module.exports = app