feat: Add cache clear api route
This commit is contained in:
@@ -328,6 +328,19 @@ function extractCidFromRecords(records) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear the cache for a specific domain
|
||||
* @param {string} domain - The Handshake domain to clear from cache
|
||||
*/
|
||||
function clearCache(domain) {
|
||||
if (CACHE_ENABLED) {
|
||||
cache.del(`hns:${domain}`);
|
||||
console.log(`Cache cleared for ${domain}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
resolveHandshake
|
||||
resolveHandshake,
|
||||
clearCache
|
||||
};
|
||||
|
||||
30
package.json
30
package.json
@@ -1,35 +1,17 @@
|
||||
{
|
||||
"name": "fireportal",
|
||||
"version": "0.1.0",
|
||||
"description": "An IPFS gateway for Handshake domains",
|
||||
"version": "1.0.0",
|
||||
"description": "IPFS Gateway for Handshake Domains",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon server.js",
|
||||
"test": "jest",
|
||||
"mock": "node tests/mock-resolver.js & node server.js"
|
||||
"dev": "nodemon server.js"
|
||||
},
|
||||
"keywords": [
|
||||
"ipfs",
|
||||
"handshake",
|
||||
"gateway",
|
||||
"hns",
|
||||
"decentralized"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"ipfs-http-client": "^56.0.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"node-cache": "^5.1.2",
|
||||
"cors": "^2.8.5",
|
||||
"morgan": "^1.10.0",
|
||||
"winston": "^3.8.2",
|
||||
"body-parser": "^1.20.2"
|
||||
"express": "^4.17.1",
|
||||
"node-fetch": "^2.6.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^2.0.22",
|
||||
"jest": "^29.5.0"
|
||||
"nodemon": "^2.0.15"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,23 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>IPFS.act</title>
|
||||
<link rel="icon" href="https://woodburn.au/favicon.png" type="image/png">
|
||||
|
||||
<!-- OpenGraph meta tags -->
|
||||
<meta property="og:title" content="IPFS.act">
|
||||
<meta property="og:description" content="Example page stored on IPFS">
|
||||
<meta property="og:image" content="https://ipfs.woodburn.au/og.png">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
</head>
|
||||
<body style="background-color: black; color: blueviolet;text-align: center;">
|
||||
<h1>IPFS.act</h1>
|
||||
<p>This is a demo page running on IPFS.</p>
|
||||
<p>It is designed to showcase the capabilities of IPFS and Handshake domains.</p>
|
||||
|
||||
<img src="https://ipfs.woodburn.au/og.png" alt="Fire Portal" style="max-width: 100%; max-height: 750px;">
|
||||
|
||||
<div style="position: absolute; bottom: 25px; left: 0; width: 100%; text-align: center;">
|
||||
<a href="https://nathan.woodburn.au" style="color: white;">© Nathan.Woodburn/</a>
|
||||
<a href="https://nathan.woodburn.au" style="color: white;" target="_blank">© Nathan.Woodburn/</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -157,6 +157,19 @@
|
||||
<li>Wait a few minutes and you should be able to see your IPFS content on the domain</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="info-section">
|
||||
<h2>API Reference</h2>
|
||||
<p>
|
||||
Fire Portal provides API endpoints to programmatically interact with the service:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Force Refresh:</strong>
|
||||
<code>GET /api/refresh/{domain}</code> - Forces a refresh of IPFS content for a domain
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
|
||||
41
server.js
41
server.js
@@ -3,7 +3,7 @@ const express = require('express');
|
||||
const morgan = require('morgan');
|
||||
const cors = require('cors');
|
||||
const path = require('path');
|
||||
const { resolveHandshake } = require('./lib/handshake');
|
||||
const { resolveHandshake, clearCache } = require('./lib/handshake');
|
||||
const { fetchFromIpfs } = require('./lib/ipfs');
|
||||
const { PORT } = require('./config');
|
||||
|
||||
@@ -234,6 +234,45 @@ app.get('/hns/:domain', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// API route to force refresh IPFS content
|
||||
app.get('/api/refresh/:domain', async (req, res) => {
|
||||
try {
|
||||
const domain = req.params.domain;
|
||||
|
||||
// Validate domain name format
|
||||
if (!domain.match(/^[a-z0-9-_]+(\.[a-z0-9-_]+)*\/?$/i)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Invalid domain format'
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Refreshing content for domain: ${domain}`);
|
||||
// Clear cache for the domain
|
||||
clearCache(domain);
|
||||
|
||||
|
||||
// Return success response
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Refresh initiated for ${domain}`,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Refresh error:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Server error during refresh operation'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Catch-all route to handle SPA navigation
|
||||
app.get('*', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Fire Portal server running on port ${PORT}`);
|
||||
|
||||
Reference in New Issue
Block a user