Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
✨ Add query parameters to select
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Apr 29, 2020
1 parent 008cde1 commit b8b274f
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 32 deletions.
15 changes: 15 additions & 0 deletions src/_staart/helpers/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ cleanup(() => {
prisma.disconnect().then(() => success("Disconnected database connection"));
});

export const queryParamsToSelect = (queryParams: any) => {
const data: any = {};
const select = queryParams.select;
if (typeof select === "string") {
select
.split(",")
.map((i) => i.trim())
.forEach((i) => {
data.select = data.select || {};
data.select[i] = true;
});
}
return data;
};

export const paginatedResult = <T>(
data: T,
{ first, last }: { first?: number; last?: number }
Expand Down
14 changes: 12 additions & 2 deletions src/_staart/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import dns from "dns";
import { Tokens } from "../interfaces/enum";
import { ApiKeyResponse } from "./jwt";
import { users } from "@prisma/client";
import { prisma } from "../helpers/prisma";
import { getOrganizationById } from "../services/organization.service";
import { getUserById, getUserByUsername } from "../services/user.service";
import { getUserById } from "../services/user.service";

/**
* Make s single property optional
Expand Down Expand Up @@ -35,7 +36,16 @@ export const userUsernameToId = async (id: string, tokenUserId?: string) => {
if (id === "me" && tokenUserId) {
return String(tokenUserId);
} else if (!id.match(/^-{0,1}\d+$/)) {
return (await getUserByUsername(id)).id.toString();
return (
(
await prisma.users.findOne({
select: { id: true },
where: {
username: id,
},
})
)?.id.toString() || parseInt(id).toString()
);
} else {
return parseInt(id).toString();
}
Expand Down
3 changes: 3 additions & 0 deletions src/_staart/rest/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
verifyToken,
resendEmailVerificationToken,
} from "../helpers/jwt";
import { deleteItemFromCache } from "../helpers/cache";
import { mail } from "../helpers/mail";
import { trackEvent } from "../helpers/tracking";
import { EventType, Templates, Tokens, UserScopes } from "../interfaces/enum";
Expand Down Expand Up @@ -171,6 +172,7 @@ export const register = async (
where: { id: userId },
data: { primaryEmail: newEmail.id },
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
resendToken = await resendEmailVerificationToken(newEmail.id.toString());
}
if (locals) await addApprovedLocation(userId, locals.ipAddress);
Expand Down Expand Up @@ -240,6 +242,7 @@ export const updatePassword = async (
where: { id: parseInt(userId) },
data: { password: await hash(password, 8) },
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
trackEvent(
{
userId,
Expand Down
26 changes: 20 additions & 6 deletions src/_staart/rest/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ import { Locals } from "../interfaces/general";
import { mail } from "../helpers/mail";
import { deleteCustomer } from "@staart/payments";
import { couponCodeJwt } from "../helpers/jwt";
import { prisma, paginatedResult } from "../helpers/prisma";
import {
prisma,
paginatedResult,
queryParamsToSelect,
} from "../helpers/prisma";
import {
users,
membershipsSelect,
Expand Down Expand Up @@ -67,10 +71,14 @@ import { deleteItemFromCache } from "../helpers/cache";

export const getUserFromIdForUser = async (
userId: string,
tokenUserId: string
tokenUserId: string,
queryParams: any
) => {
if (await can(tokenUserId, UserScopes.READ_USER, "user", userId)) {
const user = await getUserById(userId);
const user = await prisma.users.findOne({
...queryParamsToSelect(queryParams),
where: { id: parseInt(userId) },
});
if (user) return user;
throw new Error(USER_NOT_FOUND);
}
Expand All @@ -89,6 +97,7 @@ export const updateUserForUser = async (
data,
where: { id: parseInt(updateUserId) },
});
await deleteItemFromCache(`cache_getUserById_${updateUserId}`);
trackEvent(
{
userId: tokenUserId,
Expand Down Expand Up @@ -121,6 +130,7 @@ export const updatePasswordForUser = async (
data: { password: await hash(newPassword, 8) },
where: { id: parseInt(updateUserId) },
});
await deleteItemFromCache(`cache_getUserById_${updateUserId}`);
trackEvent(
{
userId: tokenUserId,
Expand Down Expand Up @@ -174,7 +184,7 @@ export const deleteUserForUser = async (
await prisma.users.delete({ where: { id: parseInt(updateUserId) } });
await deleteItemFromCache(
`cache_getUserById_${originalUser.id}`,
`cache_getUserByUsername_${originalUser.username}`
`cache_getUserIdByUsername_${originalUser.username}`
);
trackEvent(
{
Expand Down Expand Up @@ -260,6 +270,7 @@ export const enable2FAForUser = async (tokenUserId: string, userId: string) => {
where: { id: parseInt(userId) },
data: { twoFactorSecret: secret },
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
const authPath = authenticator.keyuri(`user-${userId}`, SERVICE_2FA, secret);
const qrCode = await toDataURL(authPath);
return { qrCode };
Expand All @@ -272,7 +283,6 @@ export const verify2FAForUser = async (
) => {
if (!(await can(tokenUserId, UserScopes.ENABLE_USER_2FA, "user", userId)))
throw new Error(INSUFFICIENT_PERMISSION);
// const secret = (await getUser(userId, true)).twoFactorSecret as string;
const secret = (
await prisma.users.findOne({
select: { twoFactorSecret: true },
Expand All @@ -287,6 +297,7 @@ export const verify2FAForUser = async (
where: { id: parseInt(userId) },
data: { twoFactorEnabled: true },
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
return codes;
};

Expand All @@ -297,13 +308,15 @@ export const disable2FAForUser = async (
if (!(await can(tokenUserId, UserScopes.DISABLE_USER_2FA, "user", userId)))
throw new Error(INSUFFICIENT_PERMISSION);
await prisma.backup_codes.deleteMany({ where: { userId: parseInt(userId) } });
return prisma.users.update({
const result = prisma.users.update({
where: { id: parseInt(userId) },
data: {
twoFactorEnabled: false,
twoFactorSecret: null,
},
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
return result;
};

export const regenerateBackupCodesForUser = async (
Expand Down Expand Up @@ -731,6 +744,7 @@ export const deleteEmailFromUserForUser = async (
where: { id: parseInt(userId) },
data: { primaryEmail: nextVerifiedEmail.id },
});
await deleteItemFromCache(`cache_getUserById_${userId}`);
}
const result = await prisma.emails.delete({
where: { id: parseInt(emailId) },
Expand Down
29 changes: 6 additions & 23 deletions src/_staart/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,7 @@ export const getUserByEmail = async (email: string, secureOrigin = false) => {
*/
export const updateUser = async (id: string, user: KeyValue) => {
const originalUser = await getUserById(id);
await deleteItemFromCache(
`cache_getUserById_${originalUser.id}`,
`cache_getUserByUsername_${originalUser.username}`
);
await deleteItemFromCache(`cache_getUserById_${originalUser.id}`);
if (user.password) user.password = await hash(user.password, 8);
// If you're updating your primary email, your Gravatar should reflect it
if (user.primaryEmail) {
Expand Down Expand Up @@ -155,7 +152,11 @@ export const updateUser = async (id: string, user: KeyValue) => {
)
throw new Error(USERNAME_EXISTS);
}
return await prisma.users.update({ data: user, where: { id: parseInt(id) } });
const result = await prisma.users.update({
data: user,
where: { id: parseInt(id) },
});
return result;
};

/**
Expand Down Expand Up @@ -400,21 +401,3 @@ export const getUserById = async (id: number | string) => {
throw new Error(USER_NOT_FOUND);
}
};

/**
* Get a user object from its username
* @param username - User's username
*/
export const getUserByUsername = async (username: string) => {
const key = `cache_getUserByUsername_${username}`;
try {
return await getItemFromCache<users>(key);
} catch (error) {
const user = await prisma.users.findOne({ where: { username } });
if (user) {
await setItemInCache(key, user);
return user;
}
throw new Error(USER_NOT_FOUND);
}
};
2 changes: 1 addition & 1 deletion src/controllers/users/_id/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class UserController {
async get(req: Request, res: Response) {
const id = await userUsernameToId(req.params.id, res.locals.token.id);
joiValidate({ id: Joi.string().required() }, { id });
return getUserFromIdForUser(id, res.locals.token.id);
return getUserFromIdForUser(id, res.locals.token.id, req.query);
}

@Patch()
Expand Down

0 comments on commit b8b274f

Please sign in to comment.