Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 40 additions & 28 deletions lensmint-public-server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let servicesInitialized = false;
async function initializeServices() {
try {
console.log('🔄 Initializing claim server services...');

dbService.initialize();
console.log('✅ Database initialized');

Expand All @@ -61,11 +61,23 @@ async function initializeServices() {

initializeServices();

// Utility function to escape HTML characters and prevent XSS
const escapeHtml = (unsafe) => {
if (typeof unsafe !== 'string') return unsafe;
return unsafe
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
};

// Middleware to protect internal API routes
app.post('/create-claim', (req, res) => {
try {
const {
claim_id,
cid,
const {
claim_id,
cid,
metadata_cid,
device_id,
camera_id,
Expand All @@ -82,9 +94,9 @@ app.post('/create-claim', (req, res) => {
}

const claim = dbService.createClaim(
claim_id,
null,
cid,
claim_id,
null,
cid,
metadata_cid || null,
device_id || null,
camera_id || null,
Expand Down Expand Up @@ -206,11 +218,11 @@ app.get('/api/metadata/:claim_id', (req, res) => {

app.post('/update-proof-status', (req, res) => {
try {
const {
claim_id,
token_id,
verification_status,
proof_tx_hash
const {
claim_id,
token_id,
verification_status,
proof_tx_hash
} = req.body;

if (!claim_id) {
Expand Down Expand Up @@ -243,9 +255,9 @@ app.post('/update-proof-status', (req, res) => {
app.get('/verify/:claim_id', async (req, res) => {
try {
const { claim_id } = req.params;

const claim = dbService.getClaim(claim_id);

if (!claim) {
return res.status(404).send(`
<!DOCTYPE html>
Expand All @@ -260,7 +272,7 @@ app.get('/verify/:claim_id', async (req, res) => {
</head>
<body>
<h1 class="error">Claim Not Found</h1>
<p>The claim ID "${claim_id}" does not exist.</p>
<p>The claim ID "${escapeHtml(claim_id)}" does not exist.</p>
</body>
</html>
`);
Expand Down Expand Up @@ -294,7 +306,7 @@ app.get('/verify/:claim_id', async (req, res) => {
};

let proofData = dbService.getProof(claim_id);

if (proofData) {
console.log(`[VERIFY] Found proof in local DB: status=${proofData.verification_status}, tx=${proofData.proof_tx_hash || 'none'}`);
} else {
Expand Down Expand Up @@ -346,7 +358,7 @@ app.get('/verify/:claim_id', async (req, res) => {
<body>
<div class="container">
<h1>🔐 ZK Proof Verification</h1>
<p class="subtitle">Claim ID: ${claim_id}</p>
<p class="subtitle">Claim ID: ${escapeHtml(claim_id)}</p>

<div class="grid">
<div class="card">
Expand Down Expand Up @@ -428,8 +440,8 @@ app.get('/verify/:claim_id', async (req, res) => {
</div>

<div style="margin-top: 30px; text-align: center;">
<a href="/claim/${claim_id}" class="btn">View Claim Page</a>
<a href="/api/metadata/${claim_id}" class="btn" style="margin-left: 10px;">View Metadata API</a>
<a href="/claim/${escapeHtml(claim_id)}" class="btn">View Claim Page</a>
<a href="/api/metadata/${escapeHtml(claim_id)}" class="btn" style="margin-left: 10px;">View Metadata API</a>
</div>
</div>
</body>
Expand Down Expand Up @@ -507,7 +519,7 @@ app.get('/claim/:claim_id', (req, res) => {
</head>
<body>
<h1 class="error">Claim Not Found</h1>
<p>The claim ID "${claim_id}" does not exist.</p>
<p>The claim ID "${escapeHtml(claim_id)}" does not exist.</p>
</body>
</html>
`);
Expand Down Expand Up @@ -759,10 +771,10 @@ app.get('/claim/:claim_id', (req, res) => {
` : ''}

<div id="status" class="status ${claim.status}">
${claim.status === 'open' ? `Status: Open - Ready for editions! Original Token ID: ${claim.token_id || 'N/A'}` :
claim.status === 'claimed' ? `Status: Claimed - Address: ${claim.recipient_address}` :
claim.status === 'completed' ? 'Status: Completed - NFT Minted! 🎉' :
'Status: Pending - Waiting for original NFT to be minted...'}
${claim.status === 'open' ? `Status: Open - Ready for editions! Original Token ID: ${claim.token_id || 'N/A'}` :
claim.status === 'claimed' ? `Status: Claimed - Address: ${claim.recipient_address}` :
claim.status === 'completed' ? 'Status: Completed - NFT Minted! 🎉' :
'Status: Pending - Waiting for original NFT to be minted...'}
</div>

<form id="claimForm" ${claim.status === 'open' ? '' : 'style="display:none;"'}>
Expand All @@ -781,17 +793,17 @@ app.get('/claim/:claim_id', (req, res) => {
</form>

<div id="message"></div>
<div class="claim-id">Claim ID: ${claim_id}</div>
<div class="claim-id">Claim ID: ${escapeHtml(claim_id)}</div>

<div style="margin-top: 20px; text-align: center; padding-top: 20px; border-top: 1px solid #e0e0e0;">
<a href="/verify/${claim_id}" class="proof-link">
<a href="/verify/${escapeHtml(claim_id)}" class="proof-link">
🔐 Check ZK Proof Verification
</a>
</div>
</div>

<script>
const claimId = '${claim_id}';
const claimId = '${escapeHtml(claim_id)}';
const form = document.getElementById('claimForm');
const submitBtn = document.getElementById('submitBtn');
const messageDiv = document.getElementById('message');
Expand Down Expand Up @@ -1161,7 +1173,7 @@ app.get('/health', (req, res) => {

app.listen(PORT, async () => {
await initializeServices();

console.log('═══════════════════════════════════════');
console.log('🎫 LensMint Claim Server');
console.log('═══════════════════════════════════════');
Expand Down