-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServer.js
More file actions
150 lines (132 loc) · 4.42 KB
/
Server.js
File metadata and controls
150 lines (132 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import dotenv from 'dotenv'; // Load environment variables
import express from 'express'; // Import Express
import { MongoClient } from 'mongodb'; // MongoDB client
import bodyParser from 'body-parser'; // Parse request bodies
import cors from 'cors'; // Handle cross-origin requests
import helmet from 'helmet'; // Secure HTTP headers
import session from 'express-session'; // Manage user sessions
import { generateNonce } from 'siwe'; // Generate nonce for SIWE
import {
verifySignature,
getAddressFromMessage,
getChainIdFromMessage,
} from '@reown/appkit-siwe'; // SIWE utilities
// Load environment variables from .env
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000; // Server port
// MongoDB Configuration
const mongoUri = process.env.MONGO_URI; // Ensure this is set in your .env
const dbName = process.env.MONGO_DB_NAME || 'hyprmtrx'; // Default database name
let db; // Global variable to hold the MongoDB connection
/**
* Middleware Setup
*/
app.use(bodyParser.json()); // Parse JSON request bodies
app.use(cors()); // Enable CORS
app.use(helmet()); // Secure HTTP headers
// Session Middleware for SIWE
app.use(
session({
name: 'siwe-session',
secret: 'siwe-quickstart-secret', // Replace with a strong secret in production
resave: true,
saveUninitialized: true,
cookie: { secure: false, sameSite: true }, // Adjust for your environment
})
);
/**
* Connect to MongoDB.
*/
async function connectToMongoDB() {
try {
const client = new MongoClient(mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await client.connect();
console.log('Connected to MongoDB');
db = client.db(dbName);
} catch (error) {
console.error('Failed to connect to MongoDB:', error);
process.exit(1); // Exit if connection fails
}
}
/**
* Route: Health Check
* Description: Verify if the server is running.
*/
app.get('/', (req, res) => {
res.status(200).send('API is running successfully.');
});
/**
* Route: Get All Users
* Description: Retrieve all users from the database.
*/
app.get('/users', async (req, res) => {
try {
if (!db) {
return res.status(500).json({ error: 'Database connection not established.' });
}
const usersCollection = db.collection('users');
const users = await usersCollection.find({}).toArray();
res.json(users);
} catch (error) {
console.error('Error fetching users:', error);
res.status(500).json({ error: 'Failed to fetch users.' });
}
});
/**
* SIWE Routes
*/
// Route: Generate Nonce
app.get('/nonce', (req, res) => {
res.setHeader('Content-Type', 'text/plain');
res.send(generateNonce());
});
// Route: Verify Signature
app.post('/verify', async (req, res) => {
try {
const { message, signature } = req.body;
if (!message || !signature) {
return res.status(400).json({ error: 'Message or signature is missing.' });
}
const address = getAddressFromMessage(message);
const chainId = getChainIdFromMessage(message);
const isValid = await verifySignature({
address,
message,
signature,
chainId,
projectId: '1b54a5d583ce208cc28c1362cdd3d437', // Replace with your Reown project ID
});
if (!isValid) {
throw new Error('Invalid signature');
}
// Save session
req.session.siwe = { address, chainId };
req.session.save(() => res.status(200).send(true));
} catch (error) {
console.error('Verification error:', error.message);
req.session.siwe = null;
req.session.save(() => res.status(500).json({ message: error.message }));
}
});
// Route: Retrieve Session
app.get('/session', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send(req.session.siwe || null);
});
// Route: Sign Out
app.get('/signout', (req, res) => {
req.session.destroy(() => res.status(200).send(true));
});
/**
* Start the Server
*/
(async () => {
await connectToMongoDB(); // Connect to MongoDB before starting the server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
})();