From e3009a0e738c9a39f9aefc0bed1ddc9f401c1c12 Mon Sep 17 00:00:00 2001 From: TheClashFruit Date: Thu, 1 Aug 2024 23:09:26 +0200 Subject: [PATCH] feat: get logged in user --- src/routes/v1/user/@me.ts | 66 +++++++++++++++++++++++++++++++++++++++ src/util/database.ts | 15 +++++++++ src/util/handler.ts | 4 +-- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/routes/v1/user/@me.ts create mode 100644 src/util/database.ts diff --git a/src/routes/v1/user/@me.ts b/src/routes/v1/user/@me.ts new file mode 100644 index 0000000..7fe9998 --- /dev/null +++ b/src/routes/v1/user/@me.ts @@ -0,0 +1,66 @@ +import Method from '../../../enum/method'; +import Status from '../../../enum/status'; + +import { Request, Response } from '../../../util/handler'; +import { User } from '../../../interfaces/user'; + +import { verify } from 'jsonwebtoken'; + +import Database from '../../../util/database'; + +interface ZleedJWT { + id: bigint; + email: string; + username: string; + iat: number; + exp: number; +} + +export default function handler(req: Request, res: Response) { + const jwtToken = req.getHeader('Authorization'); + + if (!jwtToken) { + return res.error(Status.UNAUTHORIZED, 'error.auth.noToken'); + } + + const tokenSplit = jwtToken.split(' '); + + if ( + !(tokenSplit.length > 1) || + jwtToken.split(' ')[0].toLowerCase() !== 'bearer' + ) { + return res.error(Status.UNAUTHORIZED, 'error.auth.invalidToken'); + } + + const token = tokenSplit[1]; + + verify(token, process.env.JWT_SECRET!, async (err, decoded) => { + if (err) { + return res.error(Status.UNAUTHORIZED, 'error.auth.invalidToken'); + } + + const data = decoded as ZleedJWT; + + data.id = BigInt(data.id); + + if (req.method === Method.GET) { + const user = await Database.getUser(data.id); + + res.status(Status.OK).json({ + id: user.id, + username: user.username, + displayName: user.displayName, + email: user.email, + avatar: user.avatar, + banner: user.banner, + badges: user.badges, + connections: user.connections, + streamTitle: user.streamTitle, + streamKeys: user.streamKeys, + lastLive: user.lastLive, + createdAt: user.createdAt, + updatedAt: user.updatedAt + }); + } + }); +} diff --git a/src/util/database.ts b/src/util/database.ts new file mode 100644 index 0000000..6028220 --- /dev/null +++ b/src/util/database.ts @@ -0,0 +1,15 @@ +import { User } from '../models'; + +class Database { + static async getUser( + id: string | number | bigint | boolean + ): Promise { + const user = await User.findOne({ id: BigInt(id) }); + + if (!user) return undefined; + + return user; + } +} + +export default Database; diff --git a/src/util/handler.ts b/src/util/handler.ts index 749824f..21dd185 100644 --- a/src/util/handler.ts +++ b/src/util/handler.ts @@ -21,11 +21,11 @@ export class Request { this.params = req.params; } - getHeader(key: string): string { + getHeader(key: string): string | undefined { return this.headers[key.toLowerCase()]; } - getParam(key: string) { + getParam(key: string): string | number | undefined { return this.params[key.toLowerCase()]; } }