feat: remove try-catch blocks for handling errors in middleware

This commit is contained in:
Spelchure
2023-06-05 21:15:35 +03:00
parent 08868681d8
commit bfee0a6d30
36 changed files with 3681 additions and 4753 deletions
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import * as bigintConversion from 'bigint-conversion'; import * as bigintConversion from 'bigint-conversion';
@@ -34,7 +33,6 @@ declare module 'jsonwebtoken' {
* @returns * @returns
*/ */
export const login1 = async (req: Request, res: Response) => { export const login1 = async (req: Request, res: Response) => {
try {
const { const {
email, email,
clientPublicKey clientPublicKey
@@ -68,13 +66,6 @@ export const login1 = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to start authentication process'
});
}
}; };
/** /**
@@ -85,7 +76,6 @@ export const login1 = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const login2 = async (req: Request, res: Response) => { export const login2 = async (req: Request, res: Response) => {
try {
const { email, clientProof } = req.body; const { email, clientProof } = req.body;
const user = await User.findOne({ const user = await User.findOne({
email email
@@ -156,13 +146,6 @@ export const login2 = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to authenticate. Try again?'
});
}
}; };
/** /**
@@ -172,7 +155,6 @@ export const login2 = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const logout = async (req: Request, res: Response) => { export const logout = async (req: Request, res: Response) => {
try {
await clearTokens({ await clearTokens({
userId: req.user._id.toString() userId: req.user._id.toString()
}); });
@@ -197,14 +179,6 @@ export const logout = async (req: Request, res: Response) => {
ipAddress: req.ip ipAddress: req.ip
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to logout'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully logged out.' message: 'Successfully logged out.'
}); });
@@ -229,7 +203,6 @@ export const checkAuth = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getNewToken = async (req: Request, res: Response) => { export const getNewToken = async (req: Request, res: Response) => {
try {
const refreshToken = req.cookies.jid; const refreshToken = req.cookies.jid;
if (!refreshToken) { if (!refreshToken) {
@@ -259,13 +232,6 @@ export const getNewToken = async (req: Request, res: Response) => {
return res.status(200).send({ return res.status(200).send({
token token
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Invalid request'
});
}
}; };
export const handleAuthProviderCallback = (req: Request, res: Response) => { export const handleAuthProviderCallback = (req: Request, res: Response) => {
+2 -22
View File
@@ -1,6 +1,5 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import * as Sentry from '@sentry/node';
import { Bot, BotKey } from '../../models'; import { Bot, BotKey } from '../../models';
import { createBot } from '../../helpers/bot'; import { createBot } from '../../helpers/bot';
@@ -17,11 +16,9 @@ interface BotKey {
* @returns * @returns
*/ */
export const getBotByWorkspaceId = async (req: Request, res: Response) => { export const getBotByWorkspaceId = async (req: Request, res: Response) => {
let bot;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
bot = await Bot.findOne({ let bot = await Bot.findOne({
workspace: workspaceId workspace: workspaceId
}); });
@@ -33,13 +30,6 @@ export const getBotByWorkspaceId = async (req: Request, res: Response) => {
workspaceId: new Types.ObjectId(workspaceId) workspaceId: new Types.ObjectId(workspaceId)
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get bot for workspace'
});
}
return res.status(200).send({ return res.status(200).send({
bot bot
@@ -53,8 +43,6 @@ export const getBotByWorkspaceId = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const setBotActiveState = async (req: Request, res: Response) => { export const setBotActiveState = async (req: Request, res: Response) => {
let bot;
try {
const { isActive, botKey }: { isActive: boolean, botKey: BotKey } = req.body; const { isActive, botKey }: { isActive: boolean, botKey: BotKey } = req.body;
if (isActive) { if (isActive) {
@@ -84,7 +72,7 @@ export const setBotActiveState = async (req: Request, res: Response) => {
}); });
} }
bot = await Bot.findOneAndUpdate({ let bot = await Bot.findOneAndUpdate({
_id: req.bot._id _id: req.bot._id
}, { }, {
isActive isActive
@@ -94,14 +82,6 @@ export const setBotActiveState = async (req: Request, res: Response) => {
if (!bot) throw new Error('Failed to update bot active state'); if (!bot) throw new Error('Failed to update bot active state');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to update bot active state'
});
}
return res.status(200).send({ return res.status(200).send({
bot bot
}); });
@@ -1,6 +1,5 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import * as Sentry from '@sentry/node';
import { import {
IntegrationAuth, IntegrationAuth,
Bot Bot
@@ -22,21 +21,12 @@ import { standardRequest } from '../../config/request';
* Return integration authorization with id [integrationAuthId] * Return integration authorization with id [integrationAuthId]
*/ */
export const getIntegrationAuth = async (req: Request, res: Response) => { export const getIntegrationAuth = async (req: Request, res: Response) => {
let integrationAuth;
try {
const { integrationAuthId } = req.params; const { integrationAuthId } = req.params;
integrationAuth = await IntegrationAuth.findById(integrationAuthId); const integrationAuth = await IntegrationAuth.findById(integrationAuthId);
if (!integrationAuth) return res.status(400).send({ if (!integrationAuth) return res.status(400).send({
message: 'Failed to find integration authorization' message: 'Failed to find integration authorization'
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get integration authorization'
});
}
return res.status(200).send({ return res.status(200).send({
integrationAuth integrationAuth
@@ -61,7 +51,6 @@ export const oAuthExchange = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
try {
const { workspaceId, code, integration } = req.body; const { workspaceId, code, integration } = req.body;
if (!INTEGRATION_SET.has(integration)) if (!INTEGRATION_SET.has(integration))
throw new Error('Failed to validate integration'); throw new Error('Failed to validate integration');
@@ -81,13 +70,6 @@ export const oAuthExchange = async (
return res.status(200).send({ return res.status(200).send({
integrationAuth integrationAuth
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get OAuth2 code-token exchange'
});
}
}; };
/** /**
@@ -104,7 +86,6 @@ export const saveIntegrationAccessToken = async (
// TODO: check if access token is valid for each integration // TODO: check if access token is valid for each integration
let integrationAuth; let integrationAuth;
try {
const { const {
workspaceId, workspaceId,
accessId, accessId,
@@ -146,13 +127,6 @@ export const saveIntegrationAccessToken = async (
}); });
if (!integrationAuth) throw new Error('Failed to save integration access token'); if (!integrationAuth) throw new Error('Failed to save integration access token');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to save access token for integration'
});
}
return res.status(200).send({ return res.status(200).send({
integrationAuth integrationAuth
@@ -166,22 +140,13 @@ export const saveIntegrationAccessToken = async (
* @returns * @returns
*/ */
export const getIntegrationAuthApps = async (req: Request, res: Response) => { export const getIntegrationAuthApps = async (req: Request, res: Response) => {
let apps;
try {
const teamId = req.query.teamId as string; const teamId = req.query.teamId as string;
apps = await getApps({ const apps = await getApps({
integrationAuth: req.integrationAuth, integrationAuth: req.integrationAuth,
accessToken: req.accessToken, accessToken: req.accessToken,
...teamId && { teamId } ...teamId && { teamId }
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get integration authorization applications",
});
}
return res.status(200).send({ return res.status(200).send({
apps apps
@@ -402,19 +367,10 @@ export const getIntegrationAuthRailwayServices = async (req: Request, res: Respo
* @returns * @returns
*/ */
export const deleteIntegrationAuth = async (req: Request, res: Response) => { export const deleteIntegrationAuth = async (req: Request, res: Response) => {
let integrationAuth; const integrationAuth = await revokeAccess({
try {
integrationAuth = await revokeAccess({
integrationAuth: req.integrationAuth, integrationAuth: req.integrationAuth,
accessToken: req.accessToken, accessToken: req.accessToken,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to delete integration authorization",
});
}
return res.status(200).send({ return res.status(200).send({
integrationAuth, integrationAuth,
@@ -1,6 +1,5 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import * as Sentry from '@sentry/node';
import { import {
Integration Integration
} from '../../models'; } from '../../models';
@@ -14,9 +13,6 @@ import { eventPushSecrets } from '../../events';
* @returns * @returns
*/ */
export const createIntegration = async (req: Request, res: Response) => { export const createIntegration = async (req: Request, res: Response) => {
let integration;
try {
const { const {
integrationAuthId, integrationAuthId,
app, app,
@@ -35,7 +31,7 @@ export const createIntegration = async (req: Request, res: Response) => {
// TODO: validate [sourceEnvironment] and [targetEnvironment] // TODO: validate [sourceEnvironment] and [targetEnvironment]
// initialize new integration after saving integration access token // initialize new integration after saving integration access token
integration = await new Integration({ const integration = await new Integration({
workspace: req.integrationAuth.workspace._id, workspace: req.integrationAuth.workspace._id,
environment: sourceEnvironment, environment: sourceEnvironment,
isActive, isActive,
@@ -61,15 +57,6 @@ export const createIntegration = async (req: Request, res: Response) => {
}) })
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to create integration'
});
}
return res.status(200).send({ return res.status(200).send({
integration, integration,
}); });
@@ -82,12 +69,10 @@ export const createIntegration = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const updateIntegration = async (req: Request, res: Response) => { export const updateIntegration = async (req: Request, res: Response) => {
let integration;
// TODO: add integration-specific validation to ensure that each // TODO: add integration-specific validation to ensure that each
// integration has the correct fields populated in [Integration] // integration has the correct fields populated in [Integration]
try {
const { const {
environment, environment,
isActive, isActive,
@@ -97,7 +82,7 @@ export const updateIntegration = async (req: Request, res: Response) => {
owner, // github-specific integration param owner, // github-specific integration param
} = req.body; } = req.body;
integration = await Integration.findOneAndUpdate( const integration = await Integration.findOneAndUpdate(
{ {
_id: req.integration._id, _id: req.integration._id,
}, },
@@ -123,13 +108,6 @@ export const updateIntegration = async (req: Request, res: Response) => {
}), }),
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to update integration",
});
}
return res.status(200).send({ return res.status(200).send({
integration, integration,
@@ -144,22 +122,13 @@ export const updateIntegration = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const deleteIntegration = async (req: Request, res: Response) => { export const deleteIntegration = async (req: Request, res: Response) => {
let integration;
try {
const { integrationId } = req.params; const { integrationId } = req.params;
integration = await Integration.findOneAndDelete({ const integration = await Integration.findOneAndDelete({
_id: integrationId, _id: integrationId,
}); });
if (!integration) throw new Error("Failed to find integration"); if (!integration) throw new Error("Failed to find integration");
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to delete integration",
});
}
return res.status(200).send({ return res.status(200).send({
integration, integration,
+1 -19
View File
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Key } from '../../models'; import { Key } from '../../models';
import { findMembership } from '../../helpers/membership'; import { findMembership } from '../../helpers/membership';
@@ -11,7 +10,6 @@ import { findMembership } from '../../helpers/membership';
* @returns * @returns
*/ */
export const uploadKey = async (req: Request, res: Response) => { export const uploadKey = async (req: Request, res: Response) => {
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { key } = req.body; const { key } = req.body;
@@ -32,13 +30,6 @@ export const uploadKey = async (req: Request, res: Response) => {
receiver: key.userId, receiver: key.userId,
workspace: workspaceId workspace: workspaceId
}).save(); }).save();
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to upload key to workspace'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully uploaded key to workspace' message: 'Successfully uploaded key to workspace'
@@ -52,25 +43,16 @@ export const uploadKey = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getLatestKey = async (req: Request, res: Response) => { export const getLatestKey = async (req: Request, res: Response) => {
let latestKey;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
// get latest key // get latest key
latestKey = await Key.find({ const latestKey = await Key.find({
workspace: workspaceId, workspace: workspaceId,
receiver: req.user._id receiver: req.user._id
}) })
.sort({ createdAt: -1 }) .sort({ createdAt: -1 })
.limit(1) .limit(1)
.populate('sender', '+publicKey'); .populate('sender', '+publicKey');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get latest key'
});
}
const resObj: any = {}; const resObj: any = {};
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { Membership, MembershipOrg, User, Key } from '../../models'; import { Membership, MembershipOrg, User, Key } from '../../models';
import { import {
@@ -16,9 +15,7 @@ import { getSiteURL } from '../../config';
* @returns * @returns
*/ */
export const validateMembership = async (req: Request, res: Response) => { export const validateMembership = async (req: Request, res: Response) => {
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
// validate membership // validate membership
const membership = await findMembership({ const membership = await findMembership({
user: req.user._id, user: req.user._id,
@@ -28,13 +25,6 @@ export const validateMembership = async (req: Request, res: Response) => {
if (!membership) { if (!membership) {
throw new Error('Failed to validate membership'); throw new Error('Failed to validate membership');
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed workspace connection check'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Workspace membership confirmed' message: 'Workspace membership confirmed'
@@ -48,8 +38,6 @@ export const validateMembership = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const deleteMembership = async (req: Request, res: Response) => { export const deleteMembership = async (req: Request, res: Response) => {
let deletedMembership;
try {
const { membershipId } = req.params; const { membershipId } = req.params;
// check if membership to delete exists // check if membership to delete exists
@@ -80,16 +68,9 @@ export const deleteMembership = async (req: Request, res: Response) => {
} }
// delete workspace membership // delete workspace membership
deletedMembership = await deleteMember({ const deletedMembership = await deleteMember({
membershipId: membershipToDelete._id.toString() membershipId: membershipToDelete._id.toString()
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete membership'
});
}
return res.status(200).send({ return res.status(200).send({
deletedMembership deletedMembership
@@ -103,8 +84,6 @@ export const deleteMembership = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const changeMembershipRole = async (req: Request, res: Response) => { export const changeMembershipRole = async (req: Request, res: Response) => {
let membershipToChangeRole;
try {
const { membershipId } = req.params; const { membershipId } = req.params;
const { role } = req.body; const { role } = req.body;
@@ -113,7 +92,7 @@ export const changeMembershipRole = async (req: Request, res: Response) => {
} }
// validate target membership // validate target membership
membershipToChangeRole = await findMembership({ const membershipToChangeRole = await findMembership({
_id: membershipId _id: membershipId
}); });
@@ -139,13 +118,6 @@ export const changeMembershipRole = async (req: Request, res: Response) => {
membershipToChangeRole.role = role; membershipToChangeRole.role = role;
await membershipToChangeRole.save(); await membershipToChangeRole.save();
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to change membership role'
});
}
return res.status(200).send({ return res.status(200).send({
membership: membershipToChangeRole membership: membershipToChangeRole
@@ -159,12 +131,10 @@ export const changeMembershipRole = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const inviteUserToWorkspace = async (req: Request, res: Response) => { export const inviteUserToWorkspace = async (req: Request, res: Response) => {
let invitee, latestKey;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { email }: { email: string } = req.body; const { email }: { email: string } = req.body;
invitee = await User.findOne({ const invitee = await User.findOne({
email email
}).select('+publicKey'); }).select('+publicKey');
@@ -193,7 +163,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
throw new Error("Failed to validate invitee's organization membership"); throw new Error("Failed to validate invitee's organization membership");
// get latest key // get latest key
latestKey = await Key.findOne({ const latestKey = await Key.findOne({
workspace: workspaceId, workspace: workspaceId,
receiver: req.user._id receiver: req.user._id
}) })
@@ -218,13 +188,6 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
callback_url: (await getSiteURL()) + '/login' callback_url: (await getSiteURL()) + '/login'
} }
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to invite user to workspace'
});
}
return res.status(200).send({ return res.status(200).send({
invitee, invitee,
@@ -1,6 +1,5 @@
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { MembershipOrg, Organization, User } from '../../models'; import { MembershipOrg, Organization, User } from '../../models';
import { deleteMembershipOrg as deleteMemberFromOrg } from '../../helpers/membershipOrg'; import { deleteMembershipOrg as deleteMemberFromOrg } from '../../helpers/membershipOrg';
import { createToken } from '../../helpers/auth'; import { createToken } from '../../helpers/auth';
@@ -17,12 +16,10 @@ import { getSiteURL, getJwtSignupLifetime, getJwtSignupSecret, getSmtpConfigured
* @returns * @returns
*/ */
export const deleteMembershipOrg = async (req: Request, res: Response) => { export const deleteMembershipOrg = async (req: Request, res: Response) => {
let membershipOrgToDelete;
try {
const { membershipOrgId } = req.params; const { membershipOrgId } = req.params;
// check if organization membership to delete exists // check if organization membership to delete exists
membershipOrgToDelete = await MembershipOrg.findOne({ const membershipOrgToDelete = await MembershipOrg.findOne({
_id: membershipOrgId _id: membershipOrgId
}).populate('user'); }).populate('user');
@@ -56,13 +53,6 @@ export const deleteMembershipOrg = async (req: Request, res: Response) => {
await updateSubscriptionOrgQuantity({ await updateSubscriptionOrgQuantity({
organizationId: membershipOrg.organization.toString() organizationId: membershipOrg.organization.toString()
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete organization membership'
});
}
return membershipOrgToDelete; return membershipOrgToDelete;
}; };
@@ -78,14 +68,6 @@ export const changeMembershipOrgRole = async (req: Request, res: Response) => {
// [membershipOrgId] // [membershipOrgId]
let membershipToChangeRole; let membershipToChangeRole;
// try {
// } catch (err) {
// Sentry.setUser({ email: req.user.email });
// Sentry.captureException(err);
// return res.status(400).send({
// message: 'Failed to change organization membership role'
// });
// }
return res.status(200).send({ return res.status(200).send({
membershipOrg: membershipToChangeRole membershipOrg: membershipToChangeRole
@@ -101,7 +83,6 @@ export const changeMembershipOrgRole = async (req: Request, res: Response) => {
*/ */
export const inviteUserToOrganization = async (req: Request, res: Response) => { export const inviteUserToOrganization = async (req: Request, res: Response) => {
let invitee, inviteeMembershipOrg, completeInviteLink; let invitee, inviteeMembershipOrg, completeInviteLink;
try {
const { organizationId, inviteeEmail } = req.body; const { organizationId, inviteeEmail } = req.body;
const host = req.headers.host; const host = req.headers.host;
const siteUrl = `${req.protocol}://${host}`; const siteUrl = `${req.protocol}://${host}`;
@@ -194,13 +175,6 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => {
} }
await updateSubscriptionOrgQuantity({ organizationId }); await updateSubscriptionOrgQuantity({ organizationId });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to send organization invite'
});
}
return res.status(200).send({ return res.status(200).send({
message: `Sent an invite link to ${req.body.inviteeEmail}`, message: `Sent an invite link to ${req.body.inviteeEmail}`,
@@ -216,8 +190,7 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const verifyUserToOrganization = async (req: Request, res: Response) => { export const verifyUserToOrganization = async (req: Request, res: Response) => {
let user, token; let user;
try {
const { const {
email, email,
organizationId, organizationId,
@@ -266,20 +239,13 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => {
} }
// generate temporary signup token // generate temporary signup token
token = createToken({ const token = createToken({
payload: { payload: {
userId: user._id.toString() userId: user._id.toString()
}, },
expiresIn: await getJwtSignupLifetime(), expiresIn: await getJwtSignupLifetime(),
secret: await getJwtSignupSecret() secret: await getJwtSignupSecret()
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed email magic link verification for organization invitation'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully verified email', message: 'Successfully verified email',
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import Stripe from 'stripe'; import Stripe from 'stripe';
import { import {
@@ -15,21 +14,12 @@ import _ from 'lodash';
import { getStripeSecretKey, getSiteURL } from '../../config'; import { getStripeSecretKey, getSiteURL } from '../../config';
export const getOrganizations = async (req: Request, res: Response) => { export const getOrganizations = async (req: Request, res: Response) => {
let organizations; const organizations = (
try {
organizations = (
await MembershipOrg.find({ await MembershipOrg.find({
user: req.user._id, user: req.user._id,
status: ACCEPTED status: ACCEPTED
}).populate('organization') }).populate('organization')
).map((m) => m.organization); ).map((m) => m.organization);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get organizations'
});
}
return res.status(200).send({ return res.status(200).send({
organizations organizations
@@ -44,8 +34,6 @@ export const getOrganizations = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const createOrganization = async (req: Request, res: Response) => { export const createOrganization = async (req: Request, res: Response) => {
let organization;
try {
const { organizationName } = req.body; const { organizationName } = req.body;
if (organizationName.length < 1) { if (organizationName.length < 1) {
@@ -53,7 +41,7 @@ export const createOrganization = async (req: Request, res: Response) => {
} }
// create organization and add user as member // create organization and add user as member
organization = await create({ const organization = await create({
email: req.user.email, email: req.user.email,
name: organizationName name: organizationName
}); });
@@ -64,13 +52,6 @@ export const createOrganization = async (req: Request, res: Response) => {
roles: [OWNER], roles: [OWNER],
statuses: [ACCEPTED] statuses: [ACCEPTED]
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to create organization'
});
}
return res.status(200).send({ return res.status(200).send({
organization organization
@@ -84,17 +65,7 @@ export const createOrganization = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getOrganization = async (req: Request, res: Response) => { export const getOrganization = async (req: Request, res: Response) => {
let organization; const organization = req.organization
try {
organization = req.organization
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to find organization'
});
}
return res.status(200).send({ return res.status(200).send({
organization organization
}); });
@@ -107,20 +78,11 @@ export const getOrganization = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getOrganizationMembers = async (req: Request, res: Response) => { export const getOrganizationMembers = async (req: Request, res: Response) => {
let users;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
users = await MembershipOrg.find({ const users = await MembershipOrg.find({
organization: organizationId organization: organizationId
}).populate('user', '+publicKey'); }).populate('user', '+publicKey');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get organization members'
});
}
return res.status(200).send({ return res.status(200).send({
users users
@@ -137,8 +99,6 @@ export const getOrganizationWorkspaces = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let workspaces;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
const workspacesSet = new Set( const workspacesSet = new Set(
@@ -152,20 +112,13 @@ export const getOrganizationWorkspaces = async (
).map((w) => w._id.toString()) ).map((w) => w._id.toString())
); );
workspaces = ( const workspaces = (
await Membership.find({ await Membership.find({
user: req.user._id user: req.user._id
}).populate('workspace') }).populate('workspace')
) )
.filter((m) => workspacesSet.has(m.workspace._id.toString())) .filter((m) => workspacesSet.has(m.workspace._id.toString()))
.map((m) => m.workspace); .map((m) => m.workspace);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get my workspaces'
});
}
return res.status(200).send({ return res.status(200).send({
workspaces workspaces
@@ -179,12 +132,10 @@ export const getOrganizationWorkspaces = async (
* @returns * @returns
*/ */
export const changeOrganizationName = async (req: Request, res: Response) => { export const changeOrganizationName = async (req: Request, res: Response) => {
let organization;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
const { name } = req.body; const { name } = req.body;
organization = await Organization.findOneAndUpdate( const organization = await Organization.findOneAndUpdate(
{ {
_id: organizationId _id: organizationId
}, },
@@ -195,13 +146,6 @@ export const changeOrganizationName = async (req: Request, res: Response) => {
new: true new: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to change organization name'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully changed organization name', message: 'Successfully changed organization name',
@@ -219,20 +163,11 @@ export const getOrganizationIncidentContacts = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let incidentContactsOrg;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
incidentContactsOrg = await IncidentContactOrg.find({ const incidentContactsOrg = await IncidentContactOrg.find({
organization: organizationId organization: organizationId
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get organization incident contacts'
});
}
return res.status(200).send({ return res.status(200).send({
incidentContactsOrg incidentContactsOrg
@@ -249,23 +184,14 @@ export const addOrganizationIncidentContact = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let incidentContactOrg;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
const { email } = req.body; const { email } = req.body;
incidentContactOrg = await IncidentContactOrg.findOneAndUpdate( const incidentContactOrg = await IncidentContactOrg.findOneAndUpdate(
{ email, organization: organizationId }, { email, organization: organizationId },
{ email, organization: organizationId }, { email, organization: organizationId },
{ upsert: true, new: true } { upsert: true, new: true }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to add incident contact for organization'
});
}
return res.status(200).send({ return res.status(200).send({
incidentContactOrg incidentContactOrg
@@ -282,22 +208,13 @@ export const deleteOrganizationIncidentContact = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let incidentContactOrg;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
const { email } = req.body; const { email } = req.body;
incidentContactOrg = await IncidentContactOrg.findOneAndDelete({ const incidentContactOrg = await IncidentContactOrg.findOneAndDelete({
email, email,
organization: organizationId organization: organizationId
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete organization incident contact'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully deleted organization incident contact', message: 'Successfully deleted organization incident contact',
@@ -317,7 +234,6 @@ export const createOrganizationPortalSession = async (
res: Response res: Response
) => { ) => {
let session; let session;
try {
const stripe = new Stripe(await getStripeSecretKey(), { const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: '2022-08-01' apiVersion: '2022-08-01'
}); });
@@ -345,13 +261,6 @@ export const createOrganizationPortalSession = async (
} }
return res.status(200).send({ url: session.url }); return res.status(200).send({ url: session.url });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to redirect to organization billing portal'
});
}
}; };
/** /**
@@ -364,22 +273,13 @@ export const getOrganizationSubscriptions = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let subscriptions;
try {
const stripe = new Stripe(await getStripeSecretKey(), { const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: '2022-08-01' apiVersion: '2022-08-01'
}); });
subscriptions = await stripe.subscriptions.list({ const subscriptions = await stripe.subscriptions.list({
customer: req.organization.customerId customer: req.organization.customerId
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get organization subscriptions'
});
}
return res.status(200).send({ return res.status(200).send({
subscriptions subscriptions
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const jsrp = require('jsrp'); const jsrp = require('jsrp');
import * as bigintConversion from 'bigint-conversion'; import * as bigintConversion from 'bigint-conversion';
@@ -19,9 +18,7 @@ import { getSiteURL, getJwtSignupLifetime, getJwtSignupSecret } from '../../conf
* @returns * @returns
*/ */
export const emailPasswordReset = async (req: Request, res: Response) => { export const emailPasswordReset = async (req: Request, res: Response) => {
let email: string; const email = req.body.email;
try {
email = req.body.email;
const user = await User.findOne({ email }).select('+publicKey'); const user = await User.findOne({ email }).select('+publicKey');
if (!user || !user?.publicKey) { if (!user || !user?.publicKey) {
@@ -47,13 +44,6 @@ export const emailPasswordReset = async (req: Request, res: Response) => {
callback_url: (await getSiteURL()) + '/password-reset' callback_url: (await getSiteURL()) + '/password-reset'
} }
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to send email for account recovery'
});
}
return res.status(200).send({ return res.status(200).send({
message: `Sent an email for account recovery to ${email}` message: `Sent an email for account recovery to ${email}`
@@ -67,11 +57,9 @@ export const emailPasswordReset = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const emailPasswordResetVerify = async (req: Request, res: Response) => { export const emailPasswordResetVerify = async (req: Request, res: Response) => {
let user, token;
try {
const { email, code } = req.body; const { email, code } = req.body;
user = await User.findOne({ email }).select('+publicKey'); const user = await User.findOne({ email }).select('+publicKey');
if (!user || !user?.publicKey) { if (!user || !user?.publicKey) {
// case: user doesn't exist with email [email] or // case: user doesn't exist with email [email] or
// hasn't even completed their account // hasn't even completed their account
@@ -87,20 +75,13 @@ export const emailPasswordResetVerify = async (req: Request, res: Response) => {
}); });
// generate temporary password-reset token // generate temporary password-reset token
token = createToken({ const token = createToken({
payload: { payload: {
userId: user._id.toString() userId: user._id.toString()
}, },
expiresIn: await getJwtSignupLifetime(), expiresIn: await getJwtSignupLifetime(),
secret: await getJwtSignupSecret() secret: await getJwtSignupSecret()
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed email verification for password reset'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully verified email', message: 'Successfully verified email',
@@ -117,7 +98,6 @@ export const emailPasswordResetVerify = async (req: Request, res: Response) => {
*/ */
export const srp1 = async (req: Request, res: Response) => { export const srp1 = async (req: Request, res: Response) => {
// return salt, serverPublicKey as part of first step of SRP protocol // return salt, serverPublicKey as part of first step of SRP protocol
try {
const { clientPublicKey } = req.body; const { clientPublicKey } = req.body;
const user = await User.findOne({ const user = await User.findOne({
email: req.user.email email: req.user.email
@@ -147,13 +127,6 @@ export const srp1 = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed to start change password process'
});
}
}; };
/** /**
@@ -165,7 +138,6 @@ export const srp1 = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const changePassword = async (req: Request, res: Response) => { export const changePassword = async (req: Request, res: Response) => {
try {
const { const {
clientProof, clientProof,
protectedKey, protectedKey,
@@ -232,13 +204,6 @@ export const changePassword = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed to change password. Try again?'
});
}
}; };
/** /**
@@ -252,7 +217,6 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => {
// requires verifying [clientProof] as part of second step of SRP protocol // requires verifying [clientProof] as part of second step of SRP protocol
// as initiated in /srp1 // as initiated in /srp1
try {
const { clientProof, encryptedPrivateKey, iv, tag, salt, verifier } = const { clientProof, encryptedPrivateKey, iv, tag, salt, verifier } =
req.body; req.body;
const user = await User.findOne({ const user = await User.findOne({
@@ -308,13 +272,6 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to update backup private key'
});
}
}; };
/** /**
@@ -324,20 +281,11 @@ export const createBackupPrivateKey = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getBackupPrivateKey = async (req: Request, res: Response) => { export const getBackupPrivateKey = async (req: Request, res: Response) => {
let backupPrivateKey; const backupPrivateKey = await BackupPrivateKey.findOne({
try {
backupPrivateKey = await BackupPrivateKey.findOne({
user: req.user._id user: req.user._id
}).select('+encryptedPrivateKey +iv +tag'); }).select('+encryptedPrivateKey +iv +tag');
if (!backupPrivateKey) throw new Error('Failed to find backup private key'); if (!backupPrivateKey) throw new Error('Failed to find backup private key');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get backup private key'
});
}
return res.status(200).send({ return res.status(200).send({
backupPrivateKey backupPrivateKey
@@ -345,7 +293,6 @@ export const getBackupPrivateKey = async (req: Request, res: Response) => {
} }
export const resetPassword = async (req: Request, res: Response) => { export const resetPassword = async (req: Request, res: Response) => {
try {
const { const {
protectedKey, protectedKey,
protectedKeyIV, protectedKeyIV,
@@ -374,13 +321,6 @@ export const resetPassword = async (req: Request, res: Response) => {
new: true new: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get backup private key'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully reset password' message: 'Successfully reset password'
+6 -36
View File
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { Key, Secret } from '../../models'; import { Key, Secret } from '../../models';
import { import {
@@ -37,8 +36,6 @@ interface PushSecret {
*/ */
export const pushSecrets = async (req: Request, res: Response) => { export const pushSecrets = async (req: Request, res: Response) => {
// upload (encrypted) secrets to workspace with id [workspaceId] // upload (encrypted) secrets to workspace with id [workspaceId]
try {
const postHogClient = await TelemetryService.getPostHogClient(); const postHogClient = await TelemetryService.getPostHogClient();
let { secrets }: { secrets: PushSecret[] } = req.body; let { secrets }: { secrets: PushSecret[] } = req.body;
const { keys, environment, channel } = req.body; const { keys, environment, channel } = req.body;
@@ -90,14 +87,6 @@ export const pushSecrets = async (req: Request, res: Response) => {
}) })
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to upload workspace secrets'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully uploaded workspace secrets' message: 'Successfully uploaded workspace secrets'
}); });
@@ -111,9 +100,6 @@ export const pushSecrets = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const pullSecrets = async (req: Request, res: Response) => { export const pullSecrets = async (req: Request, res: Response) => {
let secrets;
let key;
try {
const postHogClient = await TelemetryService.getPostHogClient(); const postHogClient = await TelemetryService.getPostHogClient();
const environment: string = req.query.environment as string; const environment: string = req.query.environment as string;
const channel: string = req.query.channel as string; const channel: string = req.query.channel as string;
@@ -125,7 +111,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
throw new Error('Failed to validate environment'); throw new Error('Failed to validate environment');
} }
secrets = await pull({ let secrets = await pull({
userId: req.user._id.toString(), userId: req.user._id.toString(),
workspaceId, workspaceId,
environment, environment,
@@ -133,7 +119,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
ipAddress: req.ip ipAddress: req.ip
}); });
key = await Key.findOne({ const key = await Key.findOne({
workspace: workspaceId, workspace: workspaceId,
receiver: req.user._id receiver: req.user._id
}) })
@@ -141,7 +127,8 @@ export const pullSecrets = async (req: Request, res: Response) => {
.populate('sender', '+publicKey'); .populate('sender', '+publicKey');
if (channel !== 'cli') { if (channel !== 'cli') {
secrets = reformatPullSecrets({ secrets }); // FIX: Fix this any
secrets = reformatPullSecrets({ secrets }) as any;
} }
if (postHogClient) { if (postHogClient) {
@@ -157,13 +144,6 @@ export const pullSecrets = async (req: Request, res: Response) => {
} }
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to pull workspace secrets'
});
}
return res.status(200).send({ return res.status(200).send({
secrets, secrets,
@@ -180,9 +160,6 @@ export const pullSecrets = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const pullSecretsServiceToken = async (req: Request, res: Response) => { export const pullSecretsServiceToken = async (req: Request, res: Response) => {
let secrets;
let key;
try {
const postHogClient = await TelemetryService.getPostHogClient(); const postHogClient = await TelemetryService.getPostHogClient();
const environment: string = req.query.environment as string; const environment: string = req.query.environment as string;
const channel: string = req.query.channel as string; const channel: string = req.query.channel as string;
@@ -194,7 +171,7 @@ export const pullSecretsServiceToken = async (req: Request, res: Response) => {
throw new Error('Failed to validate environment'); throw new Error('Failed to validate environment');
} }
secrets = await pull({ const secrets = await pull({
userId: req.serviceToken.user._id.toString(), userId: req.serviceToken.user._id.toString(),
workspaceId, workspaceId,
environment, environment,
@@ -202,7 +179,7 @@ export const pullSecretsServiceToken = async (req: Request, res: Response) => {
ipAddress: req.ip ipAddress: req.ip
}); });
key = { const key = {
encryptedKey: req.serviceToken.encryptedKey, encryptedKey: req.serviceToken.encryptedKey,
nonce: req.serviceToken.nonce, nonce: req.serviceToken.nonce,
sender: { sender: {
@@ -225,13 +202,6 @@ export const pullSecretsServiceToken = async (req: Request, res: Response) => {
} }
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.serviceToken.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to pull workspace secrets'
});
}
return res.status(200).send({ return res.status(200).send({
secrets: reformatPullSecrets({ secrets }), secrets: reformatPullSecrets({ secrets }),
+1 -19
View File
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { User } from '../../models'; import { User } from '../../models';
import { import {
sendEmailVerification, sendEmailVerification,
@@ -17,9 +16,7 @@ import { getInviteOnlySignup, getJwtSignupLifetime, getJwtSignupSecret, getSmtpC
* @returns * @returns
*/ */
export const beginEmailSignup = async (req: Request, res: Response) => { export const beginEmailSignup = async (req: Request, res: Response) => {
let email: string; const email = req.body.email;
try {
email = req.body.email;
const user = await User.findOne({ email }).select('+publicKey'); const user = await User.findOne({ email }).select('+publicKey');
if (user && user?.publicKey) { if (user && user?.publicKey) {
@@ -32,13 +29,6 @@ export const beginEmailSignup = async (req: Request, res: Response) => {
// send send verification email // send send verification email
await sendEmailVerification({ email }); await sendEmailVerification({ email });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed to send email verification code'
});
}
return res.status(200).send({ return res.status(200).send({
message: `Sent an email verification code to ${email}` message: `Sent an email verification code to ${email}`
@@ -54,7 +44,6 @@ export const beginEmailSignup = async (req: Request, res: Response) => {
*/ */
export const verifyEmailSignup = async (req: Request, res: Response) => { export const verifyEmailSignup = async (req: Request, res: Response) => {
let user, token; let user, token;
try {
const { email, code } = req.body; const { email, code } = req.body;
// initialize user account // initialize user account
@@ -96,13 +85,6 @@ export const verifyEmailSignup = async (req: Request, res: Response) => {
expiresIn: await getJwtSignupLifetime(), expiresIn: await getJwtSignupLifetime(),
secret: await getJwtSignupSecret() secret: await getJwtSignupSecret()
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed email verification'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfuly verified email', message: 'Successfuly verified email',
+1 -11
View File
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import Stripe from 'stripe'; import Stripe from 'stripe';
import { getStripeSecretKey, getStripeWebhookSecret } from '../../config'; import { getStripeSecretKey, getStripeWebhookSecret } from '../../config';
@@ -10,26 +9,17 @@ import { getStripeSecretKey, getStripeWebhookSecret } from '../../config';
* @returns * @returns
*/ */
export const handleWebhook = async (req: Request, res: Response) => { export const handleWebhook = async (req: Request, res: Response) => {
let event;
try {
// check request for valid stripe signature // check request for valid stripe signature
const stripe = new Stripe(await getStripeSecretKey(), { const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: '2022-08-01' apiVersion: '2022-08-01'
}); });
const sig = req.headers['stripe-signature'] as string; const sig = req.headers['stripe-signature'] as string;
event = stripe.webhooks.constructEvent( const event = stripe.webhooks.constructEvent(
req.body, req.body,
sig, sig,
await getStripeWebhookSecret() await getStripeWebhookSecret()
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed to process webhook'
});
}
switch (event.type) { switch (event.type) {
case '': case '':
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { UserAction } from '../../models'; import { UserAction } from '../../models';
/** /**
@@ -11,11 +10,9 @@ import { UserAction } from '../../models';
export const addUserAction = async (req: Request, res: Response) => { export const addUserAction = async (req: Request, res: Response) => {
// add/record new action [action] for user with id [req.user._id] // add/record new action [action] for user with id [req.user._id]
let userAction;
try {
const { action } = req.body; const { action } = req.body;
userAction = await UserAction.findOneAndUpdate( const userAction = await UserAction.findOneAndUpdate(
{ {
user: req.user._id, user: req.user._id,
action action
@@ -26,13 +23,6 @@ export const addUserAction = async (req: Request, res: Response) => {
upsert: true upsert: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to record user action'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully recorded user action', message: 'Successfully recorded user action',
@@ -48,21 +38,12 @@ export const addUserAction = async (req: Request, res: Response) => {
*/ */
export const getUserAction = async (req: Request, res: Response) => { export const getUserAction = async (req: Request, res: Response) => {
// get user action [action] for user with id [req.user._id] // get user action [action] for user with id [req.user._id]
let userAction;
try {
const action: string = req.query.action as string; const action: string = req.query.action as string;
userAction = await UserAction.findOne({ const userAction = await UserAction.findOne({
user: req.user._id, user: req.user._id,
action action
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get user action'
});
}
return res.status(200).send({ return res.status(200).send({
userAction userAction
@@ -1,5 +1,4 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
import { import {
Workspace, Workspace,
Membership, Membership,
@@ -24,11 +23,9 @@ import { ADMIN } from "../../variables";
* @returns * @returns
*/ */
export const getWorkspacePublicKeys = async (req: Request, res: Response) => { export const getWorkspacePublicKeys = async (req: Request, res: Response) => {
let publicKeys;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
publicKeys = ( const publicKeys = (
await Membership.find({ await Membership.find({
workspace: workspaceId, workspace: workspaceId,
}).populate<{ user: IUser }>("user", "publicKey") }).populate<{ user: IUser }>("user", "publicKey")
@@ -38,13 +35,6 @@ export const getWorkspacePublicKeys = async (req: Request, res: Response) => {
userId: member.user._id, userId: member.user._id,
}; };
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace member public keys",
});
}
return res.status(200).send({ return res.status(200).send({
publicKeys, publicKeys,
@@ -58,20 +48,11 @@ export const getWorkspacePublicKeys = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getWorkspaceMemberships = async (req: Request, res: Response) => { export const getWorkspaceMemberships = async (req: Request, res: Response) => {
let users;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
users = await Membership.find({ const users = await Membership.find({
workspace: workspaceId, workspace: workspaceId,
}).populate("user", "+publicKey"); }).populate("user", "+publicKey");
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace members",
});
}
return res.status(200).send({ return res.status(200).send({
users, users,
@@ -85,20 +66,11 @@ export const getWorkspaceMemberships = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getWorkspaces = async (req: Request, res: Response) => { export const getWorkspaces = async (req: Request, res: Response) => {
let workspaces; const workspaces = (
try {
workspaces = (
await Membership.find({ await Membership.find({
user: req.user._id, user: req.user._id,
}).populate("workspace") }).populate("workspace")
).map((m) => m.workspace); ).map((m) => m.workspace);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspaces",
});
}
return res.status(200).send({ return res.status(200).send({
workspaces, workspaces,
@@ -112,20 +84,11 @@ export const getWorkspaces = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getWorkspace = async (req: Request, res: Response) => { export const getWorkspace = async (req: Request, res: Response) => {
let workspace;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
workspace = await Workspace.findOne({ const workspace = await Workspace.findOne({
_id: workspaceId, _id: workspaceId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace",
});
}
return res.status(200).send({ return res.status(200).send({
workspace, workspace,
@@ -140,8 +103,6 @@ export const getWorkspace = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const createWorkspace = async (req: Request, res: Response) => { export const createWorkspace = async (req: Request, res: Response) => {
let workspace;
try {
const { workspaceName, organizationId } = req.body; const { workspaceName, organizationId } = req.body;
// validate organization membership // validate organization membership
@@ -159,7 +120,7 @@ export const createWorkspace = async (req: Request, res: Response) => {
} }
// create workspace and add user as member // create workspace and add user as member
workspace = await create({ const workspace = await create({
name: workspaceName, name: workspaceName,
organizationId, organizationId,
}); });
@@ -169,13 +130,6 @@ export const createWorkspace = async (req: Request, res: Response) => {
workspaceId: workspace._id.toString(), workspaceId: workspace._id.toString(),
roles: [ADMIN], roles: [ADMIN],
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to create workspace",
});
}
return res.status(200).send({ return res.status(200).send({
workspace, workspace,
@@ -189,20 +143,12 @@ export const createWorkspace = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const deleteWorkspace = async (req: Request, res: Response) => { export const deleteWorkspace = async (req: Request, res: Response) => {
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
// delete workspace // delete workspace
await deleteWork({ await deleteWork({
id: workspaceId, id: workspaceId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to delete workspace",
});
}
return res.status(200).send({ return res.status(200).send({
message: "Successfully deleted workspace", message: "Successfully deleted workspace",
@@ -216,12 +162,10 @@ export const deleteWorkspace = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const changeWorkspaceName = async (req: Request, res: Response) => { export const changeWorkspaceName = async (req: Request, res: Response) => {
let workspace;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { name } = req.body; const { name } = req.body;
workspace = await Workspace.findOneAndUpdate( const workspace = await Workspace.findOneAndUpdate(
{ {
_id: workspaceId, _id: workspaceId,
}, },
@@ -232,13 +176,6 @@ export const changeWorkspaceName = async (req: Request, res: Response) => {
new: true, new: true,
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to change workspace name",
});
}
return res.status(200).send({ return res.status(200).send({
message: "Successfully changed workspace name", message: "Successfully changed workspace name",
@@ -253,20 +190,11 @@ export const changeWorkspaceName = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const getWorkspaceIntegrations = async (req: Request, res: Response) => { export const getWorkspaceIntegrations = async (req: Request, res: Response) => {
let integrations;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
integrations = await Integration.find({ const integrations = await Integration.find({
workspace: workspaceId, workspace: workspaceId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace integrations",
});
}
return res.status(200).send({ return res.status(200).send({
integrations, integrations,
@@ -283,20 +211,11 @@ export const getWorkspaceIntegrationAuthorizations = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let authorizations;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
authorizations = await IntegrationAuth.find({ const authorizations = await IntegrationAuth.find({
workspace: workspaceId, workspace: workspaceId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace integration authorizations",
});
}
return res.status(200).send({ return res.status(200).send({
authorizations, authorizations,
@@ -313,21 +232,12 @@ export const getWorkspaceServiceTokens = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let serviceTokens;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
// ?? FIX. // ?? FIX.
serviceTokens = await ServiceToken.find({ const serviceTokens = await ServiceToken.find({
user: req.user._id, user: req.user._id,
workspace: workspaceId, workspace: workspaceId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace service tokens",
});
}
return res.status(200).send({ return res.status(200).send({
serviceTokens, serviceTokens,
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import crypto from 'crypto'; import crypto from 'crypto';
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
@@ -14,18 +13,9 @@ import { getSaltRounds } from '../../config';
* @returns * @returns
*/ */
export const getAPIKeyData = async (req: Request, res: Response) => { export const getAPIKeyData = async (req: Request, res: Response) => {
let apiKeyData; const apiKeyData = await APIKeyData.find({
try {
apiKeyData = await APIKeyData.find({
user: req.user._id user: req.user._id
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get API key data'
});
}
return res.status(200).send({ return res.status(200).send({
apiKeyData apiKeyData
@@ -38,8 +28,6 @@ export const getAPIKeyData = async (req: Request, res: Response) => {
* @param res * @param res
*/ */
export const createAPIKeyData = async (req: Request, res: Response) => { export const createAPIKeyData = async (req: Request, res: Response) => {
let apiKey, apiKeyData;
try {
const { name, expiresIn } = req.body; const { name, expiresIn } = req.body;
const secret = crypto.randomBytes(16).toString('hex'); const secret = crypto.randomBytes(16).toString('hex');
@@ -48,7 +36,7 @@ export const createAPIKeyData = async (req: Request, res: Response) => {
const expiresAt = new Date(); const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn); expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
apiKeyData = await new APIKeyData({ let apiKeyData = await new APIKeyData({
name, name,
lastUsed: new Date(), lastUsed: new Date(),
expiresAt, expiresAt,
@@ -57,19 +45,12 @@ export const createAPIKeyData = async (req: Request, res: Response) => {
}).save(); }).save();
// return api key data without sensitive data // return api key data without sensitive data
apiKeyData = await APIKeyData.findById(apiKeyData._id); // FIX: fix this any
apiKeyData = await APIKeyData.findById(apiKeyData._id) as any
if (!apiKeyData) throw new Error('Failed to find API key data'); if (!apiKeyData) throw new Error('Failed to find API key data');
apiKey = `ak.${apiKeyData._id.toString()}.${secret}`; const apiKey = `ak.${apiKeyData._id.toString()}.${secret}`;
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to API key data'
});
}
return res.status(200).send({ return res.status(200).send({
apiKey, apiKey,
@@ -84,19 +65,8 @@ export const createAPIKeyData = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const deleteAPIKeyData = async (req: Request, res: Response) => { export const deleteAPIKeyData = async (req: Request, res: Response) => {
let apiKeyData;
try {
const { apiKeyDataId } = req.params; const { apiKeyDataId } = req.params;
const apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId);
apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete API key data'
});
}
return res.status(200).send({ return res.status(200).send({
apiKeyData apiKeyData
+1 -26
View File
@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-var-requires */
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import * as Sentry from '@sentry/node';
import * as bigintConversion from 'bigint-conversion'; import * as bigintConversion from 'bigint-conversion';
const jsrp = require('jsrp'); const jsrp = require('jsrp');
import { User, LoginSRPDetail } from '../../models'; import { User, LoginSRPDetail } from '../../models';
@@ -35,7 +34,6 @@ declare module 'jsonwebtoken' {
* @returns * @returns
*/ */
export const login1 = async (req: Request, res: Response) => { export const login1 = async (req: Request, res: Response) => {
try {
const { const {
email, email,
clientPublicKey clientPublicKey
@@ -69,13 +67,7 @@ export const login1 = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to start authentication process'
});
}
}; };
/** /**
@@ -86,8 +78,6 @@ export const login1 = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const login2 = async (req: Request, res: Response) => { export const login2 = async (req: Request, res: Response) => {
try {
if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' }); if (!req.headers['user-agent']) throw InternalServerError({ message: 'User-Agent header is required' });
const { email, clientProof } = req.body; const { email, clientProof } = req.body;
@@ -222,13 +212,6 @@ export const login2 = async (req: Request, res: Response) => {
}); });
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to authenticate. Try again?'
});
}
}; };
/** /**
@@ -237,7 +220,6 @@ export const login2 = async (req: Request, res: Response) => {
* @param res * @param res
*/ */
export const sendMfaToken = async (req: Request, res: Response) => { export const sendMfaToken = async (req: Request, res: Response) => {
try {
const { email } = req.body; const { email } = req.body;
const code = await TokenService.createToken({ const code = await TokenService.createToken({
@@ -254,13 +236,6 @@ export const sendMfaToken = async (req: Request, res: Response) => {
code code
} }
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to send MFA code'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully sent new MFA code' message: 'Successfully sent new MFA code'
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { import {
Secret, Secret,
ServiceToken, ServiceToken,
@@ -25,7 +24,6 @@ export const createWorkspaceEnvironment = async (
) => { ) => {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { environmentName, environmentSlug } = req.body; const { environmentName, environmentSlug } = req.body;
try {
const workspace = await Workspace.findById(workspaceId).exec(); const workspace = await Workspace.findById(workspaceId).exec();
if ( if (
!workspace || !workspace ||
@@ -41,13 +39,6 @@ export const createWorkspaceEnvironment = async (
slug: environmentSlug.toLowerCase(), slug: environmentSlug.toLowerCase(),
}); });
await workspace.save(); await workspace.save();
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to create new workspace environment',
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully created new environment', message: 'Successfully created new environment',
@@ -72,7 +63,6 @@ export const renameWorkspaceEnvironment = async (
) => { ) => {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { environmentName, environmentSlug, oldEnvironmentSlug } = req.body; const { environmentName, environmentSlug, oldEnvironmentSlug } = req.body;
try {
// user should pass both new slug and env name // user should pass both new slug and env name
if (!environmentSlug || !environmentName) { if (!environmentSlug || !environmentName) {
throw new Error('Invalid environment given.'); throw new Error('Invalid environment given.');
@@ -133,13 +123,6 @@ export const renameWorkspaceEnvironment = async (
{ arrayFilters: [{ "element.environmentSlug": oldEnvironmentSlug }] } { arrayFilters: [{ "element.environmentSlug": oldEnvironmentSlug }] }
) )
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to update workspace environment',
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully update environment', message: 'Successfully update environment',
@@ -163,7 +146,6 @@ export const deleteWorkspaceEnvironment = async (
) => { ) => {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { environmentSlug } = req.body; const { environmentSlug } = req.body;
try {
// atomic update the env to avoid conflict // atomic update the env to avoid conflict
const workspace = await Workspace.findById(workspaceId).exec(); const workspace = await Workspace.findById(workspaceId).exec();
if (!workspace) { if (!workspace) {
@@ -206,14 +188,6 @@ export const deleteWorkspaceEnvironment = async (
{ $pull: { deniedPermissions: { environmentSlug: environmentSlug } } } { $pull: { deniedPermissions: { environmentSlug: environmentSlug } } }
) )
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete workspace environment',
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully deleted environment', message: 'Successfully deleted environment',
workspace: workspaceId, workspace: workspaceId,
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { import {
MembershipOrg, MembershipOrg,
@@ -49,20 +48,11 @@ export const getOrganizationMemberships = async (req: Request, res: Response) =>
} }
} }
*/ */
let memberships;
try {
const { organizationId } = req.params; const { organizationId } = req.params;
memberships = await MembershipOrg.find({ const memberships = await MembershipOrg.find({
organization: organizationId organization: organizationId
}).populate('user', '+publicKey'); }).populate('user', '+publicKey');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get organization memberships'
});
}
return res.status(200).send({ return res.status(200).send({
memberships memberships
@@ -128,12 +118,10 @@ export const updateOrganizationMembership = async (req: Request, res: Response)
} }
} }
*/ */
let membership;
try {
const { membershipId } = req.params; const { membershipId } = req.params;
const { role } = req.body; const { role } = req.body;
membership = await MembershipOrg.findByIdAndUpdate( const membership = await MembershipOrg.findByIdAndUpdate(
membershipId, membershipId,
{ {
role role
@@ -141,13 +129,6 @@ export const updateOrganizationMembership = async (req: Request, res: Response)
new: true new: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to update organization membership'
});
}
return res.status(200).send({ return res.status(200).send({
membership membership
@@ -197,25 +178,16 @@ export const deleteOrganizationMembership = async (req: Request, res: Response)
} }
} }
*/ */
let membership;
try {
const { membershipId } = req.params; const { membershipId } = req.params;
// delete organization membership // delete organization membership
membership = await deleteMembershipOrg({ const membership = await deleteMembershipOrg({
membershipOrgId: membershipId membershipOrgId: membershipId
}); });
await updateSubscriptionOrgQuantity({ await updateSubscriptionOrgQuantity({
organizationId: membership.organization.toString() organizationId: membership.organization.toString()
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete organization membership'
});
}
return res.status(200).send({ return res.status(200).send({
membership membership
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import crypto from 'crypto'; import crypto from 'crypto';
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { User, MembershipOrg } from '../../models'; import { User, MembershipOrg } from '../../models';
import { completeAccount } from '../../helpers/user'; import { completeAccount } from '../../helpers/user';
import { import {
@@ -20,7 +19,6 @@ import { updateSubscriptionOrgQuantity } from '../../helpers/organization';
*/ */
export const completeAccountSignup = async (req: Request, res: Response) => { export const completeAccountSignup = async (req: Request, res: Response) => {
let user, token, refreshToken; let user, token, refreshToken;
try {
const { const {
email, email,
firstName, firstName,
@@ -143,13 +141,6 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
sameSite: 'strict', sameSite: 'strict',
secure: await getHttpsEnabled() secure: await getHttpsEnabled()
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to complete account setup'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully set up account', message: 'Successfully set up account',
@@ -167,7 +158,6 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
*/ */
export const completeAccountInvite = async (req: Request, res: Response) => { export const completeAccountInvite = async (req: Request, res: Response) => {
let user, token, refreshToken; let user, token, refreshToken;
try {
const { const {
email, email,
firstName, firstName,
@@ -259,13 +249,6 @@ export const completeAccountInvite = async (req: Request, res: Response) => {
sameSite: 'strict', sameSite: 'strict',
secure: await getHttpsEnabled() secure: await getHttpsEnabled()
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to complete account setup'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully set up account', message: 'Successfully set up account',
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { import {
Membership, Secret, Membership, Secret,
+3 -31
View File
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { import {
User, User,
MembershipOrg MembershipOrg
@@ -37,18 +36,9 @@ export const getMe = async (req: Request, res: Response) => {
} }
} }
*/ */
let user; const user = await User
try {
user = await User
.findById(req.user._id) .findById(req.user._id)
.select('+salt +publicKey +encryptedPrivateKey +iv +tag +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag'); .select('+salt +publicKey +encryptedPrivateKey +iv +tag +encryptionVersion +protectedKey +protectedKeyIV +protectedKeyTag');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get current user'
});
}
return res.status(200).send({ return res.status(200).send({
user user
@@ -64,8 +54,6 @@ export const getMe = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const updateMyMfaEnabled = async (req: Request, res: Response) => { export const updateMyMfaEnabled = async (req: Request, res: Response) => {
let user;
try {
const { isMfaEnabled }: { isMfaEnabled: boolean } = req.body; const { isMfaEnabled }: { isMfaEnabled: boolean } = req.body;
req.user.isMfaEnabled = isMfaEnabled; req.user.isMfaEnabled = isMfaEnabled;
@@ -79,14 +67,7 @@ export const updateMyMfaEnabled = async (req: Request, res: Response) => {
await req.user.save(); await req.user.save();
user = req.user; const user = req.user;
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to update current user's MFA status"
});
}
return res.status(200).send({ return res.status(200).send({
user user
@@ -126,20 +107,11 @@ export const getMyOrganizations = async (req: Request, res: Response) => {
} }
} }
*/ */
let organizations; const organizations = (
try {
organizations = (
await MembershipOrg.find({ await MembershipOrg.find({
user: req.user._id user: req.user._id
}).populate('organization') }).populate('organization')
).map((m) => m.organization); ).map((m) => m.organization);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get current user's organizations"
});
}
return res.status(200).send({ return res.status(200).send({
organizations organizations
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { import {
Workspace, Workspace,
@@ -47,7 +46,6 @@ interface V2PushSecret {
*/ */
export const pushWorkspaceSecrets = async (req: Request, res: Response) => { export const pushWorkspaceSecrets = async (req: Request, res: Response) => {
// upload (encrypted) secrets to workspace with id [workspaceId] // upload (encrypted) secrets to workspace with id [workspaceId]
try {
const postHogClient = await TelemetryService.getPostHogClient(); const postHogClient = await TelemetryService.getPostHogClient();
let { secrets }: { secrets: V2PushSecret[] } = req.body; let { secrets }: { secrets: V2PushSecret[] } = req.body;
const { keys, environment, channel } = req.body; const { keys, environment, channel } = req.body;
@@ -100,14 +98,6 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => {
}) })
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to upload workspace secrets'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully uploaded workspace secrets' message: 'Successfully uploaded workspace secrets'
}); });
@@ -121,8 +111,6 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => {
* @returns * @returns
*/ */
export const pullSecrets = async (req: Request, res: Response) => { export const pullSecrets = async (req: Request, res: Response) => {
let secrets;
try {
const postHogClient = await TelemetryService.getPostHogClient(); const postHogClient = await TelemetryService.getPostHogClient();
const environment: string = req.query.environment as string; const environment: string = req.query.environment as string;
const channel: string = req.query.channel as string; const channel: string = req.query.channel as string;
@@ -140,7 +128,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
throw new Error('Failed to validate environment'); throw new Error('Failed to validate environment');
} }
secrets = await pull({ let secrets = await pull({
userId, userId,
workspaceId, workspaceId,
environment, environment,
@@ -149,7 +137,8 @@ export const pullSecrets = async (req: Request, res: Response) => {
}); });
if (channel !== 'cli') { if (channel !== 'cli') {
secrets = reformatPullSecrets({ secrets }); // FIX: Fix this any
secrets = reformatPullSecrets({ secrets }) as any;
} }
if (postHogClient) { if (postHogClient) {
@@ -165,13 +154,6 @@ export const pullSecrets = async (req: Request, res: Response) => {
} }
}); });
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to pull workspace secrets'
});
}
return res.status(200).send({ return res.status(200).send({
secrets secrets
@@ -208,7 +190,6 @@ export const getWorkspaceKey = async (req: Request, res: Response) => {
} }
*/ */
let key; let key;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
key = await Key.findOne({ key = await Key.findOne({
@@ -217,13 +198,6 @@ export const getWorkspaceKey = async (req: Request, res: Response) => {
}).populate('sender', '+publicKey'); }).populate('sender', '+publicKey');
if (!key) throw new Error('Failed to find workspace key'); if (!key) throw new Error('Failed to find workspace key');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get workspace key'
});
}
return res.status(200).json(key); return res.status(200).json(key);
} }
@@ -231,24 +205,14 @@ export const getWorkspaceServiceTokenData = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let serviceTokenData;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
serviceTokenData = await ServiceTokenData const serviceTokenData = await ServiceTokenData
.find({ .find({
workspace: workspaceId workspace: workspaceId
}) })
.select('+encryptedKey +iv +tag'); .select('+encryptedKey +iv +tag');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get workspace service token data'
});
}
return res.status(200).send({ return res.status(200).send({
serviceTokenData serviceTokenData
}); });
@@ -294,20 +258,11 @@ export const getWorkspaceMemberships = async (req: Request, res: Response) => {
} }
} }
*/ */
let memberships;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
memberships = await Membership.find({ const memberships = await Membership.find({
workspace: workspaceId workspace: workspaceId
}).populate('user', '+publicKey'); }).populate('user', '+publicKey');
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to get workspace memberships'
});
}
return res.status(200).send({ return res.status(200).send({
memberships memberships
@@ -374,14 +329,12 @@ export const updateWorkspaceMembership = async (req: Request, res: Response) =>
} }
} }
*/ */
let membership;
try {
const { const {
membershipId membershipId
} = req.params; } = req.params;
const { role } = req.body; const { role } = req.body;
membership = await Membership.findByIdAndUpdate( const membership = await Membership.findByIdAndUpdate(
membershipId, membershipId,
{ {
role role
@@ -389,13 +342,6 @@ export const updateWorkspaceMembership = async (req: Request, res: Response) =>
new: true new: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to update workspace membership'
});
}
return res.status(200).send({ return res.status(200).send({
membership membership
@@ -445,13 +391,11 @@ export const deleteWorkspaceMembership = async (req: Request, res: Response) =>
} }
} }
*/ */
let membership;
try {
const { const {
membershipId membershipId
} = req.params; } = req.params;
membership = await Membership.findByIdAndDelete(membershipId); const membership = await Membership.findByIdAndDelete(membershipId);
if (!membership) throw new Error('Failed to delete workspace membership'); if (!membership) throw new Error('Failed to delete workspace membership');
@@ -459,13 +403,6 @@ export const deleteWorkspaceMembership = async (req: Request, res: Response) =>
receiver: membership.user, receiver: membership.user,
workspace: membership.workspace workspace: membership.workspace
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to delete workspace membership'
});
}
return res.status(200).send({ return res.status(200).send({
membership membership
@@ -479,12 +416,10 @@ export const deleteWorkspaceMembership = async (req: Request, res: Response) =>
* @returns * @returns
*/ */
export const toggleAutoCapitalization = async (req: Request, res: Response) => { export const toggleAutoCapitalization = async (req: Request, res: Response) => {
let workspace;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { autoCapitalization } = req.body; const { autoCapitalization } = req.body;
workspace = await Workspace.findOneAndUpdate( const workspace = await Workspace.findOneAndUpdate(
{ {
_id: workspaceId _id: workspaceId
}, },
@@ -495,13 +430,6 @@ export const toggleAutoCapitalization = async (req: Request, res: Response) => {
new: true new: true
} }
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to change autoCapitalization setting'
});
}
return res.status(200).send({ return res.status(200).send({
message: 'Successfully changed autoCapitalization setting', message: 'Successfully changed autoCapitalization setting',
@@ -1,5 +1,4 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import { Action, SecretVersion } from '../../models'; import { Action, SecretVersion } from '../../models';
import { ActionNotFoundError } from '../../../utils/errors'; import { ActionNotFoundError } from '../../../utils/errors';
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { EELicenseService } from '../../services'; import { EELicenseService } from '../../services';
import { getLicenseServerUrl } from '../../../config'; import { getLicenseServerUrl } from '../../../config';
@@ -12,7 +11,6 @@ import { licenseServerKeyRequest } from '../../../config/request';
* @returns * @returns
*/ */
export const getCloudProducts = async (req: Request, res: Response) => { export const getCloudProducts = async (req: Request, res: Response) => {
try {
const billingCycle = req.query['billing-cycle'] as string; const billingCycle = req.query['billing-cycle'] as string;
if (EELicenseService.instanceType === 'cloud') { if (EELicenseService.instanceType === 'cloud') {
@@ -22,10 +20,6 @@ export const getCloudProducts = async (req: Request, res: Response) => {
return res.status(200).send(data); return res.status(200).send(data);
} }
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
}
return res.status(200).send({ return res.status(200).send({
head: [], head: [],
@@ -1,5 +1,4 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
import { Secret } from "../../../models"; import { Secret } from "../../../models";
import { SecretVersion } from "../../models"; import { SecretVersion } from "../../models";
import { EESecretService } from "../../services"; import { EESecretService } from "../../services";
@@ -55,14 +54,12 @@ export const getSecretVersions = async (req: Request, res: Response) => {
} }
} }
*/ */
let secretVersions;
try {
const { secretId, workspaceId, environment, folderId } = req.params; const { secretId, workspaceId, environment, folderId } = req.params;
const offset: number = parseInt(req.query.offset as string); const offset: number = parseInt(req.query.offset as string);
const limit: number = parseInt(req.query.limit as string); const limit: number = parseInt(req.query.limit as string);
secretVersions = await SecretVersion.find({ const secretVersions = await SecretVersion.find({
secret: secretId, secret: secretId,
workspace: workspaceId, workspace: workspaceId,
environment, environment,
@@ -71,13 +68,6 @@ export const getSecretVersions = async (req: Request, res: Response) => {
.sort({ createdAt: -1 }) .sort({ createdAt: -1 })
.skip(offset) .skip(offset)
.limit(limit); .limit(limit);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get secret versions",
});
}
return res.status(200).send({ return res.status(200).send({
secretVersions, secretVersions,
@@ -139,8 +129,6 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
} }
} }
*/ */
let secret;
try {
const { secretId } = req.params; const { secretId } = req.params;
const { version } = req.body; const { version } = req.body;
@@ -164,13 +152,13 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
secretValueCiphertext, secretValueCiphertext,
secretValueIV, secretValueIV,
secretValueTag, secretValueTag,
folder,
algorithm, algorithm,
folder,
keyEncoding, keyEncoding,
} = oldSecretVersion; } = oldSecretVersion;
// update secret // update secret
secret = await Secret.findByIdAndUpdate( const secret = await Secret.findByIdAndUpdate(
secretId, secretId,
{ {
$inc: { $inc: {
@@ -225,13 +213,6 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
environment, environment,
folderId: folder, folderId: folder,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to roll back secret version",
});
}
return res.status(200).send({ return res.status(200).send({
secret, secret,
@@ -1,5 +1,4 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
import { import {
ISecretVersion, ISecretVersion,
SecretSnapshot, SecretSnapshot,
@@ -13,23 +12,14 @@ import {
* @returns * @returns
*/ */
export const getSecretSnapshot = async (req: Request, res: Response) => { export const getSecretSnapshot = async (req: Request, res: Response) => {
let secretSnapshot;
try {
const { secretSnapshotId } = req.params; const { secretSnapshotId } = req.params;
const secretSnapshot = await SecretSnapshot.findById(secretSnapshotId)
secretSnapshot = await SecretSnapshot.findById(secretSnapshotId)
.lean() .lean()
.populate<{ secretVersions: ISecretVersion[] }>("secretVersions") .populate<{ secretVersions: ISecretVersion[] }>("secretVersions")
.populate<{ folderVersion: TFolderRootVersionSchema }>("folderVersion"); .populate<{ folderVersion: TFolderRootVersionSchema }>("folderVersion");
if (!secretSnapshot) throw new Error("Failed to find secret snapshot"); if (!secretSnapshot) throw new Error("Failed to find secret snapshot");
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get secret snapshot",
});
}
const folderId = secretSnapshot.folderId; const folderId = secretSnapshot.folderId;
// to show only the folder required secrets // to show only the folder required secrets
secretSnapshot.secretVersions = secretSnapshot.secretVersions.filter( secretSnapshot.secretVersions = secretSnapshot.secretVersions.filter(
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import Stripe from 'stripe'; import Stripe from 'stripe';
import { getStripeSecretKey, getStripeWebhookSecret } from '../../../config'; import { getStripeSecretKey, getStripeWebhookSecret } from '../../../config';
@@ -10,26 +9,17 @@ import { getStripeSecretKey, getStripeWebhookSecret } from '../../../config';
* @returns * @returns
*/ */
export const handleWebhook = async (req: Request, res: Response) => { export const handleWebhook = async (req: Request, res: Response) => {
let event;
try {
const stripe = new Stripe(await getStripeSecretKey(), { const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: '2022-08-01' apiVersion: '2022-08-01'
}); });
// check request for valid stripe signature // check request for valid stripe signature
const sig = req.headers['stripe-signature'] as string; const sig = req.headers['stripe-signature'] as string;
event = stripe.webhooks.constructEvent( const event = stripe.webhooks.constructEvent(
req.body, req.body,
sig, sig,
await getStripeWebhookSecret() await getStripeWebhookSecret()
); );
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
error: 'Failed to process webhook'
});
}
switch (event.type) { switch (event.type) {
case '': case '':
@@ -1,5 +1,4 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
import { PipelineStage, Types } from "mongoose"; import { PipelineStage, Types } from "mongoose";
import { Secret } from "../../../models"; import { Secret } from "../../../models";
import { import {
@@ -69,15 +68,13 @@ export const getWorkspaceSecretSnapshots = async (
} }
} }
*/ */
let secretSnapshots;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { environment, folderId } = req.query; const { environment, folderId } = req.query;
const offset: number = parseInt(req.query.offset as string); const offset: number = parseInt(req.query.offset as string);
const limit: number = parseInt(req.query.limit as string); const limit: number = parseInt(req.query.limit as string);
secretSnapshots = await SecretSnapshot.find({ const secretSnapshots = await SecretSnapshot.find({
workspace: workspaceId, workspace: workspaceId,
environment, environment,
folderId: folderId || "root", folderId: folderId || "root",
@@ -85,13 +82,6 @@ export const getWorkspaceSecretSnapshots = async (
.sort({ createdAt: -1 }) .sort({ createdAt: -1 })
.skip(offset) .skip(offset)
.limit(limit); .limit(limit);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get secret snapshots",
});
}
return res.status(200).send({ return res.status(200).send({
secretSnapshots, secretSnapshots,
@@ -107,23 +97,14 @@ export const getWorkspaceSecretSnapshotsCount = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let count;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { environment, folderId } = req.query; const { environment, folderId } = req.query;
count = await SecretSnapshot.countDocuments({ const count = await SecretSnapshot.countDocuments({
workspace: workspaceId, workspace: workspaceId,
environment, environment,
folderId: folderId || "root", folderId: folderId || "root",
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to count number of secret snapshots",
});
}
return res.status(200).send({ return res.status(200).send({
count, count,
@@ -191,8 +172,6 @@ export const rollbackWorkspaceSecretSnapshot = async (
} }
*/ */
let secrets;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const { version, environment, folderId = "root" } = req.body; const { version, environment, folderId = "root" } = req.body;
@@ -376,7 +355,7 @@ export const rollbackWorkspaceSecretSnapshot = async (
}); });
// add secrets // add secrets
secrets = await Secret.insertMany( const secrets = await Secret.insertMany(
Object.keys(oldSecretVersionsObj).map((sv) => { Object.keys(oldSecretVersionsObj).map((sv) => {
const { const {
secret: secretId, secret: secretId,
@@ -501,13 +480,6 @@ export const rollbackWorkspaceSecretSnapshot = async (
environment, environment,
folderId, folderId,
}); });
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to roll back secret snapshot",
});
}
return res.status(200).send({ return res.status(200).send({
secrets, secrets,
@@ -587,8 +559,6 @@ export const getWorkspaceLogs = async (req: Request, res: Response) => {
} }
} }
*/ */
let logs;
try {
const { workspaceId } = req.params; const { workspaceId } = req.params;
const offset: number = parseInt(req.query.offset as string); const offset: number = parseInt(req.query.offset as string);
@@ -597,7 +567,7 @@ export const getWorkspaceLogs = async (req: Request, res: Response) => {
const userId: string = req.query.userId as string; const userId: string = req.query.userId as string;
const actionNames: string = req.query.actionNames as string; const actionNames: string = req.query.actionNames as string;
logs = await Log.find({ const logs = await Log.find({
workspace: workspaceId, workspace: workspaceId,
...(userId ? { user: userId } : {}), ...(userId ? { user: userId } : {}),
...(actionNames ...(actionNames
@@ -613,13 +583,6 @@ export const getWorkspaceLogs = async (req: Request, res: Response) => {
.limit(limit) .limit(limit)
.populate("actions") .populate("actions")
.populate("user serviceAccount serviceTokenData"); .populate("user serviceAccount serviceTokenData");
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: "Failed to get workspace logs",
});
}
return res.status(200).send({ return res.status(200).send({
logs, logs,
@@ -1,5 +1,4 @@
import NodeCache from 'node-cache'; import NodeCache from 'node-cache';
import * as Sentry from '@sentry/node';
import { import {
getLicenseKey, getLicenseKey,
getLicenseServerKey, getLicenseServerKey,
@@ -98,7 +97,6 @@ class EELicenseService {
const licenseServerKey = await getLicenseServerKey(); const licenseServerKey = await getLicenseServerKey();
const licenseKey = await getLicenseKey(); const licenseKey = await getLicenseKey();
try {
if (licenseServerKey) { if (licenseServerKey) {
// license server key is present -> validate it // license server key is present -> validate it
const token = await refreshLicenseServerKeyToken() const token = await refreshLicenseServerKeyToken()
@@ -123,11 +121,6 @@ class EELicenseService {
this.instanceType = 'enterprise-self-hosted'; this.instanceType = 'enterprise-self-hosted';
} }
} }
} catch (err) {
// case: self-hosted free
Sentry.setUser(null);
Sentry.captureException(err);
}
} }
public get isLicenseValid(): boolean { public get isLicenseValid(): boolean {
+5 -56
View File
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose'; import { Types } from 'mongoose';
import { import {
Bot, Bot,
@@ -48,8 +47,6 @@ const handleOAuthExchangeHelper = async ({
code: string; code: string;
environment: string; environment: string;
}) => { }) => {
let integrationAuth;
try {
const bot = await Bot.findOne({ const bot = await Bot.findOne({
workspace: workspaceId, workspace: workspaceId,
isActive: true isActive: true
@@ -77,7 +74,7 @@ const handleOAuthExchangeHelper = async ({
break; break;
} }
integrationAuth = await IntegrationAuth.findOneAndUpdate({ const integrationAuth = await IntegrationAuth.findOneAndUpdate({
workspace: workspaceId, workspace: workspaceId,
integration integration
}, update, { }, update, {
@@ -104,11 +101,6 @@ const handleOAuthExchangeHelper = async ({
accessExpiresAt: res.accessExpiresAt accessExpiresAt: res.accessExpiresAt
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to handle OAuth2 code-token exchange')
}
return integrationAuth; return integrationAuth;
} }
@@ -125,9 +117,7 @@ const syncIntegrationsHelper = async ({
workspaceId: Types.ObjectId; workspaceId: Types.ObjectId;
environment?: string; environment?: string;
}) => { }) => {
let integrations; const integrations = await Integration.find({
try {
integrations = await Integration.find({
workspace: workspaceId, workspace: workspaceId,
...(environment ? { ...(environment ? {
environment environment
@@ -162,11 +152,6 @@ const syncIntegrationsHelper = async ({
accessToken: access.accessToken accessToken: access.accessToken
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to integrations');
}
} }
/** /**
@@ -178,31 +163,19 @@ const syncIntegrationsHelper = async ({
* @param {String} refreshToken - decrypted refresh token * @param {String} refreshToken - decrypted refresh token
*/ */
const getIntegrationAuthRefreshHelper = async ({ integrationAuthId }: { integrationAuthId: Types.ObjectId }) => { const getIntegrationAuthRefreshHelper = async ({ integrationAuthId }: { integrationAuthId: Types.ObjectId }) => {
let refreshToken;
try {
const integrationAuth = await IntegrationAuth const integrationAuth = await IntegrationAuth
.findById(integrationAuthId) .findById(integrationAuthId)
.select('+refreshCiphertext +refreshIV +refreshTag'); .select('+refreshCiphertext +refreshIV +refreshTag');
if (!integrationAuth) throw UnauthorizedRequestError({message: 'Failed to locate Integration Authentication credentials'}); if (!integrationAuth) throw UnauthorizedRequestError({message: 'Failed to locate Integration Authentication credentials'});
refreshToken = await BotService.decryptSymmetric({ const refreshToken = await BotService.decryptSymmetric({
workspaceId: integrationAuth.workspace, workspaceId: integrationAuth.workspace,
ciphertext: integrationAuth.refreshCiphertext as string, ciphertext: integrationAuth.refreshCiphertext as string,
iv: integrationAuth.refreshIV as string, iv: integrationAuth.refreshIV as string,
tag: integrationAuth.refreshTag as string tag: integrationAuth.refreshTag as string
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
if(err instanceof RequestError)
throw err
else
throw new Error('Failed to get integration refresh token');
}
return refreshToken; return refreshToken;
} }
@@ -217,7 +190,6 @@ const syncIntegrationsHelper = async ({
const getIntegrationAuthAccessHelper = async ({ integrationAuthId }: { integrationAuthId: Types.ObjectId }) => { const getIntegrationAuthAccessHelper = async ({ integrationAuthId }: { integrationAuthId: Types.ObjectId }) => {
let accessId; let accessId;
let accessToken; let accessToken;
try {
const integrationAuth = await IntegrationAuth const integrationAuth = await IntegrationAuth
.findById(integrationAuthId) .findById(integrationAuthId)
.select('workspace integration +accessCiphertext +accessIV +accessTag +accessExpiresAt + refreshCiphertext +accessIdCiphertext +accessIdIV +accessIdTag'); .select('workspace integration +accessCiphertext +accessIV +accessTag +accessExpiresAt + refreshCiphertext +accessIdCiphertext +accessIdIV +accessIdTag');
@@ -254,15 +226,6 @@ const getIntegrationAuthAccessHelper = async ({ integrationAuthId }: { integrati
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
if(err instanceof RequestError)
throw err
else
throw new Error('Failed to get integration access token');
}
return ({ return ({
accessId, accessId,
accessToken accessToken
@@ -285,9 +248,7 @@ const setIntegrationAuthRefreshHelper = async ({
refreshToken: string; refreshToken: string;
}) => { }) => {
let integrationAuth; let integrationAuth = await IntegrationAuth
try {
integrationAuth = await IntegrationAuth
.findById(integrationAuthId); .findById(integrationAuthId);
if (!integrationAuth) throw new Error('Failed to find integration auth'); if (!integrationAuth) throw new Error('Failed to find integration auth');
@@ -308,11 +269,6 @@ const setIntegrationAuthRefreshHelper = async ({
}, { }, {
new: true new: true
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to set integration auth refresh token');
}
return integrationAuth; return integrationAuth;
} }
@@ -337,9 +293,7 @@ const setIntegrationAuthAccessHelper = async ({
accessToken: string; accessToken: string;
accessExpiresAt: Date | undefined; accessExpiresAt: Date | undefined;
}) => { }) => {
let integrationAuth; let integrationAuth = await IntegrationAuth.findById(integrationAuthId);
try {
integrationAuth = await IntegrationAuth.findById(integrationAuthId);
if (!integrationAuth) throw new Error('Failed to find integration auth'); if (!integrationAuth) throw new Error('Failed to find integration auth');
@@ -371,11 +325,6 @@ const setIntegrationAuthAccessHelper = async ({
}, { }, {
new: true new: true
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to save integration auth access token');
}
return integrationAuth; return integrationAuth;
} }
+9 -32
View File
@@ -1,7 +1,6 @@
import * as Sentry from '@sentry/node'; import { Types } from "mongoose";
import { Types } from 'mongoose'; import { Membership, Key } from "../models";
import { Membership, Key } from '../models'; import { MembershipNotFoundError, BadRequestError } from "../utils/errors";
import { MembershipNotFoundError, BadRequestError } from '../utils/errors';
/** /**
* Validate that user with id [userId] is a member of workspace with id [workspaceId] * Validate that user with id [userId] is a member of workspace with id [workspaceId]
@@ -18,23 +17,23 @@ const validateMembership = async ({
}: { }: {
userId: Types.ObjectId | string; userId: Types.ObjectId | string;
workspaceId: Types.ObjectId | string; workspaceId: Types.ObjectId | string;
acceptedRoles?: Array<'admin' | 'member'>; acceptedRoles?: Array<"admin" | "member">;
}) => { }) => {
const membership = await Membership.findOne({ const membership = await Membership.findOne({
user: userId, user: userId,
workspace: workspaceId, workspace: workspaceId,
}).populate('workspace'); }).populate("workspace");
if (!membership) { if (!membership) {
throw MembershipNotFoundError({ throw MembershipNotFoundError({
message: 'Failed to find workspace membership', message: "Failed to find workspace membership",
}); });
} }
if (acceptedRoles) { if (acceptedRoles) {
if (!acceptedRoles.includes(membership.role)) { if (!acceptedRoles.includes(membership.role)) {
throw BadRequestError({ throw BadRequestError({
message: 'Failed authorization for membership role', message: "Failed authorization for membership role",
}); });
} }
} }
@@ -48,15 +47,7 @@ const validateMembership = async ({
* @return {Object} membership - membership * @return {Object} membership - membership
*/ */
const findMembership = async (queryObj: any) => { const findMembership = async (queryObj: any) => {
let membership; const membership = await Membership.findOne(queryObj);
try {
membership = await Membership.findOne(queryObj);
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to find membership');
}
return membership; return membership;
}; };
@@ -77,7 +68,6 @@ const addMemberships = async ({
workspaceId: string; workspaceId: string;
roles: string[]; roles: string[];
}): Promise<void> => { }): Promise<void> => {
try {
const operations = userIds.map((userId, idx) => { const operations = userIds.map((userId, idx) => {
return { return {
updateOne: { updateOne: {
@@ -95,13 +85,7 @@ const addMemberships = async ({
}, },
}; };
}); });
await Membership.bulkWrite(operations as any); await Membership.bulkWrite(operations as any);
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to add users to workspace');
}
}; };
/** /**
@@ -110,9 +94,7 @@ const addMemberships = async ({
* @param {String} obj.membershipId - id of membership to delete * @param {String} obj.membershipId - id of membership to delete
*/ */
const deleteMembership = async ({ membershipId }: { membershipId: string }) => { const deleteMembership = async ({ membershipId }: { membershipId: string }) => {
let deletedMembership; const deletedMembership = await Membership.findOneAndDelete({
try {
deletedMembership = await Membership.findOneAndDelete({
_id: membershipId, _id: membershipId,
}); });
@@ -124,11 +106,6 @@ const deleteMembership = async ({ membershipId }: { membershipId: string }) => {
workspace: deletedMembership.workspace, workspace: deletedMembership.workspace,
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to delete membership');
}
return deletedMembership; return deletedMembership;
}; };
-6
View File
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import handlebars from 'handlebars'; import handlebars from 'handlebars';
@@ -26,7 +25,6 @@ const sendMail = async ({
substitutions: any; substitutions: any;
}) => { }) => {
if (await getSmtpConfigured()) { if (await getSmtpConfigured()) {
try {
const html = fs.readFileSync( const html = fs.readFileSync(
path.resolve(__dirname, '../templates/' + template), path.resolve(__dirname, '../templates/' + template),
'utf8' 'utf8'
@@ -40,10 +38,6 @@ const sendMail = async ({
subject: subjectLine, subject: subjectLine,
html: htmlToSend html: htmlToSend
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
}
} }
}; };
-15
View File
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { IUser } from '../models'; import { IUser } from '../models';
import { createOrganization } from './organization'; import { createOrganization } from './organization';
import { addMembershipsOrg } from './membershipOrg'; import { addMembershipsOrg } from './membershipOrg';
@@ -15,7 +14,6 @@ import { TOKEN_EMAIL_CONFIRMATION } from '../variables';
* @returns {Boolean} success - whether or not operation was successful * @returns {Boolean} success - whether or not operation was successful
*/ */
const sendEmailVerification = async ({ email }: { email: string }) => { const sendEmailVerification = async ({ email }: { email: string }) => {
try {
const token = await TokenService.createToken({ const token = await TokenService.createToken({
type: TOKEN_EMAIL_CONFIRMATION, type: TOKEN_EMAIL_CONFIRMATION,
email email
@@ -30,13 +28,6 @@ const sendEmailVerification = async ({ email }: { email: string }) => {
code: token code: token
} }
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error(
"Ouch. We weren't able to send your email verification code"
);
}
}; };
/** /**
@@ -52,17 +43,11 @@ const checkEmailVerification = async ({
email: string; email: string;
code: string; code: string;
}) => { }) => {
try {
await TokenService.validateToken({ await TokenService.validateToken({
type: TOKEN_EMAIL_CONFIRMATION, type: TOKEN_EMAIL_CONFIRMATION,
email, email,
token: code token: code
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Oops. We weren't able to verify");
}
}; };
/** /**
+1 -15
View File
@@ -1,4 +1,3 @@
import * as Sentry from '@sentry/node';
import { import {
Workspace, Workspace,
Bot, Bot,
@@ -23,10 +22,8 @@ const createWorkspace = async ({
name: string; name: string;
organizationId: string; organizationId: string;
}) => { }) => {
let workspace;
try {
// create workspace // create workspace
workspace = await new Workspace({ const workspace = await new Workspace({
name, name,
organization: organizationId, organization: organizationId,
autoCapitalization: true autoCapitalization: true
@@ -43,11 +40,6 @@ const createWorkspace = async ({
workspaceId: workspace._id workspaceId: workspace._id
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to create workspace');
}
return workspace; return workspace;
}; };
@@ -59,7 +51,6 @@ const createWorkspace = async ({
* @param {String} obj.id - id of workspace to delete * @param {String} obj.id - id of workspace to delete
*/ */
const deleteWorkspace = async ({ id }: { id: string }) => { const deleteWorkspace = async ({ id }: { id: string }) => {
try {
await Workspace.deleteOne({ _id: id }); await Workspace.deleteOne({ _id: id });
await Bot.deleteOne({ await Bot.deleteOne({
workspace: id workspace: id
@@ -73,11 +64,6 @@ const deleteWorkspace = async ({ id }: { id: string }) => {
await Key.deleteMany({ await Key.deleteMany({
workspace: id workspace: id
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to delete workspace');
}
}; };
export { export {
-100
View File
@@ -1,4 +1,3 @@
import * as Sentry from "@sentry/node";
import _ from 'lodash'; import _ from 'lodash';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { import {
@@ -61,7 +60,6 @@ const syncSecrets = async ({
accessId: string | null; accessId: string | null;
accessToken: string; accessToken: string;
}) => { }) => {
try {
switch (integration.integration) { switch (integration.integration) {
case INTEGRATION_AZURE_KEY_VAULT: case INTEGRATION_AZURE_KEY_VAULT:
await syncSecretsAzureKeyVault({ await syncSecretsAzureKeyVault({
@@ -166,11 +164,6 @@ const syncSecrets = async ({
}); });
break; break;
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to integration');
}
}; };
/** /**
@@ -189,7 +182,6 @@ const syncSecretsAzureKeyVault = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
interface GetAzureKeyVaultSecret { interface GetAzureKeyVaultSecret {
id: string; // secret URI id: string; // secret URI
attributes: { attributes: {
@@ -212,7 +204,6 @@ const syncSecretsAzureKeyVault = async ({
*/ */
const paginateAzureKeyVaultSecrets = async (url: string) => { const paginateAzureKeyVaultSecrets = async (url: string) => {
let result: GetAzureKeyVaultSecret[] = []; let result: GetAzureKeyVaultSecret[] = [];
try {
while (url) { while (url) {
const res = await standardRequest.get(url, { const res = await standardRequest.get(url, {
headers: { headers: {
@@ -225,11 +216,6 @@ const syncSecretsAzureKeyVault = async ({
url = res.data.nextLink; url = res.data.nextLink;
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
}
return result; return result;
} }
@@ -360,11 +346,6 @@ const syncSecretsAzureKeyVault = async ({
} }
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to Azure Key Vault');
}
}; };
/** /**
@@ -386,7 +367,6 @@ const syncSecretsAWSParameterStore = async ({
accessId: string | null; accessId: string | null;
accessToken: string; accessToken: string;
}) => { }) => {
try {
if (!accessId) return; if (!accessId) return;
AWS.config.update({ AWS.config.update({
@@ -462,11 +442,6 @@ const syncSecretsAWSParameterStore = async ({
accessKeyId: undefined, accessKeyId: undefined,
secretAccessKey: undefined secretAccessKey: undefined
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to AWS Parameter Store');
}
} }
/** /**
@@ -536,10 +511,6 @@ const syncSecretsAWSSecretManager = async ({
Name: integration.app, Name: integration.app,
SecretString: JSON.stringify(secrets) SecretString: JSON.stringify(secrets)
})); }));
} else {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to AWS Secret Manager');
} }
AWS.config.update({ AWS.config.update({
region: undefined, region: undefined,
@@ -565,7 +536,6 @@ const syncSecretsHeroku = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
const herokuSecrets = ( const herokuSecrets = (
await standardRequest.get( await standardRequest.get(
`${INTEGRATION_HEROKU_API_URL}/apps/${integration.app}/config-vars`, `${INTEGRATION_HEROKU_API_URL}/apps/${integration.app}/config-vars`,
@@ -596,11 +566,6 @@ const syncSecretsHeroku = async ({
}, },
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Heroku");
}
}; };
/** /**
@@ -628,8 +593,6 @@ const syncSecretsVercel = async ({
target: string[]; target: string[];
gitBranch?: string; gitBranch?: string;
} }
try {
// Get all (decrypted) secrets back from Vercel in // Get all (decrypted) secrets back from Vercel in
// decrypted format // decrypted format
const params: { [key: string]: string } = { const params: { [key: string]: string } = {
@@ -788,11 +751,6 @@ const syncSecretsVercel = async ({
} }
); );
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Vercel");
}
}; };
/** /**
@@ -814,7 +772,6 @@ const syncSecretsNetlify = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
interface NetlifyValue { interface NetlifyValue {
id?: string; id?: string;
context: string; // 'dev' | 'branch-deploy' | 'deploy-preview' | 'production', context: string; // 'dev' | 'branch-deploy' | 'deploy-preview' | 'production',
@@ -1011,11 +968,6 @@ const syncSecretsNetlify = async ({
); );
}); });
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Heroku");
}
}; };
/** /**
@@ -1035,7 +987,6 @@ const syncSecretsGitHub = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
interface GitHubRepoKey { interface GitHubRepoKey {
key_id: string; key_id: string;
key: string; key: string;
@@ -1126,11 +1077,6 @@ const syncSecretsGitHub = async ({
); );
}); });
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to GitHub");
}
}; };
/** /**
@@ -1149,7 +1095,6 @@ const syncSecretsRender = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
await standardRequest.put( await standardRequest.put(
`${INTEGRATION_RENDER_API_URL}/v1/services/${integration.appId}/env-vars`, `${INTEGRATION_RENDER_API_URL}/v1/services/${integration.appId}/env-vars`,
Object.keys(secrets).map((key) => ({ Object.keys(secrets).map((key) => ({
@@ -1163,11 +1108,6 @@ const syncSecretsRender = async ({
}, },
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Render");
}
}; };
/** /**
@@ -1186,8 +1126,6 @@ const syncSecretsRailway = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
const query = ` const query = `
mutation UpsertVariables($input: VariableCollectionUpsertInput!) { mutation UpsertVariables($input: VariableCollectionUpsertInput!) {
variableCollectionUpsert(input: $input) variableCollectionUpsert(input: $input)
@@ -1214,12 +1152,6 @@ const syncSecretsRailway = async ({
'Accept-Encoding': 'application/json' 'Accept-Encoding': 'application/json'
}, },
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Railway");
}
} }
/** /**
@@ -1238,7 +1170,6 @@ const syncSecretsFlyio = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
// set secrets // set secrets
const SetSecrets = ` const SetSecrets = `
mutation($input: SetSecretsInput!) { mutation($input: SetSecretsInput!) {
@@ -1346,12 +1277,6 @@ const syncSecretsFlyio = async ({
'Accept-Encoding': 'application/json', 'Accept-Encoding': 'application/json',
}, },
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to Fly.io");
}
}; };
/** /**
@@ -1370,7 +1295,6 @@ const syncSecretsCircleCI = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
const circleciOrganizationDetail = ( const circleciOrganizationDetail = (
await standardRequest.get(`${INTEGRATION_CIRCLECI_API_URL}/v2/me/collaborations`, { await standardRequest.get(`${INTEGRATION_CIRCLECI_API_URL}/v2/me/collaborations`, {
headers: { headers: {
@@ -1427,11 +1351,6 @@ const syncSecretsCircleCI = async ({
); );
} }
}); });
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to CircleCI");
}
}; };
/** /**
@@ -1450,7 +1369,6 @@ const syncSecretsTravisCI = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
// get secrets from travis-ci // get secrets from travis-ci
const getSecretsRes = ( const getSecretsRes = (
await standardRequest.get( await standardRequest.get(
@@ -1528,11 +1446,6 @@ const syncSecretsTravisCI = async ({
); );
} }
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to GitLab");
}
} }
/** /**
@@ -1552,7 +1465,6 @@ const syncSecretsGitLab = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
interface GitLabSecret { interface GitLabSecret {
key: string; key: string;
value: string; value: string;
@@ -1646,12 +1558,6 @@ const syncSecretsGitLab = async ({
); );
} }
} }
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to GitLab");
}
} }
/** /**
@@ -1671,7 +1577,6 @@ const syncSecretsSupabase = async ({
secrets: any; secrets: any;
accessToken: string; accessToken: string;
}) => { }) => {
try {
const { data: getSecretsRes } = await standardRequest.get( const { data: getSecretsRes } = await standardRequest.get(
`${INTEGRATION_SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`, `${INTEGRATION_SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`,
{ {
@@ -1721,11 +1626,6 @@ const syncSecretsSupabase = async ({
data: secretsToDelete data: secretsToDelete
} }
); );
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to sync secrets to Supabase');
}
}; };