-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
143 lines (126 loc) · 3.64 KB
/
server.js
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
// Server-Side Entry Point For The Tarpaulin API
// ---------------------------------------------
// Imports
import express from "express";
import mongoose from "mongoose";
import dotenev from "dotenv";
import morgan from "morgan";
import cors from "cors";
import RedisStore from "rate-limit-redis";
import rateLimit from "express-rate-limit";
import redis from "redis";
import { rateLimitM } from "./lib/auth.js";
import api from "./api/index.js";
// Config
dotenev.config({
path: "./.env.local",
});
// Express App
const app = express();
// Environment Variables
const port = process.env.PORT || 8000;
const env = process.env.NODE_ENV || "development";
const mongoHost = process.env.MONGO_HOST || "localhost";
const mongoPort = process.env.MONGO_PORT || 27017;
const mongoDatabase = process.env.MONGO_DBNAME || "tarpaulin";
const mongoUser = process.env.MONGO_USER || "admin";
const mongoPassword = process.env.MONGO_PASS || "admin";
const mongoConnectionString = `mongodb://${mongoUser}:${mongoPassword}@${mongoHost}:${mongoPort}/${mongoDatabase}`;
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
})
// Rate Limiting
export const limiterUnauthenticated = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 10, // for requests made without a valid authentication token, the API permits 10 requests per minute
standardHeaders: true,
message: "Unauthenticated requests are limited to 10 per minute.",
store: new RedisStore({
sendCommand: (...args) => {
return client.sendCommand(...args);
}
})
});
export const limiterAuthenticated = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 30, // for requests made with a valid authentication token, the API permits 30 requests per minute
standardHeaders: true,
message: "Authenticated requests are limited to 30 per minute.",
store: new RedisStore({
sendCommand: (...args) => {
return client.sendCommand(...args);
}
})
});
// Redis
async function connectToRedis() {
try {
await redisClient.connect();
console.log("[⚡️ REDIS] Connected to RedisClient")
} catch (err) {
console.log("Redis error: ", err);
}
}
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(morgan("dev"));
app.use(cors())
// app.use(rateLimitM)
// API
app.use("/api", api);
// Test Route
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.use('*', function (req, res, next) {
res.status(404).send({
err: "This URL was not recognized: " + req.originalUrl
})
})
// Database Connection
mongoose
.connect(mongoConnectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log(`[⚡️ DATABASE] Connected to MongoDB`);
})
.catch((err) => {
console.log(`[❌ DATABASE] Error: ${err}`);
})
.finally(() => {
// Start Server
app.listen(port, () => {
console.log(`[⚡️ SERVER] Server is running on port ${port}`);
});
});
// Redis Connection
connectToRedis()
.then(() => {
console.log(`[⚡️ REDIS DOCKER] Redis is running on port ${process.env.REDIS_PORT}`);
})
.catch((err) => {
console.log("Error connecting to Redis: ", err);
});
/*
* This route will catch any errors thrown from our API endpoints and return
* a response with a 500 status to the client.
*/
app.use("*", function (err, req, res, next) {
if (err) {
console.error(err);
res.status(500).send({
err: err,
});
} else {
next();
}
});
app.use("*", function (req, res, next) {
res.status(404).json({
error: "Requested resource " + req.originalUrl + " does not exist",
});
});