From 5edf233a2283f778c230a82d5d4f132842a5d21b Mon Sep 17 00:00:00 2001 From: Anand Chowdhary Date: Tue, 4 Aug 2020 23:28:50 +0530 Subject: [PATCH] :recycle: Use number ID for user, validate number --- src/_staart/helpers/utils.ts | 11 +++++---- src/controllers/users/_id/access-tokens.ts | 26 +++++++++++----------- src/controllers/users/_id/emails.ts | 26 +++++++++++----------- src/controllers/users/_id/identities.ts | 20 ++++++++--------- src/controllers/users/_id/index.ts | 12 +++++----- src/controllers/users/_id/memberships.ts | 22 +++++++++--------- src/controllers/users/_id/security.ts | 24 ++++++++++---------- src/controllers/users/_id/sessions.ts | 16 ++++++------- 8 files changed, 80 insertions(+), 77 deletions(-) diff --git a/src/_staart/helpers/utils.ts b/src/_staart/helpers/utils.ts index b3b552416..afcda7eef 100644 --- a/src/_staart/helpers/utils.ts +++ b/src/_staart/helpers/utils.ts @@ -1,12 +1,13 @@ +import { config } from "@anandchowdhary/cosmic"; import { users } from "@prisma/client"; import { Request, Response } from "@staart/server"; import { isMatch } from "@staart/text"; import { Joi, joiValidate } from "@staart/validate"; import dns from "dns"; -import { Tokens } from "../interfaces/enum"; import { verify } from "twt"; +import { Tokens } from "../interfaces/enum"; +import { Locals } from "../interfaces/general"; import { ApiKeyResponse } from "./jwt"; -import { config } from "@anandchowdhary/cosmic"; /** * Make s single property optional @@ -14,8 +15,10 @@ import { config } from "@anandchowdhary/cosmic"; */ export type PartialBy = Omit & Partial>; -export const twtToId = (twt: string) => - parseInt(verify(twt, config("twtSecret")), 10); +export const twtToId = (twt: string, userId?: number) => + twt === "me" && userId + ? userId + : parseInt(verify(twt, config("twtSecret")), 10); /** * Delete any sensitive information for a user like passwords and tokens diff --git a/src/controllers/users/_id/access-tokens.ts b/src/controllers/users/_id/access-tokens.ts index 8ffa90e10..891cf43c0 100644 --- a/src/controllers/users/_id/access-tokens.ts +++ b/src/controllers/users/_id/access-tokens.ts @@ -29,8 +29,8 @@ import { export class UserAccessTokensController { @Get() async getUserAccessTokens(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getUserAccessTokensForUser(res.locals.token.id, id, req.query); } @@ -47,8 +47,8 @@ export class UserAccessTokensController { ) ) async putUserAccessTokens(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); try { const added = await createAccessTokenForUser( res.locals.token.id, @@ -65,12 +65,12 @@ export class UserAccessTokensController { @Get(":accessTokenId") async getUserAccessToken(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const accessTokenId = twtToId(req.params.accessTokenId); joiValidate( { - id: Joi.string().required(), - accessTokenId: Joi.string().required(), + id: Joi.number().required(), + accessTokenId: Joi.number().required(), }, { id, accessTokenId } ); @@ -90,12 +90,12 @@ export class UserAccessTokensController { ) ) async patchUserAccessToken(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const accessTokenId = twtToId(req.params.accessTokenId); joiValidate( { - id: Joi.string().required(), - accessTokenId: Joi.string().required(), + id: Joi.number().required(), + accessTokenId: Joi.number().required(), }, { id, accessTokenId } ); @@ -111,12 +111,12 @@ export class UserAccessTokensController { @Delete(":accessTokenId") async deleteUserAccessToken(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const accessTokenId = twtToId(req.params.accessTokenId); joiValidate( { - id: Joi.string().required(), - accessTokenId: Joi.string().required(), + id: Joi.number().required(), + accessTokenId: Joi.number().required(), }, { id, accessTokenId } ); diff --git a/src/controllers/users/_id/emails.ts b/src/controllers/users/_id/emails.ts index 7df5afd86..64c1ee4fe 100644 --- a/src/controllers/users/_id/emails.ts +++ b/src/controllers/users/_id/emails.ts @@ -28,18 +28,18 @@ import { export class UserEmailsController { @Get() async getEmails(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getAllEmailsForUser(res.locals.token.id, id, req.query); } @Put() async putEmails(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const email = req.body.email; joiValidate( { - id: Joi.string().required(), + id: Joi.number().required(), email: Joi.string().email().required(), }, { id, email } @@ -55,12 +55,12 @@ export class UserEmailsController { @Get(":emailId") async getEmail(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const emailId = twtToId(req.params.emailId); joiValidate( { - id: Joi.string().required(), - emailId: Joi.string().required(), + id: Joi.number().required(), + emailId: Joi.number().required(), }, { id, emailId } ); @@ -69,12 +69,12 @@ export class UserEmailsController { @Post(":emailId/resend") async postResend(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const emailId = twtToId(req.params.emailId); joiValidate( { - id: Joi.string().required(), - emailId: Joi.string().required(), + id: Joi.number().required(), + emailId: Joi.number().required(), }, { id, emailId } ); @@ -84,12 +84,12 @@ export class UserEmailsController { @Delete(":emailId") async deleteEmail(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const emailId = twtToId(req.params.emailId); joiValidate( { - id: Joi.string().required(), - emailId: Joi.string().required(), + id: Joi.number().required(), + emailId: Joi.number().required(), }, { id, emailId } ); diff --git a/src/controllers/users/_id/identities.ts b/src/controllers/users/_id/identities.ts index 73ecbc97d..a77391e5d 100644 --- a/src/controllers/users/_id/identities.ts +++ b/src/controllers/users/_id/identities.ts @@ -28,15 +28,15 @@ import { export class UserIdentitiesController { @Get() async getUserIdentities(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getUserIdentitiesForUser(res.locals.token.id, id, req.query); } @Put() async createUserIdentity(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); const added = await createUserIdentityForUser( res.locals.token.id, id, @@ -47,8 +47,8 @@ export class UserIdentitiesController { @Post(":service") async connectUserIdentity(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); const service = req.params.service; const url = req.body.url; joiValidate( @@ -61,12 +61,12 @@ export class UserIdentitiesController { @Get(":identityId") async getUserIdentity(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const identityId = twtToId(req.params.identityId); joiValidate( { id: Joi.string().required(), - identityId: Joi.string().required(), + identityId: Joi.number().required(), }, { id, identityId } ); @@ -75,12 +75,12 @@ export class UserIdentitiesController { @Delete(":identityId") async deleteUserIdentity(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const identityId = twtToId(req.params.identityId); joiValidate( { id: Joi.string().required(), - identityId: Joi.string().required(), + identityId: Joi.number().required(), }, { id, identityId } ); diff --git a/src/controllers/users/_id/index.ts b/src/controllers/users/_id/index.ts index 706ac5c1f..e7b142f3f 100644 --- a/src/controllers/users/_id/index.ts +++ b/src/controllers/users/_id/index.ts @@ -21,8 +21,8 @@ import { export class UserController { @Get() async get(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getUserFromIdForUser(id, res.locals.token.id, req.query); } @@ -59,8 +59,8 @@ export class UserController { ) ) async patch(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); const updated = await updateUserForUser( res.locals.token.id, id, @@ -72,8 +72,8 @@ export class UserController { @Delete() async delete(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); await deleteUserForUser(res.locals.token.id, id, res.locals); return respond(RESOURCE_DELETED); } diff --git a/src/controllers/users/_id/memberships.ts b/src/controllers/users/_id/memberships.ts index f241d4257..1759d1683 100644 --- a/src/controllers/users/_id/memberships.ts +++ b/src/controllers/users/_id/memberships.ts @@ -21,19 +21,19 @@ import { export class UserMembershipsController { @Get() async getMemberships(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getMembershipsForUser(res.locals.token.id, id, req.query); } @Get(":membershipId") async getMembership(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const membershipId = twtToId(req.params.membershipId); joiValidate( { - id: Joi.string().required(), - membershipId: Joi.string().required(), + id: Joi.number().required(), + membershipId: Joi.number().required(), }, { id, membershipId } ); @@ -42,12 +42,12 @@ export class UserMembershipsController { @Delete(":membershipId") async deleteMembership(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const membershipId = twtToId(req.params.membershipId); joiValidate( { - id: Joi.string().required(), - membershipId: Joi.string().required(), + id: Joi.number().required(), + membershipId: Joi.number().required(), }, { id, membershipId } ); @@ -57,12 +57,12 @@ export class UserMembershipsController { @Patch(":membershipId") async updateMembership(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const membershipId = twtToId(req.params.membershipId); joiValidate( { - id: Joi.string().required(), - membershipId: Joi.string().required(), + id: Joi.number().required(), + membershipId: Joi.number().required(), }, { id, membershipId } ); diff --git a/src/controllers/users/_id/security.ts b/src/controllers/users/_id/security.ts index 15b73274c..e162c0478 100644 --- a/src/controllers/users/_id/security.ts +++ b/src/controllers/users/_id/security.ts @@ -34,12 +34,12 @@ export class UserSecurityController { ) ) async updatePassword(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const oldPassword = req.body.oldPassword; const newPassword = req.body.newPassword; joiValidate( { - id: Joi.string().required(), + id: Joi.number().required(), }, { id } ); @@ -55,25 +55,25 @@ export class UserSecurityController { @Get("data") async getUserData(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getAllDataForUser(res.locals.token.id, id); } @Get("2fa/enable") async getEnable2FA(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return enable2FAForUser(res.locals.token.id, id); } @Post("2fa/verify") async postVerify2FA(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const code = req.body.code; joiValidate( { - id: Joi.string().required(), + id: Joi.number().required(), code: Joi.number().min(5).required(), }, { id, code } @@ -84,16 +84,16 @@ export class UserSecurityController { @Delete("2fa") async delete2FA(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); await disable2FAForUser(res.locals.token.id, id); return respond(RESOURCE_SUCCESS); } @Get("backup-codes/regenerate") async getRegenerateBackupCodes(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); const backupCodes = await regenerateBackupCodesForUser( res.locals.token.id, id diff --git a/src/controllers/users/_id/sessions.ts b/src/controllers/users/_id/sessions.ts index fc517cde7..a3e4e1993 100644 --- a/src/controllers/users/_id/sessions.ts +++ b/src/controllers/users/_id/sessions.ts @@ -19,19 +19,19 @@ import { export class UserSessionsController { @Get() async getUserSessions(req: Request, res: Response) { - const id = twtToId(req.params.id); - joiValidate({ id: Joi.string().required() }, { id }); + const id = twtToId(req.params.id, res.locals.token.id); + joiValidate({ id: Joi.number().required() }, { id }); return getUserSessionsForUser(res.locals.token.id, id, req.query); } @Get(":sessionId") async getUserSession(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const sessionId = twtToId(req.params.sessionId); joiValidate( { - id: Joi.string().required(), - sessionId: Joi.string().required(), + id: Joi.number().required(), + sessionId: Joi.number().required(), }, { id, sessionId } ); @@ -40,12 +40,12 @@ export class UserSessionsController { @Delete(":sessionId") async deleteUserSession(req: Request, res: Response) { - const id = twtToId(req.params.id); + const id = twtToId(req.params.id, res.locals.token.id); const sessionId = twtToId(req.params.sessionId); joiValidate( { - id: Joi.string().required(), - sessionId: Joi.string().required(), + id: Joi.number().required(), + sessionId: Joi.number().required(), }, { id, sessionId } );