mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 19:28:35 +00:00
Continue developing service token v2
This commit is contained in:
+3
-3
@@ -4,14 +4,14 @@ import jwt from 'jsonwebtoken';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import * as bigintConversion from 'bigint-conversion';
|
||||
const jsrp = require('jsrp');
|
||||
import { User } from '../models';
|
||||
import { createToken, issueTokens, clearTokens } from '../helpers/auth';
|
||||
import { User } from '../../models';
|
||||
import { createToken, issueTokens, clearTokens } from '../../helpers/auth';
|
||||
import {
|
||||
NODE_ENV,
|
||||
JWT_AUTH_LIFETIME,
|
||||
JWT_AUTH_SECRET,
|
||||
JWT_REFRESH_SECRET
|
||||
} from '../config';
|
||||
} from '../../config';
|
||||
|
||||
declare module 'jsonwebtoken' {
|
||||
export interface UserIDJwtPayload extends jwt.JwtPayload {
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Bot, BotKey } from '../models';
|
||||
import { createBot } from '../helpers/bot';
|
||||
import { Bot, BotKey } from '../../models';
|
||||
import { createBot } from '../../helpers/bot';
|
||||
|
||||
interface BotKey {
|
||||
encryptedKey: string;
|
||||
@@ -14,6 +14,7 @@ import * as stripeController from './stripeController';
|
||||
import * as userActionController from './userActionController';
|
||||
import * as userController from './userController';
|
||||
import * as workspaceController from './workspaceController';
|
||||
import * as serviceTokenDataController from './serviceTokenDataController';
|
||||
|
||||
export {
|
||||
authController,
|
||||
@@ -31,5 +32,6 @@ export {
|
||||
stripeController,
|
||||
userActionController,
|
||||
userController,
|
||||
workspaceController
|
||||
workspaceController,
|
||||
serviceTokenDataController
|
||||
};
|
||||
+4
-4
@@ -2,10 +2,10 @@ import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import axios from 'axios';
|
||||
import { readFileSync } from 'fs';
|
||||
import { IntegrationAuth, Integration } from '../models';
|
||||
import { INTEGRATION_SET, INTEGRATION_OPTIONS, ENV_DEV } from '../variables';
|
||||
import { IntegrationService } from '../services';
|
||||
import { getApps, revokeAccess } from '../integrations';
|
||||
import { IntegrationAuth, Integration } from '../../models';
|
||||
import { INTEGRATION_SET, INTEGRATION_OPTIONS, ENV_DEV } from '../../variables';
|
||||
import { IntegrationService } from '../../services';
|
||||
import { getApps, revokeAccess } from '../../integrations';
|
||||
|
||||
export const getIntegrationOptions = async (
|
||||
req: Request,
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { readFileSync } from 'fs';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Integration, Bot, BotKey } from '../models';
|
||||
import { EventService } from '../services';
|
||||
import { eventPushSecrets } from '../events';
|
||||
import { Integration, Bot, BotKey } from '../../models';
|
||||
import { EventService } from '../../services';
|
||||
import { eventPushSecrets } from '../../events';
|
||||
|
||||
interface Key {
|
||||
encryptedKey: string;
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Key } from '../models';
|
||||
import { findMembership } from '../helpers/membership';
|
||||
import { GRANTED } from '../variables';
|
||||
import { Key } from '../../models';
|
||||
import { findMembership } from '../../helpers/membership';
|
||||
import { GRANTED } from '../../variables';
|
||||
|
||||
/**
|
||||
* Add (encrypted) copy of workspace key for workspace with id [workspaceId] for user with
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Membership, MembershipOrg, User, Key } from '../models';
|
||||
import { Membership, MembershipOrg, User, Key } from '../../models';
|
||||
import {
|
||||
findMembership,
|
||||
deleteMembership as deleteMember
|
||||
} from '../helpers/membership';
|
||||
import { sendMail } from '../helpers/nodemailer';
|
||||
import { SITE_URL } from '../config';
|
||||
import { ADMIN, MEMBER, GRANTED, ACCEPTED } from '../variables';
|
||||
} from '../../helpers/membership';
|
||||
import { sendMail } from '../../helpers/nodemailer';
|
||||
import { SITE_URL } from '../../config';
|
||||
import { ADMIN, MEMBER, GRANTED, ACCEPTED } from '../../variables';
|
||||
|
||||
/**
|
||||
* Check that user is a member of workspace with id [workspaceId]
|
||||
+28
-22
@@ -1,14 +1,14 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import crypto from 'crypto';
|
||||
import { SITE_URL, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../config';
|
||||
import { MembershipOrg, Organization, User, Token } from '../models';
|
||||
import { deleteMembershipOrg as deleteMemberFromOrg } from '../helpers/membershipOrg';
|
||||
import { checkEmailVerification } from '../helpers/signup';
|
||||
import { createToken } from '../helpers/auth';
|
||||
import { updateSubscriptionOrgQuantity } from '../helpers/organization';
|
||||
import { sendMail } from '../helpers/nodemailer';
|
||||
import { OWNER, ADMIN, MEMBER, ACCEPTED, INVITED } from '../variables';
|
||||
import { SITE_URL, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../../config';
|
||||
import { MembershipOrg, Organization, User, Token } from '../../models';
|
||||
import { deleteMembershipOrg as deleteMemberFromOrg } from '../../helpers/membershipOrg';
|
||||
import { checkEmailVerification } from '../../helpers/signup';
|
||||
import { createToken } from '../../helpers/auth';
|
||||
import { updateSubscriptionOrgQuantity } from '../../helpers/organization';
|
||||
import { sendMail } from '../../helpers/nodemailer';
|
||||
import { OWNER, ADMIN, MEMBER, ACCEPTED, INVITED } from '../../variables';
|
||||
|
||||
/**
|
||||
* Delete organization membership with id [membershipOrgId] from organization
|
||||
@@ -80,14 +80,14 @@ export const changeMembershipOrgRole = async (req: Request, res: Response) => {
|
||||
// TODO
|
||||
|
||||
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'
|
||||
});
|
||||
}
|
||||
// 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({
|
||||
membershipOrg: membershipToChangeRole
|
||||
@@ -218,12 +218,6 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => {
|
||||
const { email, code } = req.body;
|
||||
|
||||
user = await User.findOne({ email }).select('+publicKey');
|
||||
if (user && user?.publicKey) {
|
||||
// case: user has already completed account
|
||||
return res.status(403).send({
|
||||
error: 'Failed email magic link verification for complete account'
|
||||
});
|
||||
}
|
||||
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
inviteEmail: email,
|
||||
@@ -238,6 +232,18 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => {
|
||||
code
|
||||
});
|
||||
|
||||
if (user && user?.publicKey) {
|
||||
// case: user has already completed account
|
||||
// membership can be approved and redirected to login/dashboard
|
||||
membershipOrg.status = ACCEPTED;
|
||||
await membershipOrg.save();
|
||||
|
||||
return res.status(200).send({
|
||||
message: 'Successfully verified email',
|
||||
user,
|
||||
});
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
// initialize user account
|
||||
user = await new User({
|
||||
+5
-5
@@ -6,7 +6,7 @@ import {
|
||||
STRIPE_PRODUCT_STARTER,
|
||||
STRIPE_PRODUCT_PRO,
|
||||
STRIPE_PRODUCT_CARD_AUTH
|
||||
} from '../config';
|
||||
} from '../../config';
|
||||
import Stripe from 'stripe';
|
||||
|
||||
const stripe = new Stripe(STRIPE_SECRET_KEY, {
|
||||
@@ -18,10 +18,10 @@ import {
|
||||
Organization,
|
||||
Workspace,
|
||||
IncidentContactOrg
|
||||
} from '../models';
|
||||
import { createOrganization as create } from '../helpers/organization';
|
||||
import { addMembershipsOrg } from '../helpers/membershipOrg';
|
||||
import { OWNER, ACCEPTED } from '../variables';
|
||||
} from '../../models';
|
||||
import { createOrganization as create } from '../../helpers/organization';
|
||||
import { addMembershipsOrg } from '../../helpers/membershipOrg';
|
||||
import { OWNER, ACCEPTED } from '../../variables';
|
||||
|
||||
const productToPriceMap = {
|
||||
starter: STRIPE_PRODUCT_STARTER,
|
||||
+6
-5
@@ -1,13 +1,14 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import crypto from 'crypto';
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const jsrp = require('jsrp');
|
||||
import * as bigintConversion from 'bigint-conversion';
|
||||
import { User, Token, BackupPrivateKey } from '../models';
|
||||
import { checkEmailVerification } from '../helpers/signup';
|
||||
import { createToken } from '../helpers/auth';
|
||||
import { sendMail } from '../helpers/nodemailer';
|
||||
import { JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET, SITE_URL } from '../config';
|
||||
import { User, Token, BackupPrivateKey } from '../../models';
|
||||
import { checkEmailVerification } from '../../helpers/signup';
|
||||
import { createToken } from '../../helpers/auth';
|
||||
import { sendMail } from '../../helpers/nodemailer';
|
||||
import { JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET, SITE_URL } from '../../config';
|
||||
|
||||
const clientPublicKeys: any = {};
|
||||
|
||||
+12
-8
@@ -1,16 +1,16 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Key, Secret } from '../models';
|
||||
import { Key, Secret } from '../../models';
|
||||
import {
|
||||
pushSecrets as push,
|
||||
v1PushSecrets as push,
|
||||
pullSecrets as pull,
|
||||
reformatPullSecrets
|
||||
} from '../helpers/secret';
|
||||
import { pushKeys } from '../helpers/key';
|
||||
import { eventPushSecrets } from '../events';
|
||||
import { EventService } from '../services';
|
||||
import { ENV_SET } from '../variables';
|
||||
import { postHogClient } from '../services';
|
||||
} from '../../helpers/secret';
|
||||
import { pushKeys } from '../../helpers/key';
|
||||
import { eventPushSecrets } from '../../events';
|
||||
import { EventService } from '../../services';
|
||||
import { ENV_SET } from '../../variables';
|
||||
import { postHogClient } from '../../services';
|
||||
|
||||
interface PushSecret {
|
||||
ciphertextKey: string;
|
||||
@@ -21,6 +21,10 @@ interface PushSecret {
|
||||
ivValue: string;
|
||||
tagValue: string;
|
||||
hashValue: string;
|
||||
ciphertextComment: string;
|
||||
ivComment: string;
|
||||
tagComment: string;
|
||||
hashComment: string;
|
||||
type: 'shared' | 'personal';
|
||||
}
|
||||
|
||||
+5
-15
@@ -1,8 +1,8 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { ServiceToken } from '../models';
|
||||
import { createToken } from '../helpers/auth';
|
||||
import { ENV_SET } from '../variables';
|
||||
import { JWT_SERVICE_SECRET } from '../config';
|
||||
import { ServiceToken } from '../../models';
|
||||
import { createToken } from '../../helpers/auth';
|
||||
import { ENV_SET } from '../../variables';
|
||||
import { JWT_SERVICE_SECRET } from '../../config';
|
||||
|
||||
/**
|
||||
* Return service token on request
|
||||
@@ -11,7 +11,6 @@ import { JWT_SERVICE_SECRET } from '../config';
|
||||
* @returns
|
||||
*/
|
||||
export const getServiceToken = async (req: Request, res: Response) => {
|
||||
// get service token
|
||||
return res.status(200).send({
|
||||
serviceToken: req.serviceToken
|
||||
});
|
||||
@@ -73,13 +72,4 @@ export const createServiceToken = async (req: Request, res: Response) => {
|
||||
return res.status(200).send({
|
||||
token
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* SERVICE_TOKEN: <JWT_SERVICE_TOKEN>,<PRIVATE_KEY_SERVICE_TOKEN>
|
||||
* - <JWT_SERVICE_TOKEN> authorizes the service token for "service token"-only endpoints.
|
||||
* - <PRIVATE_KEY_SERVICE_TOKEN> authorizes the service token to pull secrets via that endpoint.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import crypto from 'crypto';
|
||||
import bcrypt from 'bcrypt';
|
||||
import {
|
||||
ServiceTokenData
|
||||
} from '../../models';
|
||||
import {
|
||||
SALT_ROUNDS
|
||||
} from '../../config';
|
||||
|
||||
/**
|
||||
* Return service token data associated with service token on request
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getServiceTokenData = async (req: Request, res: Response) => ({
|
||||
serviceTokenData: req.serviceTokenData
|
||||
});
|
||||
|
||||
/**
|
||||
* Create new service token data for workspace with id [workspaceId] and
|
||||
* environment [environment].
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
let serviceToken, serviceTokenData;
|
||||
try {
|
||||
const {
|
||||
name,
|
||||
workspaceId,
|
||||
environment,
|
||||
encryptedKey,
|
||||
iv,
|
||||
tag,
|
||||
expiresIn
|
||||
} = req.body;
|
||||
|
||||
// create 41-char service token with first 9-char being the prefix
|
||||
serviceToken = `st.${crypto.randomBytes(19).toString('hex')}`;
|
||||
|
||||
const serviceTokenHash = await bcrypt.hash(serviceToken, SALT_ROUNDS);
|
||||
|
||||
// compute access token expiration date
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||
|
||||
serviceTokenData = await new ServiceTokenData({
|
||||
name,
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
user: req.user._id,
|
||||
expiresAt,
|
||||
prefix: serviceToken.substring(0, 9),
|
||||
serviceTokenHash,
|
||||
encryptedKey,
|
||||
iv,
|
||||
tag
|
||||
}).save();
|
||||
|
||||
} catch (err) {
|
||||
Sentry.setUser({ email: req.user.email });
|
||||
Sentry.captureException(err);
|
||||
return res.status(400).send({
|
||||
message: 'Failed to create service token data'
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
serviceToken,
|
||||
serviceTokenData
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete service token data with id [serviceTokenDataId].
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const deleteServiceTokenData = async (req: Request, res: Response) => {
|
||||
let serviceTokenData;
|
||||
try {
|
||||
const { serviceTokenDataId } = req.params;
|
||||
|
||||
serviceTokenData = await ServiceTokenData.findByIdAndDelete(serviceTokenDataId);
|
||||
|
||||
} catch (err) {
|
||||
Sentry.setUser({ email: req.user.email });
|
||||
Sentry.captureException(err);
|
||||
return res.status(400).send({
|
||||
message: 'Failed to delete service token data'
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
serviceTokenData
|
||||
});
|
||||
}
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { NODE_ENV, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../config';
|
||||
import { User, MembershipOrg } from '../models';
|
||||
import { completeAccount } from '../helpers/user';
|
||||
import { NODE_ENV, JWT_SIGNUP_LIFETIME, JWT_SIGNUP_SECRET } from '../../config';
|
||||
import { User, MembershipOrg } from '../../models';
|
||||
import { completeAccount } from '../../helpers/user';
|
||||
import {
|
||||
sendEmailVerification,
|
||||
checkEmailVerification,
|
||||
initializeDefaultOrg
|
||||
} from '../helpers/signup';
|
||||
import { issueTokens, createToken } from '../helpers/auth';
|
||||
import { INVITED, ACCEPTED } from '../variables';
|
||||
} from '../../helpers/signup';
|
||||
import { issueTokens, createToken } from '../../helpers/auth';
|
||||
import { INVITED, ACCEPTED } from '../../variables';
|
||||
import axios from 'axios';
|
||||
|
||||
/**
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import Stripe from 'stripe';
|
||||
import { STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET } from '../config';
|
||||
import { STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET } from '../../config';
|
||||
const stripe = new Stripe(STRIPE_SECRET_KEY, {
|
||||
apiVersion: '2022-08-01'
|
||||
});
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { UserAction } from '../models';
|
||||
import { UserAction } from '../../models';
|
||||
|
||||
/**
|
||||
* Add user action [action]
|
||||
+5
-5
@@ -8,14 +8,14 @@ import {
|
||||
IntegrationAuth,
|
||||
IUser,
|
||||
ServiceToken,
|
||||
ServiceTokenData,
|
||||
} from '../models';
|
||||
ServiceTokenData
|
||||
} from '../../models';
|
||||
import {
|
||||
createWorkspace as create,
|
||||
deleteWorkspace as deleteWork
|
||||
} from '../helpers/workspace';
|
||||
import { addMemberships } from '../helpers/membership';
|
||||
import { ADMIN, COMPLETED, GRANTED } from '../variables';
|
||||
} from '../../helpers/workspace';
|
||||
import { addMemberships } from '../../helpers/membership';
|
||||
import { ADMIN, COMPLETED, GRANTED } from '../../variables';
|
||||
|
||||
/**
|
||||
* Return public keys of members of workspace with id [workspaceId]
|
||||
@@ -0,0 +1,5 @@
|
||||
import * as workspaceController from './workspaceController';
|
||||
|
||||
export {
|
||||
workspaceController
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import { Request, Response } from 'express';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import {
|
||||
Workspace,
|
||||
Membership,
|
||||
MembershipOrg,
|
||||
Integration,
|
||||
IntegrationAuth,
|
||||
Key,
|
||||
IUser,
|
||||
ServiceToken,
|
||||
} from '../../models';
|
||||
import {
|
||||
createWorkspace as create,
|
||||
deleteWorkspace as deleteWork
|
||||
} from '../../helpers/workspace';
|
||||
import {
|
||||
v2PushSecrets as push,
|
||||
pullSecrets as pull,
|
||||
reformatPullSecrets
|
||||
} from '../../helpers/secret';
|
||||
import { pushKeys } from '../../helpers/key';
|
||||
import { addMemberships } from '../../helpers/membership';
|
||||
import { postHogClient, EventService } from '../../services';
|
||||
import { eventPushSecrets } from '../../events';
|
||||
import { ADMIN, COMPLETED, GRANTED, ENV_SET } from '../../variables';
|
||||
|
||||
interface V2PushSecret {
|
||||
type: string; // personal or shared
|
||||
secretKeyCiphertext: string;
|
||||
secretKeyIV: string;
|
||||
secretKeyTag: string;
|
||||
secretKeyHash: string;
|
||||
secretValueCiphertext: string;
|
||||
secretValueIV: string;
|
||||
secretValueTag: string;
|
||||
secretValueHash: string;
|
||||
secretCommentCiphertext?: string;
|
||||
secretCommentIV?: string;
|
||||
secretCommentTag?: string;
|
||||
secretCommentHash?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload (encrypted) secrets to workspace with id [workspaceId]
|
||||
* for environment [environment]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const pushWorkspaceSecrets = async (req: Request, res: Response) => {
|
||||
// upload (encrypted) secrets to workspace with id [workspaceId]
|
||||
|
||||
try {
|
||||
let { secrets }: { secrets: V2PushSecret[] } = req.body;
|
||||
const { keys, environment, channel } = req.body;
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
// validate environment
|
||||
if (!ENV_SET.has(environment)) {
|
||||
throw new Error('Failed to validate environment');
|
||||
}
|
||||
|
||||
// sanitize secrets
|
||||
secrets = secrets.filter(
|
||||
(s: V2PushSecret) => s.secretKeyCiphertext !== '' && s.secretValueCiphertext !== ''
|
||||
);
|
||||
|
||||
await push({
|
||||
userId: req.user._id,
|
||||
workspaceId,
|
||||
environment,
|
||||
secrets
|
||||
});
|
||||
|
||||
await pushKeys({
|
||||
userId: req.user._id,
|
||||
workspaceId,
|
||||
keys
|
||||
});
|
||||
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets pushed',
|
||||
distinctId: req.user.email,
|
||||
properties: {
|
||||
numberOfSecrets: secrets.length,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: channel ? channel : 'cli'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// trigger event - push secrets
|
||||
EventService.handleEvent({
|
||||
event: eventPushSecrets({
|
||||
workspaceId
|
||||
})
|
||||
});
|
||||
|
||||
} 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({
|
||||
message: 'Successfully uploaded workspace secrets'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Return (encrypted) secrets for workspace with id [workspaceId]
|
||||
* for environment [environment]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const pullSecrets = async (req: Request, res: Response) => {
|
||||
let secrets;
|
||||
try {
|
||||
const environment: string = req.query.environment as string;
|
||||
const channel: string = req.query.channel as string;
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
let userId;
|
||||
if (req.user) {
|
||||
userId = req.user._id.toString();
|
||||
} else if (req.serviceTokenData) {
|
||||
userId = req.serviceTokenData.user._id
|
||||
}
|
||||
|
||||
secrets = await pull({
|
||||
userId,
|
||||
workspaceId,
|
||||
environment
|
||||
});
|
||||
|
||||
if (channel !== 'cli') { // TODO: fix frontend to get rid of this reformat bs
|
||||
secrets = reformatPullSecrets({ secrets });
|
||||
}
|
||||
|
||||
if (postHogClient) {
|
||||
// capture secrets pushed event in production
|
||||
postHogClient.capture({
|
||||
distinctId: req.user.email,
|
||||
event: 'secrets pulled',
|
||||
properties: {
|
||||
numberOfSecrets: secrets.length,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: channel ? channel : 'cli'
|
||||
}
|
||||
});
|
||||
}
|
||||
} 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({
|
||||
secrets
|
||||
});
|
||||
};
|
||||
|
||||
export const getWorkspaceKey = async (req: Request, res: Response) => {
|
||||
let key;
|
||||
try {
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
key = await Key.findOne({
|
||||
workspace: workspaceId,
|
||||
receiver: req.user._id
|
||||
}).populate('sender', '+publicKey');
|
||||
|
||||
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).send({
|
||||
key
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user