mirror of
https://github.com/tlsnotary/tlsn-plugin-demo.git
synced 2026-01-09 13:28:04 -05:00
153 lines
4.0 KiB
TypeScript
153 lines
4.0 KiB
TypeScript
import express from 'express';
|
|
import { renderToString } from 'react-dom/server';
|
|
import { StaticRouter } from 'react-router-dom/server';
|
|
import App from '../web/pages/App';
|
|
import { Mutex } from 'async-mutex';
|
|
//@ts-ignore
|
|
import { assignPoapToUser } from './util/index';
|
|
import { LRUCache } from 'lru-cache'
|
|
|
|
const app = express();
|
|
const port = 3030;
|
|
|
|
app.use((req, res, next) => {
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader(
|
|
'Access-Control-Allow-Headers',
|
|
'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization',
|
|
);
|
|
res.setHeader(
|
|
'Access-Control-Allow-Methods',
|
|
'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
);
|
|
res.setHeader('Cross-origin-Embedder-Policy', 'require-corp');
|
|
res.setHeader('Cross-origin-Opener-Policy', 'same-origin');
|
|
|
|
if (req.method === 'OPTIONS') {
|
|
res.sendStatus(200);
|
|
} else {
|
|
next();
|
|
}
|
|
});
|
|
|
|
app.use(express.static('build/ui'));
|
|
app.use(express.json());
|
|
const mutex = new Mutex();
|
|
|
|
const sessions = new LRUCache<string, string>({
|
|
max: 10000,
|
|
ttl: 1000 * 60 * 60, // 60 minutes
|
|
});
|
|
|
|
app.post('/update-session', async (req, res) => {
|
|
if (
|
|
req.headers['x-verifier-secret-key'] !== process.env.VERIFIER_SECRET_KEY
|
|
) {
|
|
return res.status(403).json({ error: 'Unauthorized' });
|
|
}
|
|
|
|
console.log('Update session:', req.body);
|
|
|
|
const { screen_name, session_id } = req.body;
|
|
|
|
if (!screen_name || !session_id) {
|
|
return res.status(400).json({ error: 'Missing screen_name or session_id' });
|
|
}
|
|
|
|
sessions.set(session_id, screen_name);
|
|
console.log('Updated session:', session_id, screen_name);
|
|
res.json({ success: true });
|
|
});
|
|
|
|
app.post('/check-session', async (req, res) => {
|
|
const { session_id } = req.body;
|
|
if (!session_id) {
|
|
return res.status(400).json({ error: 'Missing session_id' });
|
|
}
|
|
let screen_name: string | undefined;
|
|
for (let i = 0; i < 5; i++) {
|
|
screen_name = sessions.get(session_id);
|
|
if (screen_name) break;
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
}
|
|
console.log('Check session:', session_id, screen_name);
|
|
if (!screen_name) {
|
|
return res.status(404).json({ error: 'Session not found' });
|
|
}
|
|
res.json({ screen_name });
|
|
});
|
|
|
|
app.post('/poap-claim', async (req, res) => {
|
|
const { sessionId } = req.body;
|
|
const sn = sessions.get(sessionId);
|
|
|
|
console.log('Checking Poap claim:', sessionId, sn);
|
|
|
|
if (!sn) {
|
|
return res.status(400).json({ error: 'Invalid handle or sessionId' });
|
|
}
|
|
|
|
try {
|
|
await mutex.runExclusive(async () => {
|
|
if (process.env.POAP !== 'true') {
|
|
return res.status(404).json({ error: 'No POAPs available in development mode' });
|
|
}
|
|
|
|
const poapLink = await assignPoapToUser(sn);
|
|
|
|
if (!poapLink) {
|
|
return res.status(404).json({ error: 'No POAPs available' });
|
|
}
|
|
|
|
console.log('Serving POAP link:', poapLink);
|
|
|
|
return res.json({ poapLink });
|
|
});
|
|
} catch (error) {
|
|
console.error('Error claiming POAP:', error);
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
function renderHTML(html: string = '', preloadedState: any = {}) {
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
<title>TLSN Plugin Demo</title>
|
|
<script>
|
|
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState)};
|
|
</script>
|
|
<script defer src="/index.bundle.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="root">${html}</div>
|
|
<div id="modal-root"></div>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
|
|
app.get('*', (req, res) => {
|
|
try {
|
|
const html = renderToString(
|
|
<StaticRouter location={req.url}>
|
|
<App />
|
|
</StaticRouter>
|
|
);
|
|
|
|
res.send(renderHTML(html));
|
|
} catch (error) {
|
|
console.error('SSR Error:', error);
|
|
// Send client-only version on SSR error
|
|
res.send(renderHTML());
|
|
}
|
|
});
|
|
|
|
app.listen(port, () => {
|
|
console.log(`Plugin demo listening on port ${port}`);
|
|
});
|