-
Notifications
You must be signed in to change notification settings - Fork 373
Expand file tree
/
Copy pathauth.ts
More file actions
149 lines (129 loc) · 3.65 KB
/
auth.ts
File metadata and controls
149 lines (129 loc) · 3.65 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
import { Connection } from '@hyperdx/common-utils/dist/types';
import { setTraceAttributes } from '@hyperdx/node-opentelemetry';
import type { NextFunction, Request, Response } from 'express';
import { serializeError } from 'serialize-error';
import * as config from '@/config';
import { getAnonymousUser } from '@/controllers/team';
import { findUserByAccessKey } from '@/controllers/user';
import type { UserDocument } from '@/models/user';
import logger from '@/utils/logger';
declare global {
namespace Express {
interface User extends UserDocument {}
}
namespace Express {
interface Request {
_hdx_connection?: Connection;
}
}
}
declare module 'express-session' {
interface Session {
messages: string[]; // Set by passport
passport: { user: string }; // Set by passport
}
}
export function redirectToDashboard(req: Request, res: Response) {
if (req?.user?.team) {
return res.redirect(`${config.FRONTEND_URL}/search`);
} else {
logger.error(
{ userId: req?.user?._id },
'Password login for user failed, user or team not found',
);
res.redirect(`${config.FRONTEND_URL}/login?err=unknown`);
}
}
export function handleAuthError(
err: any,
req: Request,
res: Response,
next: NextFunction,
) {
logger.debug({ authErr: serializeError(err) }, 'Auth error');
if (res.headersSent) {
return next(err);
}
// Get the latest auth error message
const lastMessage = req.session.messages?.at(-1);
logger.debug(`Auth error last message: ${lastMessage}`);
const returnErr =
lastMessage === 'Password or username is incorrect'
? 'authFail'
: lastMessage ===
'Authentication method password is not allowed by your team admin.'
? 'passwordAuthNotAllowed'
: 'unknown';
res.redirect(`${config.FRONTEND_URL}/login?err=${returnErr}`);
}
export async function validateUserAccessKey(
req: Request,
res: Response,
next: NextFunction,
) {
const authHeader = req.headers.authorization;
if (!authHeader) {
return res.sendStatus(401);
}
const key = authHeader.split('Bearer ')[1];
if (!key) {
return res.sendStatus(401);
}
const user = await findUserByAccessKey(key);
if (!user) {
return res.sendStatus(401);
}
req.user = user;
next();
}
export function isUserAuthenticated(
req: Request,
res: Response,
next: NextFunction,
) {
if (config.IS_LOCAL_APP_MODE) {
// If local app mode is enabled, skip authentication
logger.warn('Skipping authentication in local app mode');
req.user = {
// @ts-ignore
_id: '_local_user_',
email: 'local-user@hyperdx.io',
// @ts-ignore
team: '_local_team_',
};
return next();
}
if (config.IS_ANONYMOUS_AUTH_ENABLED) {
const anonymousUser = getAnonymousUser();
if (anonymousUser) {
req.user = anonymousUser.toObject();
setTraceAttributes({
userId: anonymousUser._id.toString(),
userEmail: anonymousUser.email,
});
return next();
}
// User not provisioned yet (server still starting)
logger.warn('Anonymous user not yet provisioned');
return res.sendStatus(503);
}
if (req.isAuthenticated()) {
// set user id as trace attribute
setTraceAttributes({
userId: req.user?._id.toString(),
userEmail: req.user?.email,
});
return next();
}
res.sendStatus(401);
}
export function getNonNullUserWithTeam(req: Request) {
const user = req.user;
if (!user) {
throw new Error('User is not authenticated');
}
if (!user.team) {
throw new Error(`User ${user._id} is not associated with a team`);
}
return { teamId: user.team, userId: user._id, email: user.email };
}