summary refs log tree commit diff
path: root/util/src/util/Token.ts
blob: 5a3922d1145daef30891194a465db854b9948d23 (plain) (blame)
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
import jwt, { VerifyOptions } from "jsonwebtoken";
import { Config } from "./Config";
import { User } from "../entities";

export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] };

export function checkToken(token: string, jwtSecret: string): Promise<any> {
	return new Promise((res, rej) => {
		token = token.replace("Bot ", "");
		/**
		in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix,
		as we don't really have separate pathways for bots 
		**/
		
		jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
			if (err || !decoded) return rej("Invalid Token");

			const user = await User.findOne({
				where: { id: decoded.id },
				select: ["data", "bot", "disabled", "deleted", "rights"] 
			});
			if (!user) return rej("Invalid Token");
			// we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds
			if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0))
				return rej("Invalid Token");
			if (user.disabled) return rej("User disabled");
			if (user.deleted) return rej("User not found");

			return res({ decoded, user });
		});
	});
}

export async function generateToken(id: string) {
	const iat = Math.floor(Date.now() / 1000);
	const algorithm = "HS256";

	return new Promise((res, rej) => {
		jwt.sign(
			{ id: id, iat },
			Config.get().security.jwtSecret,
			{
				algorithm,
			},
			(err, token) => {
				if (err) return rej(err);
				return res(token);
			}
		);
	});
}