mirror of
https://github.com/tlsnotary/tlsn-plugin-demo.git
synced 2026-01-09 21:37:55 -05:00
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
import express from 'express';
|
|
import React from 'react';
|
|
import { renderToString } from 'react-dom/server';
|
|
import { StaticRouter } from 'react-router-dom/server';
|
|
import App from '../web/pages/App';
|
|
import configureAppStore, { AppRootState } from '../web/store';
|
|
import { Provider } from 'react-redux';
|
|
import { Mutex } from 'async-mutex';
|
|
//@ts-ignore
|
|
import { verify } from '../rs/0.1.0-alpha.12/index.node';
|
|
import { convertNotaryWsToHttp, fetchPublicKeyFromNotary } from './util/index';
|
|
import { assignPoapToUser } from './util/index';
|
|
|
|
const app = express();
|
|
const port = 3031;
|
|
|
|
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();
|
|
|
|
app.get('*', (req, res) => {
|
|
try {
|
|
const storeConfig: AppRootState = {
|
|
attestation: {
|
|
raw: {
|
|
version: '0.1.0-alpha.12',
|
|
data: '',
|
|
meta: {
|
|
notaryUrl: '',
|
|
websocketProxyUrl: '',
|
|
pluginUrl: '',
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const store = configureAppStore(storeConfig);
|
|
|
|
const html = renderToString(
|
|
<Provider store={store}>
|
|
<StaticRouter location={req.url}>
|
|
<App />
|
|
</StaticRouter>
|
|
</Provider>,
|
|
);
|
|
|
|
const preloadedState = store.getState();
|
|
|
|
res.send(`
|
|
<!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>
|
|
`);
|
|
} catch (e) {
|
|
res.send(`
|
|
<!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__ = {};
|
|
</script>
|
|
<script defer src="/index.bundle.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<div id="modal-root"></div>
|
|
</body>
|
|
</html>
|
|
`);
|
|
}
|
|
});
|
|
|
|
app.post('/poap-claim', async (req, res) => {
|
|
const { screenName } = req.body;
|
|
if (!screenName) {
|
|
return res.status(400).json({ error: 'Missing screen_name' });
|
|
}
|
|
|
|
try {
|
|
await mutex.runExclusive(async () => {
|
|
const poapLink = await assignPoapToUser(screenName);
|
|
|
|
if (!poapLink) {
|
|
return res.status(404).json({ error: 'No POAPs available' });
|
|
}
|
|
|
|
return res.json({ poapLink });
|
|
});
|
|
} catch (error) {
|
|
console.error('Error claiming POAP:', error);
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
app.post('/verify-attestation', async (req, res) => {
|
|
const { attestation } = req.body;
|
|
if (!attestation) {
|
|
return res.status(400).send('Missing attestation');
|
|
}
|
|
|
|
try {
|
|
const notaryUrl = attestation.meta.notaryUrl;
|
|
const notaryPem = await fetchPublicKeyFromNotary(notaryUrl);
|
|
|
|
const presentation = await verify(attestation.data, notaryPem);
|
|
|
|
const presentationObj = {
|
|
sent: presentation.sent,
|
|
recv: presentation.recv,
|
|
};
|
|
res.json({ presentationObj });
|
|
} catch (e) {
|
|
console.error(e);
|
|
res.status(500).send('Error verifying attestation');
|
|
}
|
|
});
|
|
|
|
app.listen(port, () => {
|
|
console.log(`Plugin demo listening on port ${port}`);
|
|
});
|