-
Notifications
You must be signed in to change notification settings - Fork 394
Expand file tree
/
Copy pathapi-app.ts
More file actions
131 lines (117 loc) · 4.76 KB
/
api-app.ts
File metadata and controls
131 lines (117 loc) · 4.76 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
import compression from 'compression';
import MongoStore from 'connect-mongo';
import express from 'express';
import session from 'express-session';
import onHeaders from 'on-headers';
import * as config from './config';
import { isUserAuthenticated } from './middleware/auth';
import defaultCors from './middleware/cors';
import { appErrorHandler } from './middleware/error';
import routers from './routers/api';
import clickhouseProxyRouter from './routers/api/clickhouseProxy';
import connectionsRouter from './routers/api/connections';
import favoritesRouter from './routers/api/favorites';
import pinnedFiltersRouter from './routers/api/pinnedFilters';
import savedSearchRouter from './routers/api/savedSearch';
import sourcesRouter from './routers/api/sources';
import externalRoutersV2 from './routers/external-api/v2';
import usageStats from './tasks/usageStats';
import logger, { expressLogger } from './utils/logger';
import passport from './utils/passport';
const app: express.Application = express();
const sess: session.SessionOptions & { cookie: session.CookieOptions } = {
// Use a slot-specific cookie name in dev so multiple worktrees on localhost
// don't overwrite each other's session cookies.
...(config.IS_DEV && process.env.HDX_DEV_SLOT
? { name: `connect.sid.${process.env.HDX_DEV_SLOT}` }
: {}),
resave: false,
saveUninitialized: false,
secret: config.EXPRESS_SESSION_SECRET,
cookie: {
secure: false,
sameSite: 'lax',
maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
},
rolling: true,
store: new MongoStore({ mongoUrl: config.MONGO_URI }),
};
app.set('trust proxy', 1);
if (!config.IS_CI && config.FRONTEND_URL) {
const feUrl = new URL(config.FRONTEND_URL);
sess.cookie.domain = feUrl.hostname;
if (feUrl.protocol === 'https:') {
sess.cookie.secure = true;
}
}
app.disable('x-powered-by');
app.use(compression());
app.use(express.json({ limit: '32mb' }));
app.use(express.text({ limit: '32mb' }));
app.use(express.urlencoded({ extended: false, limit: '32mb' }));
app.use(session(sess));
if (!config.IS_LOCAL_APP_MODE) {
app.use(passport.initialize());
app.use(passport.session());
}
if (!config.IS_CI) {
app.use(expressLogger);
}
// Allows timing data from frontend package
// see: https://github.com/expressjs/cors/issues/102
app.use(function (req, res, next) {
onHeaders(res, function () {
const allowOrigin = res.getHeader('Access-Control-Allow-Origin');
if (allowOrigin) {
res.setHeader('Timing-Allow-Origin', allowOrigin);
}
});
next();
});
app.use(defaultCors);
// ---------------------------------------------------------------------
// ----------------------- Background Jobs -----------------------------
// ---------------------------------------------------------------------
if (config.USAGE_STATS_ENABLED) {
usageStats();
}
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// ----------------------- Internal Routers ----------------------------
// ---------------------------------------------------------------------
// PUBLIC ROUTES
app.use('/', routers.rootRouter);
// PRIVATE ROUTES
app.use('/ai', isUserAuthenticated, routers.aiRouter);
app.use('/alerts', isUserAuthenticated, routers.alertsRouter);
app.use('/dashboards', isUserAuthenticated, routers.dashboardRouter);
app.use('/me', isUserAuthenticated, routers.meRouter);
app.use('/team', isUserAuthenticated, routers.teamRouter);
app.use('/webhooks', isUserAuthenticated, routers.webhooksRouter);
app.use('/connections', isUserAuthenticated, connectionsRouter);
app.use('/sources', isUserAuthenticated, sourcesRouter);
app.use('/saved-search', isUserAuthenticated, savedSearchRouter);
app.use('/favorites', isUserAuthenticated, favoritesRouter);
app.use('/pinned-filters', isUserAuthenticated, pinnedFiltersRouter);
app.use('/clickhouse-proxy', isUserAuthenticated, clickhouseProxyRouter);
// ---------------------------------------------------------------------
// TODO: Separate external API routers from internal routers
// ---------------------------------------------------------------------
// ----------------------- External Routers ----------------------------
// ---------------------------------------------------------------------
// API v2
// Only initialize Swagger in development or if explicitly enabled
if (
process.env.NODE_ENV !== 'production' &&
process.env.ENABLE_SWAGGER === 'true'
) {
// Will require a refactor to ESM to use import statements
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { setupSwagger } = require('./utils/swagger');
setupSwagger(app);
logger.info('Swagger UI setup and available at /api/v2/docs');
}
app.use('/api/v2', externalRoutersV2);
// error handling
app.use(appErrorHandler);
export default app;