From 63de1164d9b72d0251def8d7053a10a173353a1b Mon Sep 17 00:00:00 2001 From: Anand Chowdhary Date: Sat, 31 Aug 2019 19:17:51 +0530 Subject: [PATCH] :bug: Convert int to string --- package.json | 4 ++-- src/controllers/v1/auth.ts | 4 ++-- src/controllers/v1/membership.ts | 7 ++++--- src/controllers/v1/organization.ts | 31 +++++++++++++++--------------- src/controllers/v1/user.ts | 24 +++++++++++------------ src/crud/email.ts | 2 +- src/crud/user.ts | 6 +++--- src/helpers/__tests__/utils.ts | 2 +- src/helpers/mysql.ts | 5 +++-- src/helpers/utils.ts | 15 ++++++++++----- src/interfaces/tables/user.ts | 2 +- src/rest/organization.ts | 2 +- 12 files changed, 56 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 50f9b1ed3..60bf6fb12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "staart-manager", - "version": "1.1.11", + "version": "1.1.12", "main": "index.js", "repository": "git@github.com:AnandChowdhary/staart.git", "author": "Anand Chowdhary ", @@ -147,5 +147,5 @@ "setup" ], "snyk": true, - "staart-version": "1.1.11" + "staart-version": "1.1.12" } \ No newline at end of file diff --git a/src/controllers/v1/auth.ts b/src/controllers/v1/auth.ts index fd9f25f1a..1fe47a304 100644 --- a/src/controllers/v1/auth.ts +++ b/src/controllers/v1/auth.ts @@ -28,7 +28,7 @@ import { } from "../../helpers/middleware"; import { CREATED } from "http-status-codes"; import asyncHandler from "express-async-handler"; -import { safeRedirect, joiValidate } from "../../helpers/utils"; +import { safeRedirect, joiValidate, hashIdToId } from "../../helpers/utils"; import Joi from "@hapi/joi"; import { FRONTEND_URL, BASE_URL } from "../../config"; import { @@ -223,7 +223,7 @@ export class AuthController { ) async getImpersonate(req: Request, res: Response) { const tokenUserId = res.locals.token.id; - const impersonateUserId = parseInt(req.params.id); + const impersonateUserId = hashIdToId(req.params.id); res.json(await impersonate(tokenUserId, impersonateUserId, res.locals)); } diff --git a/src/controllers/v1/membership.ts b/src/controllers/v1/membership.ts index adf5322a9..0e5e03675 100644 --- a/src/controllers/v1/membership.ts +++ b/src/controllers/v1/membership.ts @@ -17,6 +17,7 @@ import { import { authHandler, validator } from "../../helpers/middleware"; import asyncHandler from "express-async-handler"; import Joi from "@hapi/joi"; +import { hashIdToId } from "../../helpers/utils"; @Controller("v1/memberships") @ClassWrapper(asyncHandler) @@ -25,7 +26,7 @@ export class MembershipController { @Get(":id") @Middleware(validator({ id: Joi.string().required() }, "params")) async get(req: Request, res: Response) { - const membershipId = parseInt(req.params.id); + const membershipId = hashIdToId(req.params.id); const userId = res.locals.token.id; res.json(await getMembershipDetailsForUser(userId, membershipId)); } @@ -34,7 +35,7 @@ export class MembershipController { @Middleware(validator({ id: Joi.string().required() }, "params")) async delete(req: Request, res: Response) { const userId = res.locals.token.id; - const membershipId = parseInt(req.params.id); + const membershipId = hashIdToId(req.params.id); await deleteMembershipForUser(userId, membershipId, res.locals); res.json({ deleted: true }); } @@ -43,7 +44,7 @@ export class MembershipController { @Middleware(validator({ id: Joi.string().required() }, "params")) async patch(req: Request, res: Response) { const userId = res.locals.token.id; - const membershipId = parseInt(req.params.id); + const membershipId = hashIdToId(req.params.id); const data = req.body; delete req.body.id; await updateMembershipForUser(userId, membershipId, data, res.locals); diff --git a/src/controllers/v1/organization.ts b/src/controllers/v1/organization.ts index f60f95f2b..b1246f013 100644 --- a/src/controllers/v1/organization.ts +++ b/src/controllers/v1/organization.ts @@ -60,7 +60,8 @@ import asyncHandler from "express-async-handler"; import { joiValidate, organizationUsernameToId, - localsToTokenOrKey + localsToTokenOrKey, + hashIdToId } from "../../helpers/utils"; import Joi from "@hapi/joi"; @@ -513,7 +514,7 @@ export class OrganizationController { @Get(":id/memberships/:membershipId") async getMembership(req: Request, res: Response) { const organizationId = await organizationUsernameToId(req.params.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { organizationId: Joi.string().required(), @@ -543,7 +544,7 @@ export class OrganizationController { ) async updateMembership(req: Request, res: Response) { const organizationId = await organizationUsernameToId(req.params.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { organizationId: Joi.string().required(), @@ -564,7 +565,7 @@ export class OrganizationController { @Delete(":id/memberships/:membershipId") async deleteMembership(req: Request, res: Response) { const organizationId = await organizationUsernameToId(req.params.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { organizationId: Joi.string().required(), @@ -639,7 +640,7 @@ export class OrganizationController { @Get(":id/api-keys/:apiKeyId") async getUserApiKey(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const apiKeyId = parseInt(req.params.apiKeyId); + const apiKeyId = hashIdToId(req.params.apiKeyId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -667,7 +668,7 @@ export class OrganizationController { ) async patchUserApiKey(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const apiKeyId = parseInt(req.params.apiKeyId); + const apiKeyId = hashIdToId(req.params.apiKeyId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -689,7 +690,7 @@ export class OrganizationController { @Delete(":id/api-keys/:apiKeyId") async deleteUserApiKey(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const apiKeyId = parseInt(req.params.apiKeyId); + const apiKeyId = hashIdToId(req.params.apiKeyId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -710,7 +711,7 @@ export class OrganizationController { @Get(":id/api-keys/:apiKeyId/logs") async getUserApiKeyLogs(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const apiKeyId = parseInt(req.params.apiKeyId); + const apiKeyId = hashIdToId(req.params.apiKeyId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -782,7 +783,7 @@ export class OrganizationController { @Get(":id/domains/:domainId") async getUserDomain(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const domainId = parseInt(req.params.domainId); + const domainId = hashIdToId(req.params.domainId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -806,7 +807,7 @@ export class OrganizationController { ) async patchUserDomain(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const domainId = parseInt(req.params.domainId); + const domainId = hashIdToId(req.params.domainId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -828,7 +829,7 @@ export class OrganizationController { @Delete(":id/domains/:domainId") async deleteUserDomain(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const domainId = parseInt(req.params.domainId); + const domainId = hashIdToId(req.params.domainId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -849,7 +850,7 @@ export class OrganizationController { @Post(":id/domains/:domainId/verify") async verifyOrganizationDomain(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const domainId = parseInt(req.params.domainId); + const domainId = hashIdToId(req.params.domainId); const method = req.body.method || req.query.method; joiValidate( { @@ -928,7 +929,7 @@ export class OrganizationController { @Get(":id/webhooks/:webhookId") async getUserWebhook(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const webhookId = parseInt(req.params.webhookId); + const webhookId = hashIdToId(req.params.webhookId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -960,7 +961,7 @@ export class OrganizationController { ) async patchUserWebhook(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const webhookId = parseInt(req.params.webhookId); + const webhookId = hashIdToId(req.params.webhookId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -982,7 +983,7 @@ export class OrganizationController { @Delete(":id/webhooks/:webhookId") async deleteUserWebhook(req: Request, res: Response) { const id = await organizationUsernameToId(req.params.id); - const webhookId = parseInt(req.params.webhookId); + const webhookId = hashIdToId(req.params.webhookId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], diff --git a/src/controllers/v1/user.ts b/src/controllers/v1/user.ts index 76f86c7d7..44fe2bb71 100644 --- a/src/controllers/v1/user.ts +++ b/src/controllers/v1/user.ts @@ -42,7 +42,7 @@ import { } from "../../rest/email"; import { CREATED } from "http-status-codes"; import asyncHandler from "express-async-handler"; -import { joiValidate, userUsernameToId } from "../../helpers/utils"; +import { joiValidate, userUsernameToId, hashIdToId } from "../../helpers/utils"; import Joi from "@hapi/joi"; import { deleteMembershipForUser, @@ -167,7 +167,7 @@ export class UserController { @Get(":id/memberships/:membershipId") async getMembership(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -181,7 +181,7 @@ export class UserController { @Delete(":id/memberships/:membershipId") async deleteMembership(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -196,7 +196,7 @@ export class UserController { @Patch(":id/memberships/:membershipId") async updateMembership(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const membershipId = parseInt(req.params.membershipId); + const membershipId = hashIdToId(req.params.membershipId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -250,7 +250,7 @@ export class UserController { @Get(":id/emails/:emailId") async getEmail(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const emailId = parseInt(req.params.emailId); + const emailId = hashIdToId(req.params.emailId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -264,7 +264,7 @@ export class UserController { @Post(":id/emails/:emailId/resend") async postResend(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const emailId = parseInt(req.params.emailId); + const emailId = hashIdToId(req.params.emailId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -279,7 +279,7 @@ export class UserController { @Delete(":id/emails/:emailId") async deleteEmail(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const emailId = parseInt(req.params.emailId); + const emailId = hashIdToId(req.params.emailId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -408,7 +408,7 @@ export class UserController { @Get(":id/access-tokens/:accessTokenId") async getUserAccessToken(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const accessTokenId = parseInt(req.params.accessTokenId); + const accessTokenId = hashIdToId(req.params.accessTokenId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -434,7 +434,7 @@ export class UserController { ) async patchUserAccessToken(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const accessTokenId = parseInt(req.params.accessTokenId); + const accessTokenId = hashIdToId(req.params.accessTokenId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -456,7 +456,7 @@ export class UserController { @Delete(":id/access-tokens/:accessTokenId") async deleteUserAccessToken(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const accessTokenId = parseInt(req.params.accessTokenId); + const accessTokenId = hashIdToId(req.params.accessTokenId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -497,7 +497,7 @@ export class UserController { @Get(":id/sessions/:sessionId") async getUserSession(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const sessionId = parseInt(req.params.sessionId); + const sessionId = hashIdToId(req.params.sessionId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], @@ -511,7 +511,7 @@ export class UserController { @Delete(":id/sessions/:sessionId") async deleteUserSession(req: Request, res: Response) { const id = await userUsernameToId(req.params.id, res.locals.token.id); - const sessionId = parseInt(req.params.sessionId); + const sessionId = hashIdToId(req.params.sessionId); joiValidate( { id: [Joi.string().required(), Joi.string().required()], diff --git a/src/crud/email.ts b/src/crud/email.ts index dac34d10b..88b798a4d 100644 --- a/src/crud/email.ts +++ b/src/crud/email.ts @@ -202,7 +202,7 @@ export const getVerifiedEmailObject = async (email: string) => { * Get a list of all verified emails of a user */ export const getUserVerifiedEmails = async (user: User | string) => { - let userId = 0; + let userId = ""; if (typeof user === "object" && user.id) { userId = user.id; } else if (typeof user === "string") { diff --git a/src/crud/user.ts b/src/crud/user.ts index 945a98958..39813998c 100644 --- a/src/crud/user.ts +++ b/src/crud/user.ts @@ -271,7 +271,7 @@ export const createBackupCodes = async (userId: string, count = 1) => { /** * Update a backup code */ -export const updateBackupCode = async (backupCode: string, code: KeyValue) => { +export const updateBackupCode = async (backupCode: number, code: KeyValue) => { code.updatedAt = new Date(); return await query( `UPDATE \`backup-codes\` SET ${setValues(code)} WHERE code = ?`, @@ -282,7 +282,7 @@ export const updateBackupCode = async (backupCode: string, code: KeyValue) => { /** * Delete a backup code */ -export const deleteBackupCode = async (backupCode: string) => { +export const deleteBackupCode = async (backupCode: number) => { return await query("DELETE FROM `backup-codes` WHERE code = ?", [backupCode]); }; @@ -303,7 +303,7 @@ export const getUserBackupCodes = async (userId: string) => { /** * Get a specific backup code */ -export const getUserBackupCode = async (userId: string, backupCode: string) => { +export const getUserBackupCode = async (userId: string, backupCode: number) => { return (( await query( "SELECT * FROM `backup-codes` WHERE userId = ? AND code = ? LIMIT 1", diff --git a/src/helpers/__tests__/utils.ts b/src/helpers/__tests__/utils.ts index 46537598e..3145860d2 100644 --- a/src/helpers/__tests__/utils.ts +++ b/src/helpers/__tests__/utils.ts @@ -29,7 +29,7 @@ test("Convert date to MySQL datetime", () => { test("Remove sensitive info", () => { expect( deleteSensitiveInfoUser({ - id: 1, + id: "wiuhoeijpaoe", name: "Anand Chowdhary", password: "1abc9c" }).password diff --git a/src/helpers/mysql.ts b/src/helpers/mysql.ts index 38eb34918..47f684e34 100644 --- a/src/helpers/mysql.ts +++ b/src/helpers/mysql.ts @@ -18,7 +18,8 @@ import { dateValues, readOnlyValues, generateHashId, - hashIdToId + hashIdToId, + IdValues } from "./utils"; import { getUserPrimaryEmailObject } from "../crud/email"; import { InsertResult } from "../interfaces/mysql"; @@ -93,7 +94,7 @@ export const uncleanValues = ( ) ).toISOString(); } - if (key === "id") item[key] = generateHashId(item[key]); + if (IdValues.includes(key)) item[key] = generateHashId(item[key]); if (typeof item[key] === "string") item[key] = emojify(item[key]); }); return item; diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 12bf3df8a..2fefd33e7 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -89,8 +89,8 @@ export const userUsernameToId = async (id: string, tokenUserId: string) => { export const generateHashId = (id: string) => `hashid-${hashIds.encode(id)}`; -export const hashIdToId = (id: string | number) => { - if (typeof id === "number") return id; +export const hashIdToId = (id: string | number): string => { + if (typeof id === "number") return id.toString(); if (id.startsWith("hashid-")) { const numberId = parseInt( hashIds.decode(id.replace("hashid-", "")).join("") @@ -100,10 +100,10 @@ export const hashIdToId = (id: string | number) => { if (isNaN(newId)) { return id; } else { - return newId; + return newId.toString(); } } else { - return numberId; + return numberId.toString(); } } return id; @@ -113,7 +113,7 @@ export const localsToTokenOrKey = (res: Response) => { if (res.locals.token.sub == Tokens.API_KEY) { return res.locals.token as ApiKeyResponse; } - return res.locals.token.id as number; + return res.locals.token.id as string; }; export const createSlug = (name: string) => @@ -176,6 +176,11 @@ export const readOnlyValues = [ "organizationId" ]; +/** + * MySQL columns which are for int IDs + */ +export const IdValues = ["id", "userId", "organizationId", "primaryEmailId"]; + export const joiValidate = (schemaMap: Joi.SchemaMap, data: any) => { const schema = Joi.object().keys(schemaMap); const result = Joi.validate(data, schema); diff --git a/src/interfaces/tables/user.ts b/src/interfaces/tables/user.ts index 48262576f..dbd9f27e2 100644 --- a/src/interfaces/tables/user.ts +++ b/src/interfaces/tables/user.ts @@ -6,7 +6,7 @@ export interface User extends IdRow { name: string; username?: string; nickname?: string; - primaryEmail?: number; + primaryEmail?: string; password?: string; twoFactorEnabled?: boolean; twoFactorSecret?: string; diff --git a/src/rest/organization.ts b/src/rest/organization.ts index 0b5847048..d1221dcaf 100644 --- a/src/rest/organization.ts +++ b/src/rest/organization.ts @@ -641,7 +641,7 @@ export const inviteMemberToOrganization = async ( } let newUser: User; let userExists = false; - let createdUserId = 0; + let createdUserId: string; try { newUser = await getUserByEmail(newMemberEmail); userExists = true;