mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-17 15:08:32 +00:00
Compare commits
32 Commits
maidul98-p
...
infisical/
Author | SHA1 | Date | |
---|---|---|---|
37d52432d0 | |||
04b7e04d98 | |||
57a3384f32 | |||
c813c91aec | |||
91947df5f6 | |||
8330890087 | |||
221e601173 | |||
28c24fc8c1 | |||
a9389643b8 | |||
58854e6b81 | |||
7ae859e9ae | |||
ff6e07bdcf | |||
fc9393b77f | |||
0cad823267 | |||
97a0728f02 | |||
6cb8cf53f8 | |||
1ac607b42e | |||
ec21e35f8c | |||
2591161272 | |||
be86e4176c | |||
2067c021ed | |||
648968c453 | |||
373dfff8e0 | |||
b9ce448bed | |||
142fcf0a01 | |||
49bcd8839f | |||
d5f6e20c78 | |||
00030f2231 | |||
24d23e89d0 | |||
3fe592686a | |||
9cba0970be | |||
9d57b1db87 |
@ -28,4 +28,4 @@ HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
|
||||
|
||||
EXPOSE 4000
|
||||
|
||||
CMD ["npm", "run", "start"]
|
||||
CMD ["npm", "run", "start"]
|
||||
|
@ -15,20 +15,20 @@ import { checkUserDevice } from "../../helpers/user";
|
||||
import {
|
||||
ACTION_LOGIN,
|
||||
ACTION_LOGOUT,
|
||||
AUTH_MODE_JWT,
|
||||
} from "../../variables";
|
||||
import {
|
||||
BadRequestError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../../utils/errors";
|
||||
import { EELogService } from "../../ee/services";
|
||||
import { getChannelFromUserAgent } from "../../utils/posthog";
|
||||
import { getUserAgentType } from "../../utils/posthog";
|
||||
import {
|
||||
getHttpsEnabled,
|
||||
getJwtAuthLifetime,
|
||||
getJwtAuthSecret,
|
||||
getJwtRefreshSecret,
|
||||
} from "../../config";
|
||||
import { ActorType } from "../../ee/models";
|
||||
|
||||
declare module "jsonwebtoken" {
|
||||
export interface UserIDJwtPayload extends jwt.JwtPayload {
|
||||
@ -142,7 +142,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
loginAction && await EELogService.createLog({
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
ipAddress: req.realIP,
|
||||
});
|
||||
|
||||
@ -170,7 +170,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
* @returns
|
||||
*/
|
||||
export const logout = async (req: Request, res: Response) => {
|
||||
if (req.authData.authMode === AUTH_MODE_JWT && req.authData.authPayload instanceof User && req.authData.tokenVersionId) {
|
||||
if (req.authData.actor.type === ActorType.USER && req.authData.tokenVersionId) {
|
||||
await clearTokens(req.authData.tokenVersionId)
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ export const logout = async (req: Request, res: Response) => {
|
||||
logoutAction && await EELogService.createLog({
|
||||
userId: req.user._id,
|
||||
actions: [logoutAction],
|
||||
channel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
ipAddress: req.realIP,
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,9 @@ import { Types } from "mongoose";
|
||||
import { standardRequest } from "../../config/request";
|
||||
import { getApps, getTeams, revokeAccess } from "../../integrations";
|
||||
import { Bot, IntegrationAuth } from "../../models";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { IntegrationService } from "../../services";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import {
|
||||
ALGORITHM_AES_256_GCM,
|
||||
ENCODING_SCHEME_UTF8,
|
||||
@ -62,6 +64,19 @@ export const oAuthExchange = async (req: Request, res: Response) => {
|
||||
environment: environments[0].slug
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.AUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
});
|
||||
@ -129,6 +144,19 @@ export const saveIntegrationAccessToken = async (req: Request, res: Response) =>
|
||||
});
|
||||
|
||||
if (!integrationAuth) throw new Error("Failed to save integration access token");
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.AUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
@ -530,6 +558,23 @@ export const deleteIntegrationAuth = async (req: Request, res: Response) => {
|
||||
integrationAuth: req.integrationAuth,
|
||||
accessToken: req.accessToken
|
||||
});
|
||||
|
||||
if (!integrationAuth) return res.status(400).send({
|
||||
message: "Failed to find integration authorization"
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UNAUTHORIZE_INTEGRATION,
|
||||
metadata: {
|
||||
integration: integrationAuth.integration
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integrationAuth.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integrationAuth
|
||||
|
@ -6,6 +6,8 @@ import { eventStartIntegration } from "../../events";
|
||||
import Folder from "../../models/folder";
|
||||
import { getFolderByPath } from "../../services/FolderService";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
|
||||
/**
|
||||
* Create/initialize an (empty) integration for integration authorization
|
||||
@ -74,6 +76,31 @@ export const createIntegration = async (req: Request, res: Response) => {
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_INTEGRATION,
|
||||
metadata: {
|
||||
integrationId: integration._id.toString(),
|
||||
integration: integration.integration,
|
||||
environment: integration.environment,
|
||||
secretPath,
|
||||
url: integration.url,
|
||||
app: integration.app,
|
||||
appId: integration.appId,
|
||||
targetEnvironment: integration.targetEnvironment,
|
||||
targetEnvironmentId: integration.targetEnvironmentId,
|
||||
targetService: integration.targetService,
|
||||
targetServiceId: integration.targetServiceId,
|
||||
path: integration.path,
|
||||
region: integration.region
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integration.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integration
|
||||
@ -148,8 +175,7 @@ export const updateIntegration = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete integration with id [integrationId] and deactivate bot if there are
|
||||
* no integrations left
|
||||
* Delete integration with id [integrationId]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
@ -163,6 +189,31 @@ export const deleteIntegration = async (req: Request, res: Response) => {
|
||||
|
||||
if (!integration) throw new Error("Failed to find integration");
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_INTEGRATION,
|
||||
metadata: {
|
||||
integrationId: integration._id.toString(),
|
||||
integration: integration.integration,
|
||||
environment: integration.environment,
|
||||
secretPath: integration.secretPath,
|
||||
url: integration.url,
|
||||
app: integration.app,
|
||||
appId: integration.appId,
|
||||
targetEnvironment: integration.targetEnvironment,
|
||||
targetEnvironmentId: integration.targetEnvironmentId,
|
||||
targetService: integration.targetService,
|
||||
targetServiceId: integration.targetServiceId,
|
||||
path: integration.path,
|
||||
region: integration.region
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: integration.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
integration
|
||||
});
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { Types } from "mongoose";
|
||||
import { Request, Response } from "express";
|
||||
import { Key } from "../../models";
|
||||
import { findMembership } from "../../helpers/membership";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
|
||||
/**
|
||||
* Add (encrypted) copy of workspace key for workspace with id [workspaceId] for user with
|
||||
@ -44,7 +47,7 @@ export const uploadKey = async (req: Request, res: Response) => {
|
||||
*/
|
||||
export const getLatestKey = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
|
||||
// get latest key
|
||||
const latestKey = await Key.find({
|
||||
workspace: workspaceId,
|
||||
@ -58,6 +61,18 @@ export const getLatestKey = async (req: Request, res: Response) => {
|
||||
|
||||
if (latestKey.length > 0) {
|
||||
resObj["latestKey"] = latestKey[0];
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.GET_WORKSPACE_KEY,
|
||||
metadata: {
|
||||
keyId: latestKey[0]._id.toString()
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return res.status(200).send(resObj);
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Key, Membership, MembershipOrg, User } from "../../models";
|
||||
import { Types } from "mongoose";
|
||||
import { IUser, Key, Membership, MembershipOrg, User } from "../../models";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { deleteMembership as deleteMember, findMembership } from "../../helpers/membership";
|
||||
import { sendMail } from "../../helpers/nodemailer";
|
||||
import { ACCEPTED, ADMIN, MEMBER } from "../../variables";
|
||||
import { getSiteURL } from "../../config";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
|
||||
/**
|
||||
* Check that user is a member of workspace with id [workspaceId]
|
||||
@ -36,11 +39,11 @@ export const validateMembership = async (req: Request, res: Response) => {
|
||||
*/
|
||||
export const deleteMembership = async (req: Request, res: Response) => {
|
||||
const { membershipId } = req.params;
|
||||
|
||||
|
||||
// check if membership to delete exists
|
||||
const membershipToDelete = await Membership.findOne({
|
||||
_id: membershipId
|
||||
}).populate("user");
|
||||
}).populate<{ user: IUser }>("user");
|
||||
|
||||
if (!membershipToDelete) {
|
||||
throw new Error("Failed to delete workspace membership that doesn't exist");
|
||||
@ -66,6 +69,20 @@ export const deleteMembership = async (req: Request, res: Response) => {
|
||||
const deletedMembership = await deleteMember({
|
||||
membershipId: membershipToDelete._id.toString()
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.REMOVE_WORKSPACE_MEMBER,
|
||||
metadata: {
|
||||
userId: membershipToDelete.user._id.toString(),
|
||||
email: membershipToDelete.user.email
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: membership.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
deletedMembership
|
||||
@ -140,7 +157,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
||||
const inviteeMembership = await Membership.findOne({
|
||||
user: invitee._id,
|
||||
workspace: workspaceId
|
||||
});
|
||||
}).populate<{ user: IUser }>("user");
|
||||
|
||||
if (inviteeMembership) throw new Error("Failed to add existing member of workspace");
|
||||
|
||||
@ -181,6 +198,20 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
||||
}
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.ADD_WORKSPACE_MEMBER,
|
||||
metadata: {
|
||||
userId: invitee._id.toString(),
|
||||
email: invitee.email
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
invitee,
|
||||
latestKey
|
||||
|
@ -103,14 +103,14 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => {
|
||||
// validate membership
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
user: req.user._id,
|
||||
organization: organizationId
|
||||
organization: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
if (!membershipOrg) {
|
||||
throw new Error("Failed to validate organization membership");
|
||||
}
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId));
|
||||
|
||||
const ssoConfig = await SSOConfig.findOne({
|
||||
organization: new Types.ObjectId(organizationId)
|
||||
|
@ -5,7 +5,7 @@ import * as bigintConversion from "bigint-conversion";
|
||||
import { BackupPrivateKey, LoginSRPDetail, User } from "../../models";
|
||||
import { clearTokens, createToken, sendMail } from "../../helpers";
|
||||
import { TokenService } from "../../services";
|
||||
import { AUTH_MODE_JWT, TOKEN_EMAIL_PASSWORD_RESET } from "../../variables";
|
||||
import { TOKEN_EMAIL_PASSWORD_RESET } from "../../variables";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import {
|
||||
getHttpsEnabled,
|
||||
@ -13,6 +13,7 @@ import {
|
||||
getJwtSignupSecret,
|
||||
getSiteURL
|
||||
} from "../../config";
|
||||
import { ActorType } from "../../ee/models";
|
||||
|
||||
/**
|
||||
* Password reset step 1: Send email verification link to email [email]
|
||||
@ -208,8 +209,7 @@ export const changePassword = async (req: Request, res: Response) => {
|
||||
);
|
||||
|
||||
if (
|
||||
req.authData.authMode === AUTH_MODE_JWT &&
|
||||
req.authData.authPayload instanceof User &&
|
||||
req.authData.actor.type === ActorType.USER &&
|
||||
req.authData.tokenVersionId
|
||||
) {
|
||||
await clearTokens(req.authData.tokenVersionId);
|
||||
|
@ -1,17 +1,49 @@
|
||||
import { Request, Response } from "express";
|
||||
import { validateMembership } from "../../helpers";
|
||||
import { isValidScope, validateMembership } from "../../helpers";
|
||||
import { ServiceTokenData } from "../../models";
|
||||
import Folder from "../../models/folder";
|
||||
import SecretImport from "../../models/secretImports";
|
||||
import { getAllImportedSecrets } from "../../services/SecretImportService";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { getFolderWithPathFromId } from "../../services/FolderService";
|
||||
import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { ADMIN, MEMBER } from "../../variables";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
|
||||
export const createSecretImport = async (req: Request, res: Response) => {
|
||||
const { workspaceId, environment, folderId, secretImport } = req.body;
|
||||
|
||||
const folders = await Folder.findOne({
|
||||
workspace: workspaceId,
|
||||
environment
|
||||
}).lean();
|
||||
|
||||
if (!folders && folderId !== "root") {
|
||||
throw ResourceNotFoundError({
|
||||
message: "Failed to find folder"
|
||||
});
|
||||
}
|
||||
|
||||
let secretPath = "/";
|
||||
if (folders) {
|
||||
const { folderPath } = getFolderWithPathFromId(folders.nodes, folderId);
|
||||
secretPath = folderPath;
|
||||
}
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
// root check
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
const importSecDoc = await SecretImport.findOne({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
folderId
|
||||
});
|
||||
|
||||
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, folderId).folderPath:"/";
|
||||
|
||||
if (!importSecDoc) {
|
||||
const doc = new SecretImport({
|
||||
@ -20,7 +52,25 @@ export const createSecretImport = async (req: Request, res: Response) => {
|
||||
folderId,
|
||||
imports: [{ environment: secretImport.environment, secretPath: secretImport.secretPath }]
|
||||
});
|
||||
|
||||
await doc.save();
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: doc._id.toString(),
|
||||
folderId: doc.folderId.toString(),
|
||||
importFromEnvironment: secretImport.environment,
|
||||
importFromSecretPath: secretImport.secretPath,
|
||||
importToEnvironment: environment,
|
||||
importToSecretPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: doc.workspace
|
||||
}
|
||||
);
|
||||
return res.status(200).json({ message: "successfully created secret import" });
|
||||
}
|
||||
|
||||
@ -30,11 +80,30 @@ export const createSecretImport = async (req: Request, res: Response) => {
|
||||
if (doesImportExist) {
|
||||
throw BadRequestError({ message: "Secret import already exist" });
|
||||
}
|
||||
|
||||
importSecDoc.imports.push({
|
||||
environment: secretImport.environment,
|
||||
secretPath: secretImport.secretPath
|
||||
});
|
||||
await importSecDoc.save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: importSecDoc._id.toString(),
|
||||
folderId: importSecDoc.folderId.toString(),
|
||||
importFromEnvironment: secretImport.environment,
|
||||
importFromSecretPath: secretImport.secretPath,
|
||||
importToEnvironment: environment,
|
||||
importToSecretPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: importSecDoc.workspace
|
||||
}
|
||||
);
|
||||
return res.status(200).json({ message: "successfully created secret import" });
|
||||
};
|
||||
|
||||
@ -48,14 +117,68 @@ export const updateSecretImport = async (req: Request, res: Response) => {
|
||||
throw BadRequestError({ message: "Import not found" });
|
||||
}
|
||||
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId: importSecDoc.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) {
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId: importSecDoc.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
} else {
|
||||
// check for service token validity
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment
|
||||
}).lean();
|
||||
|
||||
let secretPath = "/";
|
||||
if (folders) {
|
||||
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||
secretPath = folderPath;
|
||||
}
|
||||
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
importSecDoc.environment,
|
||||
secretPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
const orderBefore = importSecDoc.imports;
|
||||
importSecDoc.imports = secretImports;
|
||||
|
||||
await importSecDoc.save();
|
||||
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment,
|
||||
}).lean();
|
||||
|
||||
if (!folders) throw ResourceNotFoundError({
|
||||
message: "Failed to find folder"
|
||||
});
|
||||
|
||||
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
importToEnvironment: importSecDoc.environment,
|
||||
importToSecretPath,
|
||||
secretImportId: importSecDoc._id.toString(),
|
||||
folderId: importSecDoc.folderId.toString(),
|
||||
orderBefore,
|
||||
orderAfter: secretImports
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: importSecDoc.workspace
|
||||
}
|
||||
);
|
||||
return res.status(200).json({ message: "successfully updated secret import" });
|
||||
};
|
||||
|
||||
@ -67,16 +190,69 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
|
||||
throw BadRequestError({ message: "Import not found" });
|
||||
}
|
||||
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId: importSecDoc.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) {
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId: importSecDoc.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
} else {
|
||||
// check for service token validity
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment
|
||||
}).lean();
|
||||
|
||||
let secretPath = "/";
|
||||
if (folders) {
|
||||
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||
secretPath = folderPath;
|
||||
}
|
||||
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
importSecDoc.environment,
|
||||
secretPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
importSecDoc.imports = importSecDoc.imports.filter(
|
||||
({ environment, secretPath }) =>
|
||||
!(environment === secretImportEnv && secretPath === secretImportPath)
|
||||
);
|
||||
await importSecDoc.save();
|
||||
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment,
|
||||
}).lean();
|
||||
|
||||
if (!folders) throw ResourceNotFoundError({
|
||||
message: "Failed to find folder"
|
||||
});
|
||||
|
||||
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: importSecDoc._id.toString(),
|
||||
folderId: importSecDoc.folderId.toString(),
|
||||
importFromEnvironment: secretImportEnv,
|
||||
importFromSecretPath: secretImportPath,
|
||||
importToEnvironment: importSecDoc.environment,
|
||||
importToSecretPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: importSecDoc.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).json({ message: "successfully delete secret import" });
|
||||
};
|
||||
|
||||
@ -92,6 +268,29 @@ export const getSecretImports = async (req: Request, res: Response) => {
|
||||
return res.status(200).json({ secretImport: {} });
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
// check for service token validity
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment
|
||||
}).lean();
|
||||
|
||||
let secretPath = "/";
|
||||
if (folders) {
|
||||
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||
secretPath = folderPath;
|
||||
}
|
||||
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
importSecDoc.environment,
|
||||
secretPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json({ secretImport: importSecDoc });
|
||||
};
|
||||
|
||||
@ -111,6 +310,45 @@ export const getAllSecretsFromImport = async (req: Request, res: Response) => {
|
||||
return res.status(200).json({ secrets: [] });
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
// check for service token validity
|
||||
const folders = await Folder.findOne({
|
||||
workspace: importSecDoc.workspace,
|
||||
environment: importSecDoc.environment
|
||||
}).lean();
|
||||
|
||||
let secretPath = "/";
|
||||
if (folders) {
|
||||
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||
secretPath = folderPath;
|
||||
}
|
||||
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
importSecDoc.environment,
|
||||
secretPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.GET_SECRET_IMPORTS,
|
||||
metadata: {
|
||||
environment,
|
||||
secretImportId: importSecDoc._id.toString(),
|
||||
folderId,
|
||||
numberOfImports: importSecDoc.imports.length
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: importSecDoc.workspace
|
||||
}
|
||||
);
|
||||
|
||||
const secrets = await getAllImportedSecrets(workspaceId, environment, folderId);
|
||||
return res.status(200).json({ secrets });
|
||||
};
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Request, Response } from "express";
|
||||
import GitAppInstallationSession from "../../models/gitAppInstallationSession";
|
||||
import GitAppInstallationSession from "../../ee/models/gitAppInstallationSession";
|
||||
import crypto from "crypto";
|
||||
import { Types } from "mongoose";
|
||||
import { UnauthorizedRequestError } from "../../utils/errors";
|
||||
import GitAppOrganizationInstallation from "../../models/gitAppOrganizationInstallation";
|
||||
import GitAppOrganizationInstallation from "../../ee/models/gitAppOrganizationInstallation";
|
||||
import { MembershipOrg } from "../../models";
|
||||
import GitRisks, { STATUS_RESOLVED_FALSE_POSITIVE, STATUS_RESOLVED_NOT_REVOKED, STATUS_RESOLVED_REVOKED } from "../../models/gitRisks";
|
||||
import GitRisks, { STATUS_RESOLVED_FALSE_POSITIVE, STATUS_RESOLVED_NOT_REVOKED, STATUS_RESOLVED_REVOKED } from "../../ee/models/gitRisks";
|
||||
|
||||
export const createInstallationSession = async (req: Request, res: Response) => {
|
||||
const sessionId = crypto.randomBytes(16).toString("hex");
|
||||
|
@ -1,39 +1,49 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Secret } from "../../models";
|
||||
import { Types } from "mongoose";
|
||||
import { EventType, FolderVersion } from "../../ee/models";
|
||||
import { EEAuditLogService, EESecretService } from "../../ee/services";
|
||||
import { validateMembership } from "../../helpers/membership";
|
||||
import { isValidScope } from "../../helpers/secrets";
|
||||
import { Secret, ServiceTokenData } from "../../models";
|
||||
import Folder from "../../models/folder";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import {
|
||||
appendFolder,
|
||||
deleteFolderById,
|
||||
generateFolderId,
|
||||
getAllFolderIds,
|
||||
getFolderByPath,
|
||||
getFolderWithPathFromId,
|
||||
getParentFromFolderId,
|
||||
searchByFolderId,
|
||||
searchByFolderIdWithDir,
|
||||
validateFolderName,
|
||||
validateFolderName
|
||||
} from "../../services/FolderService";
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { ADMIN, MEMBER } from "../../variables";
|
||||
import { validateMembership } from "../../helpers/membership";
|
||||
import { FolderVersion } from "../../ee/models";
|
||||
import { EESecretService } from "../../ee/services";
|
||||
|
||||
// TODO
|
||||
// verify workspace id/environment
|
||||
export const createFolder = async (req: Request, res: Response) => {
|
||||
const { workspaceId, environment, folderName, parentFolderId } = req.body;
|
||||
if (!validateFolderName(folderName)) {
|
||||
throw BadRequestError({
|
||||
message: "Folder name cannot contain spaces. Only underscore and dashes",
|
||||
message: "Folder name cannot contain spaces. Only underscore and dashes"
|
||||
});
|
||||
}
|
||||
|
||||
const folders = await Folder.findOne({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
environment
|
||||
}).lean();
|
||||
|
||||
// space has no folders initialized
|
||||
|
||||
if (!folders) {
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
// root check
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, "/");
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
const id = generateFolderId();
|
||||
const folder = new Folder({
|
||||
workspace: workspaceId,
|
||||
@ -42,39 +52,93 @@ export const createFolder = async (req: Request, res: Response) => {
|
||||
id: "root",
|
||||
name: "root",
|
||||
version: 1,
|
||||
children: [{ id, name: folderName, children: [], version: 1 }],
|
||||
},
|
||||
children: [{ id, name: folderName, children: [], version: 1 }]
|
||||
}
|
||||
});
|
||||
await folder.save();
|
||||
const folderVersion = new FolderVersion({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
nodes: folder.nodes,
|
||||
nodes: folder.nodes
|
||||
});
|
||||
await folderVersion.save();
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
environment,
|
||||
environment
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: id,
|
||||
folderName,
|
||||
folderPath: `root/${folderName}`
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({ folder: { id, name: folderName } });
|
||||
}
|
||||
|
||||
const folder = appendFolder(folders.nodes, { folderName, parentFolderId });
|
||||
|
||||
await Folder.findByIdAndUpdate(folders._id, folders);
|
||||
|
||||
const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId(
|
||||
folders.nodes,
|
||||
parentFolderId || "root"
|
||||
);
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
// root check
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
environment,
|
||||
parentFolderPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
await Folder.findByIdAndUpdate(folders._id, folders);
|
||||
|
||||
const parentFolder = searchByFolderId(folders.nodes, parentFolderId);
|
||||
const folderVersion = new FolderVersion({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
nodes: parentFolder,
|
||||
nodes: parentFolder
|
||||
});
|
||||
await folderVersion.save();
|
||||
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
environment,
|
||||
folderId: parentFolderId,
|
||||
folderId: parentFolderId
|
||||
});
|
||||
|
||||
const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: folder.id,
|
||||
folderName,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({ folder });
|
||||
};
|
||||
@ -82,28 +146,46 @@ export const createFolder = async (req: Request, res: Response) => {
|
||||
export const updateFolderById = async (req: Request, res: Response) => {
|
||||
const { folderId } = req.params;
|
||||
const { name, workspaceId, environment } = req.body;
|
||||
if (!validateFolderName(name)) {
|
||||
throw BadRequestError({
|
||||
message: "Folder name cannot contain spaces. Only underscore and dashes"
|
||||
});
|
||||
}
|
||||
|
||||
const folders = await Folder.findOne({ workspace: workspaceId, environment });
|
||||
if (!folders) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
});
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) {
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
}
|
||||
|
||||
const parentFolder = getParentFromFolderId(folders.nodes, folderId);
|
||||
if (!parentFolder) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
const folder = parentFolder.children.find(({ id }) => id === folderId);
|
||||
|
||||
if (!folder) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
|
||||
// root check
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
const oldFolderName = folder.name;
|
||||
parentFolder.version += 1;
|
||||
folder.name = name;
|
||||
|
||||
@ -111,19 +193,38 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
||||
const folderVersion = new FolderVersion({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
nodes: parentFolder,
|
||||
nodes: parentFolder
|
||||
});
|
||||
await folderVersion.save();
|
||||
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
environment,
|
||||
folderId: parentFolder.id,
|
||||
folderId: parentFolder.id
|
||||
});
|
||||
|
||||
const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_FOLDER,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId: folder.id,
|
||||
oldFolderName,
|
||||
newFolderName: name,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.json({
|
||||
message: "Successfully updated folder",
|
||||
folder: { name: folder.name, id: folder.id },
|
||||
folder: { name: folder.name, id: folder.id }
|
||||
});
|
||||
};
|
||||
|
||||
@ -136,12 +237,16 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
}
|
||||
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
});
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) {
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
}
|
||||
|
||||
const {folderPath} = getFolderWithPathFromId(folders.nodes, folderId);
|
||||
|
||||
const delOp = deleteFolderById(folders.nodes, folderId);
|
||||
if (!delOp) {
|
||||
@ -149,6 +254,14 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
||||
}
|
||||
const { deletedNode: delFolder, parent: parentFolder } = delOp;
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
parentFolder.version += 1;
|
||||
const delFolderIds = getAllFolderIds(delFolder);
|
||||
|
||||
@ -156,35 +269,50 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
||||
const folderVersion = new FolderVersion({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
nodes: parentFolder,
|
||||
nodes: parentFolder
|
||||
});
|
||||
await folderVersion.save();
|
||||
if (delFolderIds.length) {
|
||||
await Secret.deleteMany({
|
||||
folder: { $in: delFolderIds.map(({ id }) => id) },
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
environment
|
||||
});
|
||||
}
|
||||
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
environment,
|
||||
folderId: parentFolder.id,
|
||||
folderId: parentFolder.id
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_FOLDER ,
|
||||
metadata: {
|
||||
environment,
|
||||
folderId,
|
||||
folderName: delFolder.name,
|
||||
folderPath
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
res.send({ message: "successfully deleted folders", folders: delFolderIds });
|
||||
};
|
||||
|
||||
// TODO: validate workspace
|
||||
export const getFolders = async (req: Request, res: Response) => {
|
||||
const { workspaceId, environment, parentFolderId, parentFolderPath } =
|
||||
req.query as {
|
||||
workspaceId: string;
|
||||
environment: string;
|
||||
parentFolderId?: string;
|
||||
parentFolderPath?: string;
|
||||
};
|
||||
const { workspaceId, environment, parentFolderId, parentFolderPath } = req.query as {
|
||||
workspaceId: string;
|
||||
environment: string;
|
||||
parentFolderId?: string;
|
||||
parentFolderPath?: string;
|
||||
};
|
||||
|
||||
const folders = await Folder.findOne({ workspace: workspaceId, environment });
|
||||
if (!folders) {
|
||||
@ -192,16 +320,29 @@ export const getFolders = async (req: Request, res: Response) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
});
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) {
|
||||
// check that user is a member of the workspace
|
||||
await validateMembership({
|
||||
userId: req.user._id.toString(),
|
||||
workspaceId,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
}
|
||||
|
||||
// if instead of parentFolderId given a path like /folder1/folder2
|
||||
if (parentFolderPath) {
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
environment,
|
||||
parentFolderPath
|
||||
);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
const folder = getFolderByPath(folders.nodes, parentFolderPath);
|
||||
|
||||
if (!folder) {
|
||||
res.send({ folders: [], dir: [] });
|
||||
return;
|
||||
@ -209,27 +350,36 @@ export const getFolders = async (req: Request, res: Response) => {
|
||||
// dir is not needed at present as this is only used in overview section of secrets
|
||||
res.send({
|
||||
folders: folder.children.map(({ id, name }) => ({ id, name })),
|
||||
dir: [{ name: folder.name, id: folder.id }],
|
||||
dir: [{ name: folder.name, id: folder.id }]
|
||||
});
|
||||
}
|
||||
|
||||
if (!parentFolderId) {
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, "/");
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
const rootFolders = folders.nodes.children.map(({ id, name }) => ({
|
||||
id,
|
||||
name,
|
||||
name
|
||||
}));
|
||||
res.send({ folders: rootFolders });
|
||||
return;
|
||||
}
|
||||
|
||||
const folderBySearch = searchByFolderIdWithDir(folders.nodes, parentFolderId);
|
||||
if (!folderBySearch) {
|
||||
throw BadRequestError({ message: "The folder doesn't exist" });
|
||||
const { folder, folderPath, dir } = getFolderWithPathFromId(folders.nodes, parentFolderId);
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath);
|
||||
if (!isValidScopeAccess) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
const { folder, dir } = folderBySearch;
|
||||
|
||||
res.send({
|
||||
folders: folder.children.map(({ id, name }) => ({ id, name })),
|
||||
dir,
|
||||
dir
|
||||
});
|
||||
};
|
||||
|
@ -4,7 +4,9 @@ import { client, getRootEncryptionKey } from "../../config";
|
||||
import { validateMembership } from "../../helpers";
|
||||
import Webhook from "../../models/webhooks";
|
||||
import { getWebhookPayload, triggerWebhookRequest } from "../../services/WebhookService";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { BadRequestError, ResourceNotFoundError } from "../../utils/errors";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
import { ADMIN, ALGORITHM_AES_256_GCM, ENCODING_SCHEME_BASE64, MEMBER } from "../../variables";
|
||||
|
||||
export const createWebhook = async (req: Request, res: Response) => {
|
||||
@ -27,6 +29,23 @@ export const createWebhook = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
await webhook.save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment,
|
||||
secretPath,
|
||||
webhookUrl,
|
||||
isDisabled: false
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
webhook,
|
||||
@ -54,6 +73,23 @@ export const updateWebhook = async (req: Request, res: Response) => {
|
||||
}
|
||||
await webhook.save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_WEBHOOK_STATUS,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment: webhook.environment,
|
||||
secretPath: webhook.secretPath,
|
||||
webhookUrl: webhook.url,
|
||||
isDisabled
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: webhook.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
webhook,
|
||||
message: "successfully updated webhook"
|
||||
@ -62,9 +98,10 @@ export const updateWebhook = async (req: Request, res: Response) => {
|
||||
|
||||
export const deleteWebhook = async (req: Request, res: Response) => {
|
||||
const { webhookId } = req.params;
|
||||
const webhook = await Webhook.findById(webhookId);
|
||||
let webhook = await Webhook.findById(webhookId);
|
||||
|
||||
if (!webhook) {
|
||||
throw BadRequestError({ message: "Webhook not found!!" });
|
||||
throw ResourceNotFoundError({ message: "Webhook not found!!" });
|
||||
}
|
||||
|
||||
await validateMembership({
|
||||
@ -72,8 +109,29 @@ export const deleteWebhook = async (req: Request, res: Response) => {
|
||||
workspaceId: webhook.workspace,
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
});
|
||||
|
||||
webhook = await Webhook.findByIdAndDelete(webhookId);
|
||||
|
||||
await webhook.deleteOne();
|
||||
if (!webhook) {
|
||||
throw ResourceNotFoundError({ message: "Webhook not found!!" });
|
||||
}
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: webhook._id.toString(),
|
||||
environment: webhook.environment,
|
||||
secretPath: webhook.secretPath,
|
||||
webhookUrl: webhook.url,
|
||||
isDisabled: webhook.isDisabled
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: webhook.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
message: "successfully removed webhook"
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Types } from "mongoose";
|
||||
import { Request, Response } from "express";
|
||||
import {
|
||||
IUser,
|
||||
@ -108,14 +109,14 @@ export const createWorkspace = async (req: Request, res: Response) => {
|
||||
// validate organization membership
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
user: req.user._id,
|
||||
organization: organizationId,
|
||||
organization: new Types.ObjectId(organizationId),
|
||||
});
|
||||
|
||||
if (!membershipOrg) {
|
||||
throw new Error("Failed to validate organization membership");
|
||||
}
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId));
|
||||
|
||||
if (plan.workspaceLimit !== null) {
|
||||
// case: limit imposed on number of workspaces allowed
|
||||
@ -134,7 +135,7 @@ export const createWorkspace = async (req: Request, res: Response) => {
|
||||
// create workspace and add user as member
|
||||
const workspace = await create({
|
||||
name: workspaceName,
|
||||
organizationId,
|
||||
organizationId: new Types.ObjectId(organizationId),
|
||||
});
|
||||
|
||||
await addMemberships({
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
ACTION_LOGIN,
|
||||
TOKEN_EMAIL_MFA,
|
||||
} from "../../variables";
|
||||
import { getChannelFromUserAgent } from "../../utils/posthog"; // TODO: move this
|
||||
import { getUserAgentType } from "../../utils/posthog"; // TODO: move this
|
||||
import {
|
||||
getHttpsEnabled,
|
||||
getJwtMfaLifetime,
|
||||
@ -203,7 +203,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
loginAction && await EELogService.createLog({
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
ipAddress: req.ip,
|
||||
});
|
||||
|
||||
@ -336,7 +336,7 @@ export const verifyMfaToken = async (req: Request, res: Response) => {
|
||||
loginAction && await EELogService.createLog({
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
ipAddress: req.realIP,
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
Integration,
|
||||
Membership,
|
||||
@ -7,8 +8,8 @@ import {
|
||||
ServiceTokenData,
|
||||
Workspace,
|
||||
} from "../../models";
|
||||
import { SecretVersion } from "../../ee/models";
|
||||
import { EELicenseService } from "../../ee/services";
|
||||
import { EventType, SecretVersion } from "../../ee/models";
|
||||
import { EEAuditLogService, EELicenseService } from "../../ee/services";
|
||||
import { BadRequestError, WorkspaceNotFoundError } from "../../utils/errors";
|
||||
import _ from "lodash";
|
||||
import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../variables";
|
||||
@ -30,7 +31,7 @@ export const createWorkspaceEnvironment = async (
|
||||
|
||||
if (!workspace) throw WorkspaceNotFoundError();
|
||||
|
||||
const plan = await EELicenseService.getPlan(workspace.organization.toString());
|
||||
const plan = await EELicenseService.getPlan(workspace.organization);
|
||||
|
||||
if (plan.environmentLimit !== null) {
|
||||
// case: limit imposed on number of environments allowed
|
||||
@ -58,7 +59,21 @@ export const createWorkspaceEnvironment = async (
|
||||
});
|
||||
await workspace.save();
|
||||
|
||||
await EELicenseService.refreshPlan(workspace.organization.toString(), workspaceId);
|
||||
await EELicenseService.refreshPlan(workspace.organization, new Types.ObjectId(workspaceId));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_ENVIRONMENT,
|
||||
metadata: {
|
||||
name: environmentName,
|
||||
slug: environmentSlug
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: workspace._id
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
message: "Successfully created new environment",
|
||||
@ -109,6 +124,8 @@ export const renameWorkspaceEnvironment = async (
|
||||
if (envIndex === -1) {
|
||||
throw new Error("Invalid environment given");
|
||||
}
|
||||
|
||||
const oldEnvironment = workspace.environments[envIndex];
|
||||
|
||||
workspace.environments[envIndex].name = environmentName;
|
||||
workspace.environments[envIndex].slug = environmentSlug.toLowerCase();
|
||||
@ -141,8 +158,23 @@ export const renameWorkspaceEnvironment = async (
|
||||
},
|
||||
{ $set: { "deniedPermissions.$[element].environmentSlug": environmentSlug } },
|
||||
{ arrayFilters: [{ "element.environmentSlug": oldEnvironmentSlug }] }
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_ENVIRONMENT,
|
||||
metadata: {
|
||||
oldName: oldEnvironment.name,
|
||||
newName: environmentName,
|
||||
oldSlug: oldEnvironment.slug,
|
||||
newSlug: environmentSlug.toLowerCase()
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: workspace._id
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
message: "Successfully update environment",
|
||||
@ -178,6 +210,8 @@ export const deleteWorkspaceEnvironment = async (
|
||||
if (envIndex === -1) {
|
||||
throw new Error("Invalid environment given");
|
||||
}
|
||||
|
||||
const oldEnvironment = workspace.environments[envIndex];
|
||||
|
||||
workspace.environments.splice(envIndex, 1);
|
||||
await workspace.save();
|
||||
@ -215,7 +249,21 @@ export const deleteWorkspaceEnvironment = async (
|
||||
{ $pull: { deniedPermissions: { environmentSlug: environmentSlug } } }
|
||||
);
|
||||
|
||||
await EELicenseService.refreshPlan(workspace.organization.toString(), workspaceId);
|
||||
await EELicenseService.refreshPlan(workspace.organization, new Types.ObjectId(workspaceId));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_ENVIRONMENT,
|
||||
metadata: {
|
||||
name: oldEnvironment.name,
|
||||
slug: oldEnvironment.slug
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: workspace._id
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
message: "Successfully deleted environment",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Types } from "mongoose";
|
||||
import { Request, Response } from "express";
|
||||
import { ISecret, Secret, ServiceTokenData } from "../../models";
|
||||
import { IAction, SecretVersion } from "../../ee/models";
|
||||
import { IAction, SecretVersion, EventType, AuditLog } from "../../ee/models";
|
||||
import {
|
||||
ACTION_ADD_SECRETS,
|
||||
ACTION_DELETE_SECRETS,
|
||||
@ -14,9 +14,9 @@ import {
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { EventService } from "../../services";
|
||||
import { eventPushSecrets } from "../../events";
|
||||
import { EELogService, EESecretService } from "../../ee/services";
|
||||
import { EELogService, EESecretService, EEAuditLogService } from "../../ee/services";
|
||||
import { SecretService, TelemetryService } from "../../services";
|
||||
import { getChannelFromUserAgent } from "../../utils/posthog";
|
||||
import { getUserAgentType } from "../../utils/posthog";
|
||||
import { PERMISSION_WRITE_SECRETS } from "../../variables";
|
||||
import {
|
||||
userHasNoAbility,
|
||||
@ -44,7 +44,7 @@ import { getAllImportedSecrets } from "../../services/SecretImportService";
|
||||
* @param res
|
||||
*/
|
||||
export const batchSecrets = async (req: Request, res: Response) => {
|
||||
const channel = getChannelFromUserAgent(req.headers["user-agent"]);
|
||||
const channel = getUserAgentType(req.headers["user-agent"]);
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
|
||||
const {
|
||||
@ -56,12 +56,13 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
environment: string;
|
||||
requests: BatchSecretRequest[];
|
||||
} = req.body;
|
||||
|
||||
let secretPath = req.body.secretPath as string;
|
||||
let folderId = req.body.folderId as string;
|
||||
|
||||
|
||||
const createSecrets: BatchSecret[] = [];
|
||||
const updateSecrets: BatchSecret[] = [];
|
||||
const deleteSecrets: Types.ObjectId[] = [];
|
||||
const deleteSecrets: { _id: Types.ObjectId, secretName: string; }[] = [];
|
||||
const actions: IAction[] = [];
|
||||
|
||||
// get secret blind index salt
|
||||
@ -133,7 +134,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
});
|
||||
break;
|
||||
case "DELETE":
|
||||
deleteSecrets.push(new Types.ObjectId(request.secret._id));
|
||||
deleteSecrets.push({ _id: new Types.ObjectId(request.secret._id), secretName: request.secret.secretName });
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -153,7 +154,31 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
const auditLogs = await Promise.all(
|
||||
createdSecrets.map((secret, index) => {
|
||||
return EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_SECRET,
|
||||
metadata: {
|
||||
environment: secret.environment,
|
||||
secretPath: secretPath ?? "/",
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: createSecrets[index].secretName,
|
||||
secretVersion: secret.version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: secret.workspace
|
||||
},
|
||||
false
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
await AuditLog.insertMany(auditLogs);
|
||||
|
||||
const addAction = (await EELogService.createAction({
|
||||
name: ACTION_ADD_SECRETS,
|
||||
userId: req.user?._id,
|
||||
@ -252,6 +277,30 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
$in: updateSecrets.map((u) => new Types.ObjectId(u._id))
|
||||
}
|
||||
});
|
||||
|
||||
const auditLogs = await Promise.all(
|
||||
updateSecrets.map((secret) => {
|
||||
return EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath: secretPath ?? "/",
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secret.secretName,
|
||||
secretVersion: listedSecretsObj[secret._id.toString()].version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
},
|
||||
false
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
await AuditLog.insertMany(auditLogs);
|
||||
|
||||
const updateAction = (await EELogService.createAction({
|
||||
name: ACTION_UPDATE_SECRETS,
|
||||
@ -279,21 +328,60 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// handle delete secrets
|
||||
if (deleteSecrets.length > 0) {
|
||||
const deleteSecretIds: Types.ObjectId[] = deleteSecrets.map((s) => s._id);
|
||||
|
||||
const deletedSecretsObj = (await Secret.find({
|
||||
_id: {
|
||||
$in: deleteSecretIds
|
||||
}
|
||||
}))
|
||||
.reduce(
|
||||
(obj: any, secret: ISecret) => ({
|
||||
...obj,
|
||||
[secret._id.toString()]: secret
|
||||
}),
|
||||
{}
|
||||
);
|
||||
|
||||
await Secret.deleteMany({
|
||||
_id: {
|
||||
$in: deleteSecrets
|
||||
$in: deleteSecretIds
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await EESecretService.markDeletedSecretVersions({
|
||||
secretIds: deleteSecrets
|
||||
secretIds: deleteSecretIds
|
||||
});
|
||||
|
||||
const auditLogs = await Promise.all(
|
||||
deleteSecrets.map((secret) => {
|
||||
return EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath: secretPath ?? "/",
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secret.secretName,
|
||||
secretVersion: deletedSecretsObj[secret._id.toString()].version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
},
|
||||
false
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
await AuditLog.insertMany(auditLogs);
|
||||
|
||||
const deleteAction = (await EELogService.createAction({
|
||||
name: ACTION_DELETE_SECRETS,
|
||||
userId: req.user._id,
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
secretIds: deleteSecrets
|
||||
secretIds: deleteSecretIds
|
||||
})) as IAction;
|
||||
actions.push(deleteAction);
|
||||
|
||||
@ -351,7 +439,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
if (deleteSecrets.length > 0) {
|
||||
resObj["deletedSecrets"] = deleteSecrets.map((d) => d.toString());
|
||||
resObj["deletedSecrets"] = deleteSecrets.map((d) => d._id.toString());
|
||||
}
|
||||
|
||||
return res.status(200).send(resObj);
|
||||
@ -416,7 +504,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
*/
|
||||
|
||||
const channel = getChannelFromUserAgent(req.headers["user-agent"]);
|
||||
const channel = getUserAgentType(req.headers["user-agent"]);
|
||||
const {
|
||||
workspaceId,
|
||||
environment,
|
||||
@ -697,10 +785,16 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
const environment = req.query.environment as string;
|
||||
|
||||
const folders = await Folder.findOne({ workspace: workspaceId, environment });
|
||||
if ((!folders && folderId && folderId !== "root") || (!folders && secretPath)) {
|
||||
|
||||
if (
|
||||
// if no folders and asking for a non root folder id or non root secret path
|
||||
(!folders && folderId && folderId !== "root") ||
|
||||
(!folders && secretPath && secretPath !== "/")
|
||||
) {
|
||||
res.send({ secrets: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (folders && folderId !== "root") {
|
||||
const folder = searchByFolderId(folders.nodes, folderId as string);
|
||||
if (!folder) {
|
||||
@ -834,7 +928,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
importedSecrets = await getAllImportedSecrets(workspaceId, environment, folderId as string);
|
||||
}
|
||||
|
||||
const channel = getChannelFromUserAgent(req.headers["user-agent"]);
|
||||
const channel = getUserAgentType(req.headers["user-agent"]);
|
||||
|
||||
const readAction = await EELogService.createAction({
|
||||
name: ACTION_READ_SECRETS,
|
||||
@ -855,6 +949,21 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
channel,
|
||||
ipAddress: req.realIP
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.GET_SECRETS,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath: secretPath as string,
|
||||
numberOfSecrets: secrets.length
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId as string)
|
||||
}
|
||||
);
|
||||
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
@ -1170,7 +1279,7 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
*/
|
||||
|
||||
const channel = getChannelFromUserAgent(req.headers["user-agent"]);
|
||||
const channel = getUserAgentType(req.headers["user-agent"]);
|
||||
const toDelete = req.secrets.map((s: any) => s._id);
|
||||
|
||||
await Secret.deleteMany({
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { Request, Response } from "express";
|
||||
import crypto from "crypto";
|
||||
import bcrypt from "bcrypt";
|
||||
import { ServiceAccount, ServiceTokenData, User } from "../../models";
|
||||
import { AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT } from "../../variables";
|
||||
import { ServiceTokenData } from "../../models";
|
||||
import { getSaltRounds } from "../../config";
|
||||
import { BadRequestError } from "../../utils/errors";
|
||||
import { ActorType, EventType } from "../../ee/models";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
|
||||
/**
|
||||
* Return service token data associated with service token on request
|
||||
@ -73,24 +74,16 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||
}
|
||||
|
||||
let user, serviceAccount;
|
||||
|
||||
if (req.authData.authMode === AUTH_MODE_JWT && req.authData.authPayload instanceof User) {
|
||||
let user;
|
||||
|
||||
if (req.authData.actor.type === ActorType.USER) {
|
||||
user = req.authData.authPayload._id;
|
||||
}
|
||||
|
||||
if (
|
||||
req.authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
|
||||
req.authData.authPayload instanceof ServiceAccount
|
||||
) {
|
||||
serviceAccount = req.authData.authPayload._id;
|
||||
}
|
||||
|
||||
serviceTokenData = await new ServiceTokenData({
|
||||
name,
|
||||
workspace: workspaceId,
|
||||
user,
|
||||
serviceAccount,
|
||||
scopes,
|
||||
lastUsed: new Date(),
|
||||
expiresAt,
|
||||
@ -107,6 +100,20 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
if (!serviceTokenData) throw new Error("Failed to find service token data");
|
||||
|
||||
const serviceToken = `st.${serviceTokenData._id.toString()}.${secret}`;
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_SERVICE_TOKEN,
|
||||
metadata: {
|
||||
name,
|
||||
scopes
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
serviceToken,
|
||||
@ -124,6 +131,24 @@ export const deleteServiceTokenData = async (req: Request, res: Response) => {
|
||||
const { serviceTokenDataId } = req.params;
|
||||
|
||||
const serviceTokenData = await ServiceTokenData.findByIdAndDelete(serviceTokenDataId);
|
||||
|
||||
if (!serviceTokenData) return res.status(200).send({
|
||||
message: "Failed to delete service token"
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_SERVICE_TOKEN,
|
||||
metadata: {
|
||||
name: serviceTokenData.name,
|
||||
scopes: serviceTokenData?.scopes
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: serviceTokenData.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
serviceTokenData
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
import { pushKeys } from "../../helpers/key";
|
||||
import { EventService, TelemetryService } from "../../services";
|
||||
import { eventPushSecrets } from "../../events";
|
||||
import { EEAuditLogService } from "../../ee/services";
|
||||
import { EventType } from "../../ee/models";
|
||||
|
||||
interface V2PushSecret {
|
||||
type: string; // personal or shared
|
||||
@ -180,16 +182,30 @@ export const getWorkspaceKey = async (req: Request, res: Response) => {
|
||||
}
|
||||
*/
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
|
||||
const key = await Key.findOne({
|
||||
workspace: workspaceId,
|
||||
receiver: req.user._id
|
||||
}).populate("sender", "+publicKey");
|
||||
|
||||
if (!key) throw new Error("Failed to find workspace key");
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.GET_WORKSPACE_KEY,
|
||||
metadata: {
|
||||
keyId: key._id.toString()
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).json(key);
|
||||
};
|
||||
|
||||
export const getWorkspaceServiceTokenData = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
ACTION_LOGIN,
|
||||
TOKEN_EMAIL_MFA,
|
||||
} from "../../variables";
|
||||
import { getChannelFromUserAgent } from "../../utils/posthog"; // TODO: move this
|
||||
import { getUserAgentType } from "../../utils/posthog"; // TODO: move this
|
||||
import {
|
||||
getHttpsEnabled,
|
||||
getJwtMfaLifetime,
|
||||
@ -241,7 +241,7 @@ export const login2 = async (req: Request, res: Response) => {
|
||||
loginAction && await EELogService.createLog({
|
||||
userId: user._id,
|
||||
actions: [loginAction],
|
||||
channel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
ipAddress: req.realIP,
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Types } from "mongoose";
|
||||
import { Request, Response } from "express";
|
||||
import { getLicenseServerUrl } from "../../../config";
|
||||
import { licenseServerKeyRequest } from "../../../config/request";
|
||||
@ -20,7 +21,7 @@ export const getOrganizationPlan = async (req: Request, res: Response) => {
|
||||
const { organizationId } = req.params;
|
||||
const workspaceId = req.query.workspaceId as string;
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId, workspaceId);
|
||||
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId), new Types.ObjectId(workspaceId));
|
||||
|
||||
return res.status(200).send({
|
||||
plan,
|
||||
@ -44,7 +45,7 @@ export const startOrganizationTrial = async (req: Request, res: Response) => {
|
||||
}
|
||||
);
|
||||
|
||||
EELicenseService.delPlan(organizationId);
|
||||
EELicenseService.delPlan(new Types.ObjectId(organizationId));
|
||||
|
||||
return res.status(200).send({
|
||||
url
|
||||
|
@ -59,7 +59,7 @@ export const updateSSOConfig = async (req: Request, res: Response) => {
|
||||
cert,
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId));
|
||||
|
||||
if (!plan.samlSSO) return res.status(400).send({
|
||||
message: "Failed to update SAML SSO configuration due to plan restriction. Upgrade plan to update SSO configuration."
|
||||
@ -194,7 +194,7 @@ export const createSSOConfig = async (req: Request, res: Response) => {
|
||||
cert
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(organizationId);
|
||||
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId));
|
||||
|
||||
if (!plan.samlSSO) return res.status(400).send({
|
||||
message: "Failed to create SAML SSO configuration due to plan restriction. Upgrade plan to add SSO configuration."
|
||||
|
@ -8,6 +8,6 @@ import { Request, Response } from "express";
|
||||
*/
|
||||
export const getMyIp = (req: Request, res: Response) => {
|
||||
return res.status(200).send({
|
||||
ip: req.authData.authIP
|
||||
ip: req.authData.ipAddress
|
||||
});
|
||||
}
|
@ -1,21 +1,26 @@
|
||||
import { Request, Response } from "express";
|
||||
import { PipelineStage, Types } from "mongoose";
|
||||
import { Secret } from "../../../models";
|
||||
import { Membership, Secret, ServiceTokenData, User } from "../../../models";
|
||||
import {
|
||||
ActorType,
|
||||
AuditLog,
|
||||
EventType,
|
||||
FolderVersion,
|
||||
IPType,
|
||||
ISecretVersion,
|
||||
Log,
|
||||
SecretSnapshot,
|
||||
SecretVersion,
|
||||
ServiceActor,
|
||||
TFolderRootVersionSchema,
|
||||
TrustedIP
|
||||
TrustedIP,
|
||||
UserActor
|
||||
} from "../../models";
|
||||
import { EESecretService } from "../../services";
|
||||
import { getLatestSecretVersionIds } from "../../helpers/secretVersion";
|
||||
import Folder, { TFolderSchema } from "../../../models/folder";
|
||||
import { searchByFolderId } from "../../../services/FolderService";
|
||||
import { EELicenseService } from "../../services";
|
||||
import { EEAuditLogService, EELicenseService } from "../../services";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "../../../utils/ip";
|
||||
|
||||
/**
|
||||
@ -593,6 +598,101 @@ export const getWorkspaceLogs = async (req: Request, res: Response) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Return audit logs for workspace with id [workspaceId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const getWorkspaceAuditLogs = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
const eventType = req.query.eventType;
|
||||
const userAgentType = req.query.userAgentType;
|
||||
const actor = req.query.actor as string | undefined;
|
||||
const offset: number = parseInt(req.query.offset as string);
|
||||
const limit: number = parseInt(req.query.limit as string);
|
||||
|
||||
const startDate = req.query.startDate as string;
|
||||
const endDate = req.query.endDate as string;
|
||||
|
||||
const query = {
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
...(eventType ? {
|
||||
"event.type": eventType
|
||||
} : {}),
|
||||
...(userAgentType ? {
|
||||
userAgentType
|
||||
} : {}),
|
||||
...(actor ? {
|
||||
"actor.type": actor.split("-", 2)[0],
|
||||
...(actor.split("-", 2)[0] === ActorType.USER ? {
|
||||
"actor.metadata.userId": actor.split("-", 2)[1]
|
||||
} : {
|
||||
"actor.metadata.serviceId": actor.split("-", 2)[1]
|
||||
})
|
||||
} : {}),
|
||||
...(startDate || endDate ? {
|
||||
createdAt: {
|
||||
...(startDate && { $gte: new Date(startDate) }),
|
||||
...(endDate && { $lte: new Date(endDate) })
|
||||
}
|
||||
} : {})
|
||||
}
|
||||
|
||||
const auditLogs = await AuditLog.find(query)
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(offset)
|
||||
.limit(limit);
|
||||
|
||||
const totalCount = await AuditLog.countDocuments(query);
|
||||
|
||||
return res.status(200).send({
|
||||
auditLogs,
|
||||
totalCount
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return audit log actor filter options for workspace with id [workspaceId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const getWorkspaceAuditLogActorFilterOpts = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
const userIds = await Membership.distinct("user", {
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
const userActors: UserActor[] = (await User.find({
|
||||
_id: {
|
||||
$in: userIds
|
||||
}
|
||||
})
|
||||
.select("email"))
|
||||
.map((user) => ({
|
||||
type: ActorType.USER,
|
||||
metadata: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email
|
||||
}
|
||||
}));
|
||||
|
||||
const serviceActors: ServiceActor[] = (await ServiceTokenData.find({
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
})
|
||||
.select("name"))
|
||||
.map((serviceTokenData) => ({
|
||||
type: ActorType.SERVICE,
|
||||
metadata: {
|
||||
serviceId: serviceTokenData._id.toString(),
|
||||
name: serviceTokenData.name
|
||||
}
|
||||
}));
|
||||
|
||||
return res.status(200).send({
|
||||
actors: [...userActors, ...serviceActors]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return trusted ips for workspace with id [workspaceId]
|
||||
* @param req
|
||||
@ -623,7 +723,7 @@ export const addWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
isActive
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization.toString());
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization);
|
||||
|
||||
if (!plan.ipAllowlisting) return res.status(400).send({
|
||||
message: "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range."
|
||||
@ -645,6 +745,21 @@ export const addWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
isActive,
|
||||
comment,
|
||||
}).save();
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.ADD_TRUSTED_IP,
|
||||
metadata: {
|
||||
trustedIpId: trustedIp._id.toString(),
|
||||
ipAddress: trustedIp.ipAddress,
|
||||
prefix: trustedIp.prefix
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: trustedIp.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
trustedIp
|
||||
@ -663,7 +778,7 @@ export const updateWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
comment
|
||||
} = req.body;
|
||||
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization.toString());
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization);
|
||||
|
||||
if (!plan.ipAllowlisting) return res.status(400).send({
|
||||
message: "Failed to update IP access range due to plan restriction. Upgrade plan to update IP access range."
|
||||
@ -708,6 +823,25 @@ export const updateWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
}
|
||||
);
|
||||
|
||||
if (!trustedIp) return res.status(400).send({
|
||||
message: "Failed to update trusted IP"
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_TRUSTED_IP,
|
||||
metadata: {
|
||||
trustedIpId: trustedIp._id.toString(),
|
||||
ipAddress: trustedIp.ipAddress,
|
||||
prefix: trustedIp.prefix
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: trustedIp.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
trustedIp
|
||||
});
|
||||
@ -721,7 +855,7 @@ export const updateWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
export const deleteWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
const { workspaceId, trustedIpId } = req.params;
|
||||
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization.toString());
|
||||
const plan = await EELicenseService.getPlan(req.workspace.organization);
|
||||
|
||||
if (!plan.ipAllowlisting) return res.status(400).send({
|
||||
message: "Failed to delete IP access range due to plan restriction. Upgrade plan to delete IP access range."
|
||||
@ -731,6 +865,25 @@ export const deleteWorkspaceTrustedIp = async (req: Request, res: Response) => {
|
||||
_id: new Types.ObjectId(trustedIpId),
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
if (!trustedIp) return res.status(400).send({
|
||||
message: "Failed to delete trusted IP"
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_TRUSTED_IP,
|
||||
metadata: {
|
||||
trustedIpId: trustedIp._id.toString(),
|
||||
ipAddress: trustedIp.ipAddress,
|
||||
prefix: trustedIp.prefix
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId: trustedIp.workspace
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
trustedIp
|
||||
|
76
backend/src/ee/models/auditLog/auditLog.ts
Normal file
76
backend/src/ee/models/auditLog/auditLog.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
import {
|
||||
ActorType,
|
||||
EventType,
|
||||
UserAgentType
|
||||
} from "./enums";
|
||||
import {
|
||||
Actor,
|
||||
Event
|
||||
} from "./types";
|
||||
|
||||
export interface IAuditLog {
|
||||
actor: Actor;
|
||||
organization: Types.ObjectId;
|
||||
workspace: Types.ObjectId;
|
||||
ipAddress: string;
|
||||
event: Event;
|
||||
userAgent: string;
|
||||
userAgentType: UserAgentType;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
const auditLogSchema = new Schema<IAuditLog>(
|
||||
{
|
||||
actor: {
|
||||
type: {
|
||||
type: String,
|
||||
enum: ActorType,
|
||||
required: true
|
||||
},
|
||||
metadata: {
|
||||
type: Schema.Types.Mixed
|
||||
}
|
||||
},
|
||||
organization: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: false
|
||||
},
|
||||
workspace: {
|
||||
type: Schema.Types.ObjectId,
|
||||
required: false
|
||||
},
|
||||
ipAddress: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
event: {
|
||||
type: {
|
||||
type: String,
|
||||
enum: EventType,
|
||||
required: true
|
||||
},
|
||||
metadata: {
|
||||
type: Schema.Types.Mixed
|
||||
}
|
||||
},
|
||||
userAgent: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
userAgentType: {
|
||||
type: String,
|
||||
enum: UserAgentType,
|
||||
required: true
|
||||
},
|
||||
expiresAt: {
|
||||
type: Date,
|
||||
expires: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
export const AuditLog = model<IAuditLog>("AuditLog", auditLogSchema);
|
45
backend/src/ee/models/auditLog/enums.ts
Normal file
45
backend/src/ee/models/auditLog/enums.ts
Normal file
@ -0,0 +1,45 @@
|
||||
export enum ActorType {
|
||||
USER = "user",
|
||||
SERVICE = "service"
|
||||
}
|
||||
|
||||
export enum UserAgentType {
|
||||
WEB = "web",
|
||||
CLI = "cli",
|
||||
K8_OPERATOR = "k8-operator",
|
||||
OTHER = "other"
|
||||
}
|
||||
|
||||
export enum EventType {
|
||||
GET_SECRETS = "get-secrets",
|
||||
GET_SECRET = "get-secret",
|
||||
REVEAL_SECRET = "reveal-secret",
|
||||
CREATE_SECRET = "create-secret",
|
||||
UPDATE_SECRET = "update-secret",
|
||||
DELETE_SECRET = "delete-secret",
|
||||
GET_WORKSPACE_KEY = "get-workspace-key",
|
||||
AUTHORIZE_INTEGRATION = "authorize-integration",
|
||||
UNAUTHORIZE_INTEGRATION = "unauthorize-integration",
|
||||
CREATE_INTEGRATION = "create-integration",
|
||||
DELETE_INTEGRATION = "delete-integration",
|
||||
ADD_TRUSTED_IP = "add-trusted-ip",
|
||||
UPDATE_TRUSTED_IP = "update-trusted-ip",
|
||||
DELETE_TRUSTED_IP = "delete-trusted-ip",
|
||||
CREATE_SERVICE_TOKEN = "create-service-token",
|
||||
DELETE_SERVICE_TOKEN = "delete-service-token",
|
||||
CREATE_ENVIRONMENT = "create-environment",
|
||||
UPDATE_ENVIRONMENT = "update-environment",
|
||||
DELETE_ENVIRONMENT = "delete-environment",
|
||||
ADD_WORKSPACE_MEMBER = "add-workspace-member",
|
||||
REMOVE_WORKSPACE_MEMBER = "remove-workspace-member",
|
||||
CREATE_FOLDER = "create-folder",
|
||||
UPDATE_FOLDER = "update-folder",
|
||||
DELETE_FOLDER = "delete-folder",
|
||||
CREATE_WEBHOOK = "create-webhook",
|
||||
UPDATE_WEBHOOK_STATUS = "update-webhook-status",
|
||||
DELETE_WEBHOOK = "delete-webhook",
|
||||
GET_SECRET_IMPORTS = "get-secret-imports",
|
||||
CREATE_SECRET_IMPORT = "create-secret-import",
|
||||
UPDATE_SECRET_IMPORT = "update-secret-import",
|
||||
DELETE_SECRET_IMPORT = "delete-secret-import",
|
||||
}
|
3
backend/src/ee/models/auditLog/index.ts
Normal file
3
backend/src/ee/models/auditLog/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./auditLog";
|
||||
export * from "./enums";
|
||||
export * from "./types";
|
379
backend/src/ee/models/auditLog/types.ts
Normal file
379
backend/src/ee/models/auditLog/types.ts
Normal file
@ -0,0 +1,379 @@
|
||||
import {
|
||||
ActorType,
|
||||
EventType
|
||||
} from "./enums";
|
||||
|
||||
interface UserActorMetadata {
|
||||
userId: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface ServiceActorMetadata {
|
||||
serviceId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface UserActor {
|
||||
type: ActorType.USER;
|
||||
metadata: UserActorMetadata;
|
||||
}
|
||||
|
||||
export interface ServiceActor {
|
||||
type: ActorType.SERVICE;
|
||||
metadata: ServiceActorMetadata;
|
||||
}
|
||||
|
||||
export type Actor =
|
||||
| UserActor
|
||||
| ServiceActor;
|
||||
|
||||
interface GetSecretsEvent {
|
||||
type: EventType.GET_SECRETS;
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
numberOfSecrets: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface GetSecretEvent {
|
||||
type: EventType.GET_SECRET;
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
secretVersion: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface CreateSecretEvent {
|
||||
type: EventType.CREATE_SECRET;
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
secretVersion: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateSecretEvent {
|
||||
type: EventType.UPDATE_SECRET;
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
secretVersion: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteSecretEvent {
|
||||
type: EventType.DELETE_SECRET;
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretId: string;
|
||||
secretKey: string;
|
||||
secretVersion: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface GetWorkspaceKeyEvent {
|
||||
type: EventType.GET_WORKSPACE_KEY,
|
||||
metadata: {
|
||||
keyId: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface AuthorizeIntegrationEvent {
|
||||
type: EventType.AUTHORIZE_INTEGRATION;
|
||||
metadata: {
|
||||
integration: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface UnauthorizeIntegrationEvent {
|
||||
type: EventType.UNAUTHORIZE_INTEGRATION;
|
||||
metadata: {
|
||||
integration: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateIntegrationEvent {
|
||||
type: EventType.CREATE_INTEGRATION;
|
||||
metadata: {
|
||||
integrationId: string;
|
||||
integration: string; // TODO: fix type
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
url?: string;
|
||||
app?: string;
|
||||
appId?: string;
|
||||
targetEnvironment?: string;
|
||||
targetEnvironmentId?: string;
|
||||
targetService?: string;
|
||||
targetServiceId?: string;
|
||||
path?: string;
|
||||
region?: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteIntegrationEvent {
|
||||
type: EventType.DELETE_INTEGRATION;
|
||||
metadata: {
|
||||
integrationId: string;
|
||||
integration: string; // TODO: fix type
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
url?: string;
|
||||
app?: string;
|
||||
appId?: string;
|
||||
targetEnvironment?: string;
|
||||
targetEnvironmentId?: string;
|
||||
targetService?: string;
|
||||
targetServiceId?: string;
|
||||
path?: string;
|
||||
region?: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface AddTrustedIPEvent {
|
||||
type: EventType.ADD_TRUSTED_IP;
|
||||
metadata: {
|
||||
trustedIpId: string;
|
||||
ipAddress: string;
|
||||
prefix?: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateTrustedIPEvent {
|
||||
type: EventType.UPDATE_TRUSTED_IP;
|
||||
metadata: {
|
||||
trustedIpId: string;
|
||||
ipAddress: string;
|
||||
prefix?: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteTrustedIPEvent {
|
||||
type: EventType.DELETE_TRUSTED_IP;
|
||||
metadata: {
|
||||
trustedIpId: string;
|
||||
ipAddress: string;
|
||||
prefix?: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateServiceTokenEvent {
|
||||
type: EventType.CREATE_SERVICE_TOKEN;
|
||||
metadata: {
|
||||
name: string;
|
||||
scopes: Array<{
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteServiceTokenEvent {
|
||||
type: EventType.DELETE_SERVICE_TOKEN;
|
||||
metadata: {
|
||||
name: string;
|
||||
scopes: Array<{
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateEnvironmentEvent {
|
||||
type: EventType.CREATE_ENVIRONMENT;
|
||||
metadata: {
|
||||
name: string;
|
||||
slug: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateEnvironmentEvent {
|
||||
type: EventType.UPDATE_ENVIRONMENT;
|
||||
metadata: {
|
||||
oldName: string;
|
||||
newName: string;
|
||||
oldSlug: string;
|
||||
newSlug: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteEnvironmentEvent {
|
||||
type: EventType.DELETE_ENVIRONMENT;
|
||||
metadata: {
|
||||
name: string;
|
||||
slug: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface AddWorkspaceMemberEvent {
|
||||
type: EventType.ADD_WORKSPACE_MEMBER;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface RemoveWorkspaceMemberEvent {
|
||||
type: EventType.REMOVE_WORKSPACE_MEMBER;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateFolderEvent {
|
||||
type: EventType.CREATE_FOLDER;
|
||||
metadata: {
|
||||
environment: string;
|
||||
folderId: string;
|
||||
folderName: string;
|
||||
folderPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateFolderEvent {
|
||||
type: EventType.UPDATE_FOLDER;
|
||||
metadata: {
|
||||
environment: string;
|
||||
folderId: string;
|
||||
oldFolderName: string;
|
||||
newFolderName: string;
|
||||
folderPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteFolderEvent {
|
||||
type: EventType.DELETE_FOLDER;
|
||||
metadata: {
|
||||
environment: string;
|
||||
folderId: string;
|
||||
folderName: string;
|
||||
folderPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateWebhookEvent {
|
||||
type: EventType.CREATE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
webhookUrl: string;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateWebhookStatusEvent {
|
||||
type: EventType.UPDATE_WEBHOOK_STATUS,
|
||||
metadata: {
|
||||
webhookId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
webhookUrl: string;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteWebhookEvent {
|
||||
type: EventType.DELETE_WEBHOOK,
|
||||
metadata: {
|
||||
webhookId: string;
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
webhookUrl: string;
|
||||
isDisabled: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
interface GetSecretImportsEvent {
|
||||
type: EventType.GET_SECRET_IMPORTS,
|
||||
metadata: {
|
||||
environment: string;
|
||||
secretImportId: string;
|
||||
folderId: string;
|
||||
numberOfImports: number;
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateSecretImportEvent {
|
||||
type: EventType.CREATE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: string;
|
||||
folderId: string;
|
||||
importFromEnvironment: string;
|
||||
importFromSecretPath: string;
|
||||
importToEnvironment: string;
|
||||
importToSecretPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface UpdateSecretImportEvent {
|
||||
type: EventType.UPDATE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: string;
|
||||
folderId: string;
|
||||
importToEnvironment: string;
|
||||
importToSecretPath: string;
|
||||
orderBefore: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
}[],
|
||||
orderAfter: {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
}[]
|
||||
}
|
||||
}
|
||||
|
||||
interface DeleteSecretImportEvent {
|
||||
type: EventType.DELETE_SECRET_IMPORT,
|
||||
metadata: {
|
||||
secretImportId: string;
|
||||
folderId: string;
|
||||
importFromEnvironment: string;
|
||||
importFromSecretPath: string;
|
||||
importToEnvironment: string;
|
||||
importToSecretPath: string;
|
||||
}
|
||||
}
|
||||
|
||||
export type Event =
|
||||
| GetSecretsEvent
|
||||
| GetSecretEvent
|
||||
| CreateSecretEvent
|
||||
| UpdateSecretEvent
|
||||
| DeleteSecretEvent
|
||||
| GetWorkspaceKeyEvent
|
||||
| AuthorizeIntegrationEvent
|
||||
| UnauthorizeIntegrationEvent
|
||||
| CreateIntegrationEvent
|
||||
| DeleteIntegrationEvent
|
||||
| AddTrustedIPEvent
|
||||
| UpdateTrustedIPEvent
|
||||
| DeleteTrustedIPEvent
|
||||
| CreateServiceTokenEvent
|
||||
| DeleteServiceTokenEvent
|
||||
| CreateEnvironmentEvent
|
||||
| UpdateEnvironmentEvent
|
||||
| DeleteEnvironmentEvent
|
||||
| AddWorkspaceMemberEvent
|
||||
| RemoveWorkspaceMemberEvent
|
||||
| CreateFolderEvent
|
||||
| UpdateFolderEvent
|
||||
| DeleteFolderEvent
|
||||
| CreateWebhookEvent
|
||||
| UpdateWebhookStatusEvent
|
||||
| DeleteWebhookEvent
|
||||
| GetSecretImportsEvent
|
||||
| CreateSecretImportEvent
|
||||
| UpdateSecretImportEvent
|
||||
| DeleteSecretImportEvent;
|
@ -4,4 +4,8 @@ export * from "./folderVersion";
|
||||
export * from "./log";
|
||||
export * from "./action";
|
||||
export * from "./ssoConfig";
|
||||
export * from "./trustedIp";
|
||||
export * from "./trustedIp";
|
||||
export * from "./auditLog";
|
||||
export * from "./gitRisks";
|
||||
export * from "./gitAppOrganizationInstallation";
|
||||
export * from "./gitAppInstallationSession";
|
||||
|
@ -6,11 +6,12 @@ import {
|
||||
} from "../../../middleware";
|
||||
import { query } from "express-validator";
|
||||
import { cloudProductsController } from "../../controllers/v1";
|
||||
import { AuthMode } from "../../../variables";
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt", "apiKey"],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
query("billing-cycle").exists().isIn(["monthly", "yearly"]),
|
||||
validateRequest,
|
||||
|
@ -6,6 +6,7 @@ import users from "./users";
|
||||
import workspace from "./workspace";
|
||||
import action from "./action";
|
||||
import cloudProducts from "./cloudProducts";
|
||||
import secretScanning from "./secretScanning";
|
||||
|
||||
export {
|
||||
secret,
|
||||
@ -16,4 +17,5 @@ export {
|
||||
workspace,
|
||||
action,
|
||||
cloudProducts,
|
||||
secretScanning
|
||||
}
|
@ -8,13 +8,13 @@ import {
|
||||
import { body, param, query } from "express-validator";
|
||||
import { organizationsController } from "../../controllers/v1";
|
||||
import {
|
||||
ACCEPTED, ADMIN, MEMBER, OWNER,
|
||||
ACCEPTED, ADMIN, AuthMode, MEMBER, OWNER
|
||||
} from "../../../variables";
|
||||
|
||||
router.get(
|
||||
"/:organizationId/plans/table",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -29,7 +29,7 @@ router.get(
|
||||
router.get(
|
||||
"/:organizationId/plan",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -44,7 +44,7 @@ router.get(
|
||||
router.post(
|
||||
"/:organizationId/session/trial",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -59,7 +59,7 @@ router.post(
|
||||
router.get(
|
||||
"/:organizationId/plan/billing",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -74,7 +74,7 @@ router.get(
|
||||
router.get(
|
||||
"/:organizationId/plan/table",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -89,7 +89,7 @@ router.get(
|
||||
router.get(
|
||||
"/:organizationId/billing-details",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -103,7 +103,7 @@ router.get(
|
||||
router.patch(
|
||||
"/:organizationId/billing-details",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -119,7 +119,7 @@ router.patch(
|
||||
router.get(
|
||||
"/:organizationId/billing-details/payment-methods",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -133,7 +133,7 @@ router.get(
|
||||
router.post(
|
||||
"/:organizationId/billing-details/payment-methods",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -149,7 +149,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:organizationId/billing-details/payment-methods/:pmtMethodId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -164,7 +164,7 @@ router.delete(
|
||||
router.get(
|
||||
"/:organizationId/billing-details/tax-ids",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -178,7 +178,7 @@ router.get(
|
||||
router.post(
|
||||
"/:organizationId/billing-details/tax-ids",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -194,7 +194,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:organizationId/billing-details/tax-ids/:taxId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -209,7 +209,7 @@ router.delete(
|
||||
router.get(
|
||||
"/:organizationId/invoices",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -223,7 +223,7 @@ router.get(
|
||||
router.get(
|
||||
"/:organizationId/licenses",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
|
@ -9,15 +9,16 @@ import { body, param, query } from "express-validator";
|
||||
import { secretController } from "../../controllers/v1";
|
||||
import {
|
||||
ADMIN,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
PERMISSION_READ_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS
|
||||
} from "../../../variables";
|
||||
|
||||
router.get(
|
||||
"/:secretId/secret-versions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt", "apiKey"],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireSecretAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -33,7 +34,7 @@ router.get(
|
||||
router.post(
|
||||
"/:secretId/secret-versions/rollback",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt", "apiKey"],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireSecretAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -4,15 +4,15 @@ import {
|
||||
requireAuth,
|
||||
requireOrganizationAuth,
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
} from "../../../middleware";
|
||||
import { body, param } from "express-validator";
|
||||
import { createInstallationSession, getCurrentOrganizationInstallationStatus, getRisksForOrganization, linkInstallationToOrganization, updateRisksStatus } from "../../controllers/v1/secretScanningController";
|
||||
import { ACCEPTED, ADMIN, MEMBER, OWNER } from "../../variables";
|
||||
import { createInstallationSession, getCurrentOrganizationInstallationStatus, getRisksForOrganization, linkInstallationToOrganization, updateRisksStatus } from "../../../controllers/v1/secretScanningController";
|
||||
import { ACCEPTED, ADMIN, AuthMode, MEMBER, OWNER } from "../../../variables";
|
||||
|
||||
router.post(
|
||||
"/create-installation-session/organization/:organizationId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("organizationId").exists().trim(),
|
||||
requireOrganizationAuth({
|
||||
@ -26,7 +26,7 @@ router.post(
|
||||
router.post(
|
||||
"/link-installation",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("installationId").exists().trim(),
|
||||
body("sessionId").exists().trim(),
|
||||
@ -37,7 +37,7 @@ router.post(
|
||||
router.get(
|
||||
"/installation-status/organization/:organizationId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("organizationId").exists().trim(),
|
||||
requireOrganizationAuth({
|
||||
@ -51,7 +51,7 @@ router.get(
|
||||
router.get(
|
||||
"/organization/:organizationId/risks",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("organizationId").exists().trim(),
|
||||
requireOrganizationAuth({
|
||||
@ -65,7 +65,7 @@ router.get(
|
||||
router.post(
|
||||
"/organization/:organizationId/risks/:riskId/status",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("organizationId").exists().trim(),
|
||||
param("riskId").exists().trim(),
|
@ -8,13 +8,13 @@ import {
|
||||
validateRequest,
|
||||
} from "../../../middleware";
|
||||
import { param } from "express-validator";
|
||||
import { ADMIN, MEMBER } from "../../../variables";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../../variables";
|
||||
import { secretSnapshotController } from "../../controllers/v1";
|
||||
|
||||
router.get(
|
||||
"/:secretSnapshotId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireSecretSnapshotAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -15,6 +15,7 @@ import { authLimiter } from "../../../helpers/rateLimiter";
|
||||
import {
|
||||
ACCEPTED,
|
||||
ADMIN,
|
||||
AuthMode,
|
||||
OWNER
|
||||
} from "../../../variables";
|
||||
|
||||
@ -90,7 +91,7 @@ router.post("/saml2/:ssoIdentifier",
|
||||
router.get(
|
||||
"/config",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
@ -105,7 +106,7 @@ router.get(
|
||||
router.post(
|
||||
"/config",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
@ -125,7 +126,7 @@ router.post(
|
||||
router.patch(
|
||||
"/config",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
|
@ -3,13 +3,13 @@ const router = express.Router();
|
||||
import {
|
||||
requireAuth
|
||||
} from "../../../middleware";
|
||||
import { AUTH_MODE_API_KEY, AUTH_MODE_JWT } from "../../../variables";
|
||||
import { AuthMode } from "../../../variables";
|
||||
import { usersController } from "../../controllers/v1";
|
||||
|
||||
router.get(
|
||||
"/me/ip",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
usersController.getMyIp
|
||||
);
|
||||
|
@ -8,16 +8,16 @@ import {
|
||||
import { body, param, query } from "express-validator";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../../variables";
|
||||
import { workspaceController } from "../../controllers/v1";
|
||||
import { EventType, UserAgentType } from "../../models";
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/secret-snapshots",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -35,7 +35,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/secret-snapshots/count",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -51,7 +51,7 @@ router.get(
|
||||
router.post(
|
||||
"/:workspaceId/secret-snapshots/rollback",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -68,7 +68,7 @@ router.post(
|
||||
router.get(
|
||||
"/:workspaceId/logs",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -84,11 +84,46 @@ router.get(
|
||||
workspaceController.getWorkspaceLogs
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/audit-logs",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
locationWorkspaceId: "params",
|
||||
}),
|
||||
param("workspaceId").exists().trim(),
|
||||
query("eventType").isString().isIn(Object.values(EventType)).optional({ nullable: true }),
|
||||
query("userAgentType").isString().isIn(Object.values(UserAgentType)).optional({ nullable: true }),
|
||||
query("actor").optional({ nullable: true }),
|
||||
query("startDate").isISO8601().withMessage("Invalid start date format").optional({ nullable: true }),
|
||||
query("endDate").isISO8601().withMessage("Invalid end date format").optional({ nullable: true }),
|
||||
query("offset"),
|
||||
query("limit"),
|
||||
validateRequest,
|
||||
workspaceController.getWorkspaceAuditLogs
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/audit-logs/filters/actors",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
locationWorkspaceId: "params",
|
||||
}),
|
||||
param("workspaceId").exists().trim(),
|
||||
validateRequest,
|
||||
workspaceController.getWorkspaceAuditLogActorFilterOpts
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/trusted-ips",
|
||||
param("workspaceId").exists().isString().trim(),
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -105,7 +140,7 @@ router.post(
|
||||
body("isActive").exists().isBoolean(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -122,7 +157,7 @@ router.patch(
|
||||
body("comment").default("").isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -137,7 +172,7 @@ router.delete(
|
||||
param("trustedIpId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
|
50
backend/src/ee/services/EEAuditLogService.ts
Normal file
50
backend/src/ee/services/EEAuditLogService.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { Types } from "mongoose";
|
||||
import { AuditLog, Event } from "../models";
|
||||
import { AuthData } from "../../interfaces/middleware";
|
||||
import EELicenseService from "./EELicenseService";
|
||||
import { Workspace } from "../../models";
|
||||
import { OrganizationNotFoundError } from "../../utils/errors";
|
||||
|
||||
interface EventScope {
|
||||
workspaceId?: Types.ObjectId;
|
||||
organizationId?: Types.ObjectId;
|
||||
}
|
||||
|
||||
type ValidEventScope =
|
||||
| Required<Pick<EventScope, "workspaceId">>
|
||||
| Required<Pick<EventScope, "organizationId">>
|
||||
| Required<EventScope>
|
||||
|
||||
export default class EEAuditLogService {
|
||||
static async createAuditLog(authData: AuthData, event: Event, eventScope: ValidEventScope, shouldSave: boolean = true) {
|
||||
|
||||
const MS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
const organizationId = ("organizationId" in eventScope)
|
||||
? eventScope.organizationId
|
||||
: (await Workspace.findById(eventScope.workspaceId).select("organization").lean())?.organization;
|
||||
|
||||
if (!organizationId) throw OrganizationNotFoundError({
|
||||
message: "createAuditLog: Failed to create audit log due to missing organizationId"
|
||||
});
|
||||
|
||||
const ttl = (await EELicenseService.getPlan(organizationId)).auditLogsRetentionDays * MS_IN_DAY;
|
||||
|
||||
const auditLog = await new AuditLog({
|
||||
actor: authData.actor,
|
||||
organization: organizationId,
|
||||
workspace: ("workspaceId" in eventScope) ? eventScope.workspaceId : undefined,
|
||||
ipAddress: authData.ipAddress,
|
||||
event,
|
||||
userAgent: authData.userAgent,
|
||||
userAgentType: authData.userAgentType,
|
||||
expiresAt: new Date(Date.now() + ttl)
|
||||
});
|
||||
|
||||
if (shouldSave) {
|
||||
await auditLog.save();
|
||||
}
|
||||
|
||||
return auditLog;
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import { Types } from "mongoose";
|
||||
import * as Sentry from "@sentry/node";
|
||||
import NodeCache from "node-cache";
|
||||
import {
|
||||
@ -31,6 +32,7 @@ interface FeatureSet {
|
||||
customRateLimits: boolean;
|
||||
customAlerts: boolean;
|
||||
auditLogs: boolean;
|
||||
auditLogsRetentionDays: number;
|
||||
samlSSO: boolean;
|
||||
status: "incomplete" | "incomplete_expired" | "trialing" | "active" | "past_due" | "canceled" | "unpaid" | null;
|
||||
trial_end: number | null;
|
||||
@ -63,9 +65,10 @@ class EELicenseService {
|
||||
pitRecovery: false,
|
||||
ipAllowlisting: false,
|
||||
rbac: true,
|
||||
customRateLimits: true,
|
||||
customAlerts: true,
|
||||
customRateLimits: false,
|
||||
customAlerts: false,
|
||||
auditLogs: false,
|
||||
auditLogsRetentionDays: 0,
|
||||
samlSSO: false,
|
||||
status: null,
|
||||
trial_end: null,
|
||||
@ -81,10 +84,10 @@ class EELicenseService {
|
||||
});
|
||||
}
|
||||
|
||||
public async getPlan(organizationId: string, workspaceId?: string): Promise<FeatureSet> {
|
||||
public async getPlan(organizationId: Types.ObjectId, workspaceId?: Types.ObjectId): Promise<FeatureSet> {
|
||||
try {
|
||||
if (this.instanceType === "cloud") {
|
||||
const cachedPlan = this.localFeatureSet.get<FeatureSet>(`${organizationId}-${workspaceId ?? ""}`);
|
||||
const cachedPlan = this.localFeatureSet.get<FeatureSet>(`${organizationId.toString()}-${workspaceId?.toString() ?? ""}`);
|
||||
if (cachedPlan) {
|
||||
return cachedPlan;
|
||||
}
|
||||
@ -101,7 +104,7 @@ class EELicenseService {
|
||||
const { data: { currentPlan } } = await licenseServerKeyRequest.get(url);
|
||||
|
||||
// cache fetched plan for organization
|
||||
this.localFeatureSet.set(`${organizationId}-${workspaceId ?? ""}`, currentPlan);
|
||||
this.localFeatureSet.set(`${organizationId.toString()}-${workspaceId?.toString() ?? ""}`, currentPlan);
|
||||
|
||||
return currentPlan;
|
||||
}
|
||||
@ -112,16 +115,16 @@ class EELicenseService {
|
||||
return this.globalFeatureSet;
|
||||
}
|
||||
|
||||
public async refreshPlan(organizationId: string, workspaceId?: string) {
|
||||
public async refreshPlan(organizationId: Types.ObjectId, workspaceId?: Types.ObjectId) {
|
||||
if (this.instanceType === "cloud") {
|
||||
this.localFeatureSet.del(`${organizationId}-${workspaceId ?? ""}`);
|
||||
this.localFeatureSet.del(`${organizationId.toString()}-${workspaceId?.toString() ?? ""}`);
|
||||
await this.getPlan(organizationId, workspaceId);
|
||||
}
|
||||
}
|
||||
|
||||
public async delPlan(organizationId: string) {
|
||||
public async delPlan(organizationId: Types.ObjectId) {
|
||||
if (this.instanceType === "cloud") {
|
||||
this.localFeatureSet.del(`${organizationId}-`);
|
||||
this.localFeatureSet.del(`${organizationId.toString()}-`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import EELicenseService from "./EELicenseService";
|
||||
/**
|
||||
* Class to handle Enterprise Edition secret actions
|
||||
*/
|
||||
class EESecretService {
|
||||
export default class EESecretService {
|
||||
/**
|
||||
* Save a secret snapshot that is a copy of the current state of secrets in workspace with id
|
||||
* [workspaceId] under a new snapshot with incremented version under the
|
||||
@ -71,5 +71,3 @@ class EESecretService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default EESecretService;
|
||||
|
@ -3,13 +3,13 @@ import { exec } from "child_process";
|
||||
import { mkdir, readFile, rm, writeFile } from "fs";
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path"
|
||||
import GitRisks from "../models/gitRisks";
|
||||
import GitAppOrganizationInstallation from "../models/gitAppOrganizationInstallation";
|
||||
import MembershipOrg from "../models/membershipOrg";
|
||||
import { ADMIN, OWNER } from "../variables";
|
||||
import User from "../models/user";
|
||||
import { sendMail } from "../helpers";
|
||||
import TelemetryService from "./TelemetryService";
|
||||
import GitRisks from "../../models/gitRisks";
|
||||
import GitAppOrganizationInstallation from "../../models/gitAppOrganizationInstallation";
|
||||
import MembershipOrg from "../../../models/membershipOrg";
|
||||
import { ADMIN, OWNER } from "../../../variables";
|
||||
import User from "../../../models/user";
|
||||
import { sendMail } from "../../../helpers";
|
||||
import TelemetryService from "../../../services/TelemetryService";
|
||||
|
||||
type SecretMatch = {
|
||||
Description: string;
|
@ -1,9 +1,13 @@
|
||||
import EELicenseService from "./EELicenseService";
|
||||
import EESecretService from "./EESecretService";
|
||||
import EELogService from "./EELogService";
|
||||
import EEAuditLogService from "./EEAuditLogService";
|
||||
import GithubSecretScanningService from "./GithubSecretScanning/GithubSecretScanningService"
|
||||
|
||||
export {
|
||||
EELicenseService,
|
||||
EESecretService,
|
||||
EELogService,
|
||||
EEAuditLogService,
|
||||
GithubSecretScanningService
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import { Request } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import jwt from "jsonwebtoken";
|
||||
import bcrypt from "bcrypt";
|
||||
@ -5,7 +6,6 @@ import {
|
||||
APIKeyData,
|
||||
ITokenVersion,
|
||||
IUser,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
TokenVersion,
|
||||
User,
|
||||
@ -14,7 +14,6 @@ import {
|
||||
APIKeyDataNotFoundError,
|
||||
AccountNotFoundError,
|
||||
BadRequestError,
|
||||
ServiceAccountNotFoundError,
|
||||
ServiceTokenDataNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
@ -26,11 +25,15 @@ import {
|
||||
getJwtRefreshSecret,
|
||||
} from "../config";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AuthMode
|
||||
} from "../variables";
|
||||
import {
|
||||
ServiceTokenAuthData,
|
||||
UserAuthData
|
||||
} from "../interfaces/middleware";
|
||||
|
||||
import { ActorType } from "../ee/models";
|
||||
import { getUserAgentType } from "../utils/posthog";
|
||||
|
||||
/**
|
||||
*
|
||||
@ -42,7 +45,7 @@ export const validateAuthMode = ({
|
||||
acceptedAuthModes,
|
||||
}: {
|
||||
headers: { [key: string]: string | string[] | undefined },
|
||||
acceptedAuthModes: string[]
|
||||
acceptedAuthModes: AuthMode[]
|
||||
}) => {
|
||||
const apiKey = headers["x-api-key"];
|
||||
const authHeader = headers["authorization"];
|
||||
@ -55,7 +58,7 @@ export const validateAuthMode = ({
|
||||
|
||||
if (typeof apiKey === "string") {
|
||||
// case: treat request authentication type as via X-API-KEY (i.e. API Key)
|
||||
authMode = AUTH_MODE_API_KEY;
|
||||
authMode = AuthMode.API_KEY;
|
||||
authTokenValue = apiKey;
|
||||
}
|
||||
|
||||
@ -71,13 +74,10 @@ export const validateAuthMode = ({
|
||||
|
||||
switch (tokenValue.split(".", 1)[0]) {
|
||||
case "st":
|
||||
authMode = AUTH_MODE_SERVICE_TOKEN;
|
||||
break;
|
||||
case "sa":
|
||||
authMode = AUTH_MODE_SERVICE_ACCOUNT;
|
||||
authMode = AuthMode.SERVICE_TOKEN;
|
||||
break;
|
||||
default:
|
||||
authMode = AUTH_MODE_JWT;
|
||||
authMode = AuthMode.JWT;
|
||||
}
|
||||
|
||||
authTokenValue = tokenValue;
|
||||
@ -100,10 +100,12 @@ export const validateAuthMode = ({
|
||||
* @returns {User} user - user corresponding to JWT token
|
||||
*/
|
||||
export const getAuthUserPayload = async ({
|
||||
req,
|
||||
authTokenValue,
|
||||
}: {
|
||||
req: Request,
|
||||
authTokenValue: string;
|
||||
}) => {
|
||||
}): Promise<UserAuthData> => {
|
||||
const decodedToken = <jwt.UserIDJwtPayload>(
|
||||
jwt.verify(authTokenValue, await getJwtAuthSecret())
|
||||
);
|
||||
@ -130,11 +132,25 @@ export const getAuthUserPayload = async ({
|
||||
if (decodedToken.accessVersion !== tokenVersion.accessVersion) throw UnauthorizedRequestError({
|
||||
message: "Failed to validate access token",
|
||||
});
|
||||
|
||||
return ({
|
||||
user,
|
||||
tokenVersionId: tokenVersion._id,
|
||||
});
|
||||
|
||||
return {
|
||||
actor: {
|
||||
type: ActorType.USER,
|
||||
metadata: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email
|
||||
}
|
||||
},
|
||||
authPayload: user,
|
||||
ipAddress: req.realIP,
|
||||
userAgent: req.headers["user-agent"] ?? "",
|
||||
userAgentType: getUserAgentType(req.headers["user-agent"])
|
||||
}
|
||||
|
||||
// return ({
|
||||
// user,
|
||||
// tokenVersionId: tokenVersion._id, // what to do with this? // move this out
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,10 +160,12 @@ export const getAuthUserPayload = async ({
|
||||
* @returns {ServiceTokenData} serviceTokenData - service token data
|
||||
*/
|
||||
export const getAuthSTDPayload = async ({
|
||||
req,
|
||||
authTokenValue,
|
||||
}: {
|
||||
req: Request,
|
||||
authTokenValue: string;
|
||||
}) => {
|
||||
}): Promise<ServiceTokenAuthData> => {
|
||||
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3);
|
||||
|
||||
const serviceTokenData = await ServiceTokenData
|
||||
@ -180,36 +198,21 @@ export const getAuthSTDPayload = async ({
|
||||
|
||||
if (!serviceTokenDataToReturn) throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" });
|
||||
|
||||
return serviceTokenDataToReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service account access key payload
|
||||
* @param {Object} obj
|
||||
* @param {String} obj.authTokenValue - service account access token value
|
||||
* @returns {ServiceAccount} serviceAccount
|
||||
*/
|
||||
export const getAuthSAAKPayload = async ({
|
||||
authTokenValue,
|
||||
}: {
|
||||
authTokenValue: string;
|
||||
}) => {
|
||||
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3);
|
||||
|
||||
const serviceAccount = await ServiceAccount.findById(
|
||||
Buffer.from(TOKEN_IDENTIFIER, "base64").toString("hex")
|
||||
).select("+secretHash");
|
||||
|
||||
if (!serviceAccount) {
|
||||
throw ServiceAccountNotFoundError({ message: "Failed to find service account" });
|
||||
return {
|
||||
actor: {
|
||||
type: ActorType.SERVICE,
|
||||
metadata: {
|
||||
serviceId: serviceTokenDataToReturn._id.toString(),
|
||||
name: serviceTokenDataToReturn.name
|
||||
}
|
||||
},
|
||||
authPayload: serviceTokenDataToReturn,
|
||||
ipAddress: req.realIP,
|
||||
userAgent: req.headers["user-agent"] ?? "",
|
||||
userAgentType: getUserAgentType(req.headers["user-agent"])
|
||||
}
|
||||
|
||||
const result = await bcrypt.compare(TOKEN_SECRET, serviceAccount.secretHash);
|
||||
if (!result) throw UnauthorizedRequestError({
|
||||
message: "Failed to authenticate service account access key",
|
||||
});
|
||||
|
||||
return serviceAccount;
|
||||
// return serviceTokenDataToReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,10 +222,12 @@ export const getAuthSAAKPayload = async ({
|
||||
* @returns {APIKeyData} apiKeyData - API key data
|
||||
*/
|
||||
export const getAuthAPIKeyPayload = async ({
|
||||
req,
|
||||
authTokenValue,
|
||||
}: {
|
||||
req: Request,
|
||||
authTokenValue: string;
|
||||
}) => {
|
||||
}): Promise<UserAuthData> => {
|
||||
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3);
|
||||
|
||||
let apiKeyData = await APIKeyData
|
||||
@ -264,7 +269,19 @@ export const getAuthAPIKeyPayload = async ({
|
||||
});
|
||||
}
|
||||
|
||||
return user;
|
||||
return {
|
||||
actor: {
|
||||
type: ActorType.USER,
|
||||
metadata: {
|
||||
userId: user._id.toString(),
|
||||
email: user.email
|
||||
}
|
||||
},
|
||||
authPayload: user,
|
||||
ipAddress: req.realIP,
|
||||
userAgent: req.headers["user-agent"] ?? "",
|
||||
userAgentType: getUserAgentType(req.headers["user-agent"])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,5 +115,5 @@ export const updateSubscriptionOrgQuantity = async ({
|
||||
);
|
||||
}
|
||||
|
||||
await EELicenseService.refreshPlan(organizationId);
|
||||
await EELicenseService.refreshPlan(new Types.ObjectId(organizationId));
|
||||
};
|
@ -11,9 +11,9 @@ import {
|
||||
IServiceTokenData,
|
||||
Secret,
|
||||
SecretBlindIndexData,
|
||||
ServiceTokenData
|
||||
ServiceTokenData,
|
||||
} from "../models";
|
||||
import { SecretVersion } from "../ee/models";
|
||||
import { EventType, SecretVersion } from "../ee/models";
|
||||
import {
|
||||
BadRequestError,
|
||||
InternalServerError,
|
||||
@ -40,7 +40,7 @@ import {
|
||||
} from "../utils/crypto";
|
||||
import { TelemetryService } from "../services";
|
||||
import { client, getEncryptionKey, getRootEncryptionKey } from "../config";
|
||||
import { EELogService, EESecretService } from "../ee/services";
|
||||
import { EEAuditLogService, EELogService, EESecretService } from "../ee/services";
|
||||
import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/auth";
|
||||
import { getFolderByPath, getFolderIdFromServiceToken } from "../services/FolderService";
|
||||
import picomatch from "picomatch";
|
||||
@ -433,10 +433,27 @@ export const createSecretHelper = async ({
|
||||
...getAuthDataPayloadIdObj(authData),
|
||||
workspaceId,
|
||||
actions: [action],
|
||||
channel: authData.authChannel,
|
||||
ipAddress: authData.authIP
|
||||
channel: authData.userAgentType,
|
||||
ipAddress: authData.ipAddress
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
authData,
|
||||
{
|
||||
type: EventType.CREATE_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath,
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secretName,
|
||||
secretVersion: secret.version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
@ -457,8 +474,8 @@ export const createSecretHelper = async ({
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
channel: authData.authChannel,
|
||||
userAgent: authData.authUserAgent
|
||||
channel: authData.userAgentType,
|
||||
userAgent: authData.userAgent
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -528,9 +545,24 @@ export const getSecretsHelper = async ({
|
||||
...getAuthDataPayloadIdObj(authData),
|
||||
workspaceId,
|
||||
actions: [action],
|
||||
channel: authData.authChannel,
|
||||
ipAddress: authData.authIP
|
||||
channel: authData.userAgentType,
|
||||
ipAddress: authData.ipAddress
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
authData,
|
||||
{
|
||||
type: EventType.GET_SECRETS,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath,
|
||||
numberOfSecrets: secrets.length
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
|
||||
@ -545,8 +577,8 @@ export const getSecretsHelper = async ({
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
channel: authData.authChannel,
|
||||
userAgent: authData.authUserAgent
|
||||
channel: authData.userAgentType,
|
||||
userAgent: authData.userAgent
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -622,10 +654,27 @@ export const getSecretHelper = async ({
|
||||
...getAuthDataPayloadIdObj(authData),
|
||||
workspaceId,
|
||||
actions: [action],
|
||||
channel: authData.authChannel,
|
||||
ipAddress: authData.authIP
|
||||
channel: authData.userAgentType,
|
||||
ipAddress: authData.ipAddress
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
authData,
|
||||
{
|
||||
type: EventType.GET_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath,
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secretName,
|
||||
secretVersion: secret.version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
const postHogClient = await TelemetryService.getPostHogClient();
|
||||
|
||||
if (postHogClient) {
|
||||
@ -639,8 +688,8 @@ export const getSecretHelper = async ({
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
channel: authData.authChannel,
|
||||
userAgent: authData.authUserAgent
|
||||
channel: authData.userAgentType,
|
||||
userAgent: authData.userAgent
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -771,9 +820,26 @@ export const updateSecretHelper = async ({
|
||||
...getAuthDataPayloadIdObj(authData),
|
||||
workspaceId,
|
||||
actions: [action],
|
||||
channel: authData.authChannel,
|
||||
ipAddress: authData.authIP
|
||||
channel: authData.userAgentType,
|
||||
ipAddress: authData.ipAddress
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
authData,
|
||||
{
|
||||
type: EventType.UPDATE_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath,
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secretName,
|
||||
secretVersion: secret.version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
@ -795,8 +861,8 @@ export const updateSecretHelper = async ({
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
channel: authData.authChannel,
|
||||
userAgent: authData.authUserAgent
|
||||
channel: authData.userAgentType,
|
||||
userAgent: authData.userAgent
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -894,10 +960,27 @@ export const deleteSecretHelper = async ({
|
||||
...getAuthDataPayloadIdObj(authData),
|
||||
workspaceId,
|
||||
actions: [action],
|
||||
channel: authData.authChannel,
|
||||
ipAddress: authData.authIP
|
||||
channel: authData.userAgentType,
|
||||
ipAddress: authData.ipAddress
|
||||
}));
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
authData,
|
||||
{
|
||||
type: EventType.DELETE_SECRET,
|
||||
metadata: {
|
||||
environment,
|
||||
secretPath,
|
||||
secretId: secret._id.toString(),
|
||||
secretKey: secretName,
|
||||
secretVersion: secret.version
|
||||
}
|
||||
},
|
||||
{
|
||||
workspaceId
|
||||
}
|
||||
);
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId,
|
||||
@ -918,8 +1001,8 @@ export const deleteSecretHelper = async ({
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
channel: authData.authChannel,
|
||||
userAgent: authData.authUserAgent
|
||||
channel: authData.userAgentType,
|
||||
userAgent: authData.userAgent
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
Bot,
|
||||
Key,
|
||||
@ -25,7 +26,7 @@ export const createWorkspace = async ({
|
||||
organizationId,
|
||||
}: {
|
||||
name: string;
|
||||
organizationId: string;
|
||||
organizationId: Types.ObjectId;
|
||||
}) => {
|
||||
// create workspace
|
||||
const workspace = await new Workspace({
|
||||
|
@ -5,8 +5,8 @@ import express from "express";
|
||||
require("express-async-errors");
|
||||
import helmet from "helmet";
|
||||
import cors from "cors";
|
||||
import { DatabaseService, GithubSecretScanningService } from "./services";
|
||||
import { EELicenseService } from "./ee/services";
|
||||
import { DatabaseService } from "./services";
|
||||
import { EELicenseService, GithubSecretScanningService} from "./ee/services";
|
||||
import { setUpHealthEndpoint } from "./services/health";
|
||||
import cookieParser from "cookie-parser";
|
||||
import swaggerUi = require("swagger-ui-express");
|
||||
@ -24,6 +24,7 @@ import {
|
||||
secretSnapshot as eeSecretSnapshotRouter,
|
||||
users as eeUsersRouter,
|
||||
workspace as eeWorkspaceRouter,
|
||||
secretScanning as v1SecretScanningRouter,
|
||||
} from "./ee/routes/v1";
|
||||
import {
|
||||
auth as v1AuthRouter,
|
||||
@ -38,7 +39,6 @@ import {
|
||||
password as v1PasswordRouter,
|
||||
secretImport as v1SecretImportRouter,
|
||||
secret as v1SecretRouter,
|
||||
secretScanning as v1SecretScanningRouter,
|
||||
secretsFolder as v1SecretsFolder,
|
||||
serviceToken as v1ServiceTokenRouter,
|
||||
signup as v1SignupRouter,
|
||||
|
@ -1,15 +1,31 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
} from "../../models";
|
||||
import {
|
||||
ServiceActor,
|
||||
UserActor,
|
||||
UserAgentType
|
||||
} from "../../ee/models";
|
||||
|
||||
export interface AuthData {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
authChannel: string;
|
||||
authIP: string;
|
||||
authUserAgent: string;
|
||||
interface BaseAuthData {
|
||||
ipAddress: string;
|
||||
userAgent: string;
|
||||
userAgentType: UserAgentType;
|
||||
tokenVersionId?: Types.ObjectId;
|
||||
}
|
||||
}
|
||||
|
||||
export interface UserAuthData extends BaseAuthData {
|
||||
actor: UserActor;
|
||||
authPayload: IUser;
|
||||
}
|
||||
|
||||
export interface ServiceTokenAuthData extends BaseAuthData {
|
||||
actor: ServiceActor;
|
||||
authPayload: IServiceTokenData;
|
||||
}
|
||||
|
||||
export type AuthData =
|
||||
| UserAuthData
|
||||
| ServiceTokenAuthData;
|
@ -1,25 +1,13 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Types } from "mongoose";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import {
|
||||
getAuthAPIKeyPayload,
|
||||
getAuthSAAKPayload,
|
||||
getAuthSTDPayload,
|
||||
getAuthUserPayload,
|
||||
validateAuthMode,
|
||||
} from "../helpers/auth";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
} from "../models";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { getChannelFromUserAgent } from "../utils/posthog";
|
||||
import { AuthMode } from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
|
||||
declare module "jsonwebtoken" {
|
||||
export interface UserIDJwtPayload extends jwt.JwtPayload {
|
||||
@ -38,9 +26,9 @@ declare module "jsonwebtoken" {
|
||||
* @returns
|
||||
*/
|
||||
const requireAuth = ({
|
||||
acceptedAuthModes = [AUTH_MODE_JWT],
|
||||
acceptedAuthModes = [AuthMode.JWT],
|
||||
}: {
|
||||
acceptedAuthModes: string[];
|
||||
acceptedAuthModes: AuthMode[];
|
||||
}) => {
|
||||
return async (req: Request, res: Response, next: NextFunction) => {
|
||||
|
||||
@ -50,55 +38,36 @@ const requireAuth = ({
|
||||
headers: req.headers,
|
||||
acceptedAuthModes,
|
||||
});
|
||||
|
||||
let authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
let authUserPayload: {
|
||||
user: IUser;
|
||||
tokenVersionId: Types.ObjectId;
|
||||
};
|
||||
|
||||
let authData: AuthData;
|
||||
|
||||
switch (authMode) {
|
||||
case AUTH_MODE_SERVICE_ACCOUNT:
|
||||
authPayload = await getAuthSAAKPayload({
|
||||
case AuthMode.SERVICE_TOKEN:
|
||||
authData = await getAuthSTDPayload({
|
||||
req,
|
||||
authTokenValue,
|
||||
});
|
||||
req.serviceAccount = authPayload;
|
||||
req.serviceTokenData = authData.authPayload;
|
||||
break;
|
||||
case AUTH_MODE_SERVICE_TOKEN:
|
||||
authPayload = await getAuthSTDPayload({
|
||||
authTokenValue,
|
||||
case AuthMode.API_KEY:
|
||||
authData = await getAuthAPIKeyPayload({
|
||||
req,
|
||||
authTokenValue
|
||||
});
|
||||
req.serviceTokenData = authPayload;
|
||||
req.user = authData.authPayload;
|
||||
break;
|
||||
case AUTH_MODE_API_KEY:
|
||||
authPayload = await getAuthAPIKeyPayload({
|
||||
authTokenValue,
|
||||
case AuthMode.JWT:
|
||||
authData = await getAuthUserPayload({
|
||||
req,
|
||||
authTokenValue
|
||||
});
|
||||
req.user = authPayload;
|
||||
break;
|
||||
default:
|
||||
authUserPayload = await getAuthUserPayload({
|
||||
authTokenValue,
|
||||
});
|
||||
authPayload = authUserPayload.user;
|
||||
req.user = authUserPayload.user;
|
||||
req.tokenVersionId = authUserPayload.tokenVersionId;
|
||||
// authPayload = authUserPayload.user;
|
||||
req.user = authData.authPayload;
|
||||
// req.tokenVersionId = authUserPayload.tokenVersionId; // TODO
|
||||
break;
|
||||
}
|
||||
|
||||
req.requestData = {
|
||||
...req.params,
|
||||
...req.query,
|
||||
...req.body,
|
||||
}
|
||||
|
||||
req.authData = {
|
||||
authMode,
|
||||
authPayload, // User, ServiceAccount, ServiceTokenData
|
||||
authChannel: getChannelFromUserAgent(req.headers["user-agent"]),
|
||||
authIP: req.realIP,
|
||||
authUserAgent: req.headers["user-agent"] ?? "other",
|
||||
tokenVersionId: req.tokenVersionId,
|
||||
}
|
||||
|
||||
req.authData = authData;
|
||||
|
||||
return next();
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import Membership, { IMembership } from "./membership";
|
||||
import MembershipOrg, { IMembershipOrg } from "./membershipOrg";
|
||||
import Organization, { IOrganization } from "./organization";
|
||||
import Secret, { ISecret } from "./secret";
|
||||
import Folder, { TFolderRootSchema, TFolderSchema } from "./folder";
|
||||
import SecretImport, { ISecretImports } from "./secretImports";
|
||||
import SecretBlindIndexData, { ISecretBlindIndexData } from "./secretBlindIndexData";
|
||||
import ServiceToken, { IServiceToken } from "./serviceToken";
|
||||
import ServiceAccount, { IServiceAccount } from "./serviceAccount"; // new
|
||||
@ -24,7 +26,6 @@ import ServiceTokenData, { IServiceTokenData } from "./serviceTokenData";
|
||||
import APIKeyData, { IAPIKeyData } from "./apiKeyData";
|
||||
import LoginSRPDetail, { ILoginSRPDetail } from "./loginSRPDetail";
|
||||
import TokenVersion, { ITokenVersion } from "./tokenVersion";
|
||||
import GitRisks, { STATUS_RESOLVED_FALSE_POSITIVE } from "./gitRisks";
|
||||
|
||||
export {
|
||||
AuthProvider,
|
||||
@ -52,6 +53,11 @@ export {
|
||||
IOrganization,
|
||||
Secret,
|
||||
ISecret,
|
||||
Folder,
|
||||
TFolderRootSchema,
|
||||
TFolderSchema,
|
||||
SecretImport,
|
||||
ISecretImports,
|
||||
SecretBlindIndexData,
|
||||
ISecretBlindIndexData,
|
||||
ServiceToken,
|
||||
@ -79,7 +85,5 @@ export {
|
||||
LoginSRPDetail,
|
||||
ILoginSRPDetail,
|
||||
TokenVersion,
|
||||
ITokenVersion,
|
||||
GitRisks,
|
||||
STATUS_RESOLVED_FALSE_POSITIVE
|
||||
ITokenVersion
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ import { body } from "express-validator";
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { authController } from "../../controllers/v1";
|
||||
import { authLimiter } from "../../helpers/rateLimiter";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.post("/token", validateRequest, authController.getNewToken);
|
||||
|
||||
@ -30,7 +30,7 @@ router.post(
|
||||
"/logout",
|
||||
authLimiter,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
authController.logout
|
||||
);
|
||||
@ -38,7 +38,7 @@ router.post(
|
||||
router.post(
|
||||
"/checkAuth",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
authController.checkAuth
|
||||
);
|
||||
@ -53,9 +53,9 @@ router.delete(
|
||||
"/sessions",
|
||||
authLimiter,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
authController.revokeAllSessions
|
||||
);
|
||||
|
||||
export default router;
|
||||
export default router;
|
@ -8,12 +8,12 @@ import {
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { botController } from "../../controllers/v1";
|
||||
import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../variables";
|
||||
|
||||
router.get(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -27,7 +27,7 @@ router.get(
|
||||
router.patch(
|
||||
"/:botId/active",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireBotAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -15,7 +15,6 @@ import password from "./password";
|
||||
import integration from "./integration";
|
||||
import integrationAuth from "./integrationAuth";
|
||||
import secretsFolder from "./secretsFolder";
|
||||
import secretScanning from "./secretScanning";
|
||||
import webhooks from "./webhook";
|
||||
import secretImport from "./secretImport";
|
||||
|
||||
@ -37,7 +36,6 @@ export {
|
||||
integration,
|
||||
integrationAuth,
|
||||
secretsFolder,
|
||||
secretScanning,
|
||||
webhooks,
|
||||
secretImport
|
||||
};
|
||||
|
@ -8,9 +8,8 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
import { body, param } from "express-validator";
|
||||
import { integrationController } from "../../controllers/v1";
|
||||
@ -18,7 +17,7 @@ import { integrationController } from "../../controllers/v1";
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -44,7 +43,7 @@ router.post(
|
||||
router.patch(
|
||||
"/:integrationId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireIntegrationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -64,7 +63,7 @@ router.patch(
|
||||
router.delete(
|
||||
"/:integrationId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireIntegrationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -9,16 +9,15 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
import { integrationAuthController } from "../../controllers/v1";
|
||||
|
||||
router.get(
|
||||
"/integration-options",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
integrationAuthController.getIntegrationOptions
|
||||
);
|
||||
@ -26,7 +25,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -39,7 +38,7 @@ router.get(
|
||||
router.post(
|
||||
"/oauth-token",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -62,7 +61,7 @@ router.post(
|
||||
body("integration").exists().trim().notEmpty(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -74,7 +73,7 @@ router.post(
|
||||
router.get(
|
||||
"/:integrationAuthId/apps",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -89,7 +88,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/teams",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -102,7 +101,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/vercel/branches",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -117,7 +116,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/railway/environments",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -131,7 +130,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/railway/services",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -145,7 +144,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/bitbucket/workspaces",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -158,7 +157,7 @@ router.get(
|
||||
router.get(
|
||||
"/:integrationAuthId/northflank/secret-groups",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -172,7 +171,7 @@ router.get(
|
||||
router.delete(
|
||||
"/:integrationAuthId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireIntegrationAuthorizationAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -3,12 +3,12 @@ const router = express.Router();
|
||||
import { body } from "express-validator";
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { membershipOrgController } from "../../controllers/v1";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.post(
|
||||
"/signup",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("inviteeEmail").exists().trim().notEmpty().isEmail(),
|
||||
body("organizationId").exists().trim().notEmpty(),
|
||||
|
@ -6,13 +6,13 @@ import {
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { body, param } from "express-validator";
|
||||
import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../variables";
|
||||
import { keyController } from "../../controllers/v1";
|
||||
|
||||
router.post(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -27,7 +27,7 @@ router.post(
|
||||
router.get(
|
||||
"/:workspaceId/latest",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -4,14 +4,14 @@ import { body, param } from "express-validator";
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { membershipController } from "../../controllers/v1";
|
||||
import { membershipController as EEMembershipControllers } from "../../ee/controllers/v1";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
// note: ALL DEPRECIATED (moved to api/v2/workspace/:workspaceId/memberships/:membershipId)
|
||||
|
||||
router.get( // used for old CLI (deprecate)
|
||||
"/:workspaceId/connect",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("workspaceId").exists().trim(),
|
||||
validateRequest,
|
||||
@ -21,7 +21,7 @@ router.get( // used for old CLI (deprecate)
|
||||
router.delete(
|
||||
"/:membershipId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("membershipId").exists().trim(),
|
||||
validateRequest,
|
||||
@ -31,7 +31,7 @@ router.delete(
|
||||
router.post(
|
||||
"/:membershipId/change-role",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("role").exists().trim(),
|
||||
validateRequest,
|
||||
@ -41,7 +41,7 @@ router.post(
|
||||
router.post(
|
||||
"/:membershipId/deny-permissions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("membershipId").isMongoId().exists().trim(),
|
||||
body("permissions").isArray().exists(),
|
||||
|
@ -3,13 +3,13 @@ const router = express.Router();
|
||||
import { param } from "express-validator";
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { membershipOrgController } from "../../controllers/v1";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.post(
|
||||
// TODO
|
||||
"/membershipOrg/:membershipOrgId/change-role",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("membershipOrgId"),
|
||||
validateRequest,
|
||||
@ -19,7 +19,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:membershipOrgId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("membershipOrgId").exists().trim(),
|
||||
validateRequest,
|
||||
|
@ -9,16 +9,16 @@ import {
|
||||
import {
|
||||
ACCEPTED,
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
OWNER,
|
||||
OWNER
|
||||
} from "../../variables";
|
||||
import { organizationController } from "../../controllers/v1";
|
||||
|
||||
router.get( // deprecated (moved to api/v2/users/me/organizations)
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
organizationController.getOrganizations
|
||||
);
|
||||
@ -26,7 +26,7 @@ router.get( // deprecated (moved to api/v2/users/me/organizations)
|
||||
router.post( // not used on frontend
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("organizationName").exists().trim().notEmpty(),
|
||||
validateRequest,
|
||||
@ -36,7 +36,7 @@ router.post( // not used on frontend
|
||||
router.get(
|
||||
"/:organizationId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -50,7 +50,7 @@ router.get(
|
||||
router.get( // deprecated (moved to api/v2/organizations/:organizationId/memberships)
|
||||
"/:organizationId/users",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -64,7 +64,7 @@ router.get( // deprecated (moved to api/v2/organizations/:organizationId/members
|
||||
router.get(
|
||||
"/:organizationId/my-workspaces", // deprecated (moved to api/v2/organizations/:organizationId/workspaces)
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -78,7 +78,7 @@ router.get(
|
||||
router.patch(
|
||||
"/:organizationId/name",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -93,7 +93,7 @@ router.patch(
|
||||
router.get(
|
||||
"/:organizationId/incidentContactOrg",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -107,7 +107,7 @@ router.get(
|
||||
router.post(
|
||||
"/:organizationId/incidentContactOrg",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -122,7 +122,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:organizationId/incidentContactOrg",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -137,7 +137,7 @@ router.delete(
|
||||
router.post(
|
||||
"/:organizationId/customer-portal-session",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -151,7 +151,7 @@ router.post(
|
||||
router.get(
|
||||
"/:organizationId/subscriptions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -165,7 +165,7 @@ router.get(
|
||||
router.get(
|
||||
"/:organizationId/workspace-memberships",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
|
@ -4,14 +4,12 @@ import { body } from "express-validator";
|
||||
import { requireAuth, requireSignupAuth, validateRequest } from "../../middleware";
|
||||
import { passwordController } from "../../controllers/v1";
|
||||
import { passwordLimiter } from "../../helpers/rateLimiter";
|
||||
import {
|
||||
AUTH_MODE_JWT,
|
||||
} from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.post(
|
||||
"/srp1",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("clientPublicKey").exists().isString().trim().notEmpty(),
|
||||
validateRequest,
|
||||
@ -22,7 +20,7 @@ router.post(
|
||||
"/change-password",
|
||||
passwordLimiter,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("clientProof").exists().trim().notEmpty(),
|
||||
body("protectedKey").exists().isString().trim().notEmpty(),
|
||||
@ -65,7 +63,7 @@ router.post(
|
||||
"/backup-private-key",
|
||||
passwordLimiter,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("clientProof").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKey").exists().isString().trim().notEmpty(), // (backup) private key encrypted under a strong key
|
||||
|
@ -10,8 +10,8 @@ import { body, param, query } from "express-validator";
|
||||
import { secretController } from "../../controllers/v1";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
|
||||
// note to devs: these endpoints will be deprecated in favor of v2
|
||||
@ -19,7 +19,7 @@ import {
|
||||
router.post(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -37,7 +37,7 @@ router.post(
|
||||
router.get(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -1,14 +1,14 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { body, param, query } from "express-validator";
|
||||
import { secretImportController } from "../../controllers/v1";
|
||||
import { requireAuth, requireWorkspaceAuth, validateRequest } from "../../middleware";
|
||||
import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../variables";
|
||||
const router = express.Router();
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -27,7 +27,7 @@ router.post(
|
||||
router.put(
|
||||
"/:id",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
param("id").exists().isString().trim(),
|
||||
body("secretImports").exists().isArray(),
|
||||
@ -40,7 +40,7 @@ router.put(
|
||||
router.delete(
|
||||
"/:id",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
param("id").exists().isString().trim(),
|
||||
body("secretImportPath").isString().exists().trim(),
|
||||
@ -52,7 +52,7 @@ router.delete(
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -68,7 +68,7 @@ router.get(
|
||||
router.get(
|
||||
"/secrets",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -1,27 +1,23 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import {
|
||||
requireAuth,
|
||||
requireWorkspaceAuth,
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { body, param, query } from "express-validator";
|
||||
import {
|
||||
createFolder,
|
||||
deleteFolder,
|
||||
getFolders,
|
||||
updateFolderById,
|
||||
updateFolderById
|
||||
} from "../../controllers/v1/secretsFolderController";
|
||||
import { ADMIN, MEMBER } from "../../variables";
|
||||
import { requireAuth, requireWorkspaceAuth, validateRequest } from "../../middleware";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../variables";
|
||||
const router = express.Router();
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
locationWorkspaceId: "body",
|
||||
locationWorkspaceId: "body"
|
||||
}),
|
||||
body("workspaceId").exists(),
|
||||
body("environment").exists(),
|
||||
@ -34,7 +30,7 @@ router.post(
|
||||
router.patch(
|
||||
"/:folderId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
body("workspaceId").exists(),
|
||||
body("environment").exists(),
|
||||
@ -46,7 +42,7 @@ router.patch(
|
||||
router.delete(
|
||||
"/:folderId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
body("workspaceId").exists(),
|
||||
body("environment").exists(),
|
||||
@ -58,7 +54,7 @@ router.delete(
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: ["jwt"],
|
||||
acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
query("workspaceId").exists().isString().trim(),
|
||||
query("environment").exists().isString().trim(),
|
||||
|
@ -9,8 +9,8 @@ import {
|
||||
import { body } from "express-validator";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
import { serviceTokenController } from "../../controllers/v1";
|
||||
|
||||
@ -25,7 +25,7 @@ router.get(
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -2,14 +2,12 @@ import express from "express";
|
||||
const router = express.Router();
|
||||
import { requireAuth } from "../../middleware";
|
||||
import { userController } from "../../controllers/v1";
|
||||
import {
|
||||
AUTH_MODE_JWT,
|
||||
} from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
userController.getUser
|
||||
);
|
||||
|
@ -3,13 +3,13 @@ const router = express.Router();
|
||||
import { requireAuth, validateRequest } from "../../middleware";
|
||||
import { body, query } from "express-validator";
|
||||
import { userActionController } from "../../controllers/v1";
|
||||
import { AUTH_MODE_JWT } from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
// note: [userAction] will be deprecated in /v2 in favor of [action]
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("action"),
|
||||
validateRequest,
|
||||
@ -19,7 +19,7 @@ router.post(
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
query("action"),
|
||||
validateRequest,
|
||||
|
@ -2,13 +2,13 @@ import express from "express";
|
||||
const router = express.Router();
|
||||
import { requireAuth, requireWorkspaceAuth, validateRequest } from "../../middleware";
|
||||
import { body, param, query } from "express-validator";
|
||||
import { ADMIN, AUTH_MODE_JWT, MEMBER } from "../../variables";
|
||||
import { ADMIN, AuthMode, MEMBER } from "../../variables";
|
||||
import { webhookController } from "../../controllers/v1";
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -27,7 +27,7 @@ router.post(
|
||||
router.patch(
|
||||
"/:webhookId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("webhookId").exists().isString().trim(),
|
||||
body("isDisabled").default(false).isBoolean(),
|
||||
@ -38,7 +38,7 @@ router.patch(
|
||||
router.post(
|
||||
"/:webhookId/test",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("webhookId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
@ -48,7 +48,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:webhookId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("webhookId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
@ -58,7 +58,7 @@ router.delete(
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -8,16 +8,15 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
import { membershipController, workspaceController } from "../../controllers/v1";
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/keys",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -31,7 +30,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/users",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -45,7 +44,7 @@ router.get(
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
workspaceController.getWorkspaces
|
||||
);
|
||||
@ -53,7 +52,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -67,7 +66,7 @@ router.get(
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("workspaceName").exists().trim().notEmpty(),
|
||||
body("organizationId").exists().trim().notEmpty(),
|
||||
@ -78,7 +77,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:workspaceId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -92,7 +91,7 @@ router.delete(
|
||||
router.post(
|
||||
"/:workspaceId/name",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -107,7 +106,7 @@ router.post(
|
||||
router.post(
|
||||
"/:workspaceId/invite-signup",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -122,7 +121,7 @@ router.post(
|
||||
router.get(
|
||||
"/:workspaceId/integrations",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -136,7 +135,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/authorizations",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -150,7 +149,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/service-tokens", // deprecate
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -9,14 +9,14 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
|
||||
router.post(
|
||||
"/:workspaceId/environments",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -32,7 +32,7 @@ router.post(
|
||||
router.put(
|
||||
"/:workspaceId/environments",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -49,7 +49,7 @@ router.put(
|
||||
router.delete(
|
||||
"/:workspaceId/environments",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -64,7 +64,7 @@ router.delete(
|
||||
router.get(
|
||||
"/:workspaceId/environments",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [MEMBER, ADMIN],
|
||||
|
@ -10,10 +10,9 @@ import { body, param } from "express-validator";
|
||||
import {
|
||||
ACCEPTED,
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
OWNER,
|
||||
OWNER
|
||||
} from "../../variables";
|
||||
import { organizationsController } from "../../controllers/v2";
|
||||
|
||||
@ -24,7 +23,7 @@ router.get(
|
||||
param("organizationId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
@ -40,7 +39,7 @@ router.patch(
|
||||
body("role").exists().isString().trim().isIn([OWNER, ADMIN, MEMBER]),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
@ -59,7 +58,7 @@ router.delete(
|
||||
param("membershipId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
@ -77,7 +76,7 @@ router.get(
|
||||
param("organizationId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
@ -91,7 +90,7 @@ router.get(
|
||||
param("organizationId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
|
@ -8,8 +8,7 @@ import {
|
||||
import { body, param, query } from "express-validator";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
PERMISSION_READ_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS,
|
||||
@ -24,7 +23,7 @@ const router = express.Router();
|
||||
router.post(
|
||||
"/batch-create/workspace/:workspaceId/environment/:environment",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -41,7 +40,7 @@ router.post(
|
||||
router.post(
|
||||
"/workspace/:workspaceId/environment/:environment",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -60,7 +59,7 @@ router.get(
|
||||
param("workspaceId").exists().trim(),
|
||||
query("environment").exists(),
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -74,7 +73,7 @@ router.get(
|
||||
router.get(
|
||||
"/:secretId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN],
|
||||
}),
|
||||
requireSecretAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -87,7 +86,7 @@ router.get(
|
||||
router.delete(
|
||||
"/batch/workspace/:workspaceId/environment/:environmentName",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("workspaceId").exists().isMongoId().trim(),
|
||||
param("environmentName").exists().trim(),
|
||||
@ -103,7 +102,7 @@ router.delete(
|
||||
router.delete(
|
||||
"/:secretId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireSecretAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -117,7 +116,7 @@ router.delete(
|
||||
router.patch(
|
||||
"/batch-modify/workspace/:workspaceId/environment/:environmentName",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("secrets").exists().isArray().custom((secrets: ModifySecretRequestBody[]) => secrets.length > 0),
|
||||
param("workspaceId").exists().isMongoId().trim(),
|
||||
@ -133,7 +132,7 @@ router.patch(
|
||||
router.patch(
|
||||
"/workspace/:workspaceId/environment/:environmentName",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
body("secret").isObject(),
|
||||
param("workspaceId").exists().isMongoId().trim(),
|
||||
|
@ -12,10 +12,7 @@ import { body, query } from "express-validator";
|
||||
import { secretsController } from "../../controllers/v2";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
PERMISSION_READ_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS,
|
||||
@ -27,7 +24,7 @@ import { BatchSecretRequest } from "../../types/secret";
|
||||
router.post(
|
||||
"/batch",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY, AUTH_MODE_SERVICE_TOKEN]
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -109,7 +106,7 @@ router.post(
|
||||
}),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY, AUTH_MODE_SERVICE_TOKEN]
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -130,12 +127,7 @@ router.get(
|
||||
query("include_imports").optional().default(false).isBoolean(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
]
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -172,7 +164,7 @@ router.patch(
|
||||
}),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY, AUTH_MODE_SERVICE_TOKEN]
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireSecretsAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -201,7 +193,7 @@ router.delete(
|
||||
.isEmpty(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY, AUTH_MODE_SERVICE_TOKEN]
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
requireSecretsAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -1,159 +1,158 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import {
|
||||
requireAuth,
|
||||
requireOrganizationAuth,
|
||||
requireServiceAccountAuth,
|
||||
requireServiceAccountWorkspacePermissionAuth,
|
||||
requireWorkspaceAuth,
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { body, param, query } from "express-validator";
|
||||
import {
|
||||
ACCEPTED,
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
MEMBER,
|
||||
OWNER,
|
||||
} from "../../variables";
|
||||
import { serviceAccountsController } from "../../controllers/v2";
|
||||
// import {
|
||||
// requireAuth,
|
||||
// requireOrganizationAuth,
|
||||
// requireServiceAccountAuth,
|
||||
// requireServiceAccountWorkspacePermissionAuth,
|
||||
// requireWorkspaceAuth,
|
||||
// validateRequest,
|
||||
// } from "../../middleware";
|
||||
// import { body, param, query } from "express-validator";
|
||||
// import {
|
||||
// ACCEPTED,
|
||||
// ADMIN,
|
||||
// MEMBER,
|
||||
// OWNER,
|
||||
// AuthMode
|
||||
// } from "../../variables";
|
||||
// import { serviceAccountsController } from "../../controllers/v2";
|
||||
|
||||
router.get( // TODO: check
|
||||
"/me",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_SERVICE_ACCOUNT],
|
||||
}),
|
||||
serviceAccountsController.getCurrentServiceAccount
|
||||
);
|
||||
// router.get( // TODO: check
|
||||
// "/me",
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_SERVICE_ACCOUNT],
|
||||
// }),
|
||||
// serviceAccountsController.getCurrentServiceAccount
|
||||
// );
|
||||
|
||||
router.get(
|
||||
"/:serviceAccountId",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.getServiceAccountById
|
||||
);
|
||||
// router.get(
|
||||
// "/:serviceAccountId",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.getServiceAccountById
|
||||
// );
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
body("organizationId").exists().isString().trim(),
|
||||
body("name").exists().isString().trim(),
|
||||
body("publicKey").exists().isString().trim(),
|
||||
body("expiresIn").isNumeric(), // measured in ms
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireOrganizationAuth({
|
||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
locationOrganizationId: "body",
|
||||
}),
|
||||
serviceAccountsController.createServiceAccount
|
||||
);
|
||||
// router.post(
|
||||
// "/",
|
||||
// body("organizationId").exists().isString().trim(),
|
||||
// body("name").exists().isString().trim(),
|
||||
// body("publicKey").exists().isString().trim(),
|
||||
// body("expiresIn").isNumeric(), // measured in ms
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireOrganizationAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// locationOrganizationId: "body",
|
||||
// }),
|
||||
// serviceAccountsController.createServiceAccount
|
||||
// );
|
||||
|
||||
router.patch(
|
||||
"/:serviceAccountId/name",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.changeServiceAccountName
|
||||
);
|
||||
// router.patch(
|
||||
// "/:serviceAccountId/name",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.changeServiceAccountName
|
||||
// );
|
||||
|
||||
router.delete(
|
||||
"/:serviceAccountId",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.deleteServiceAccount
|
||||
);
|
||||
// router.delete(
|
||||
// "/:serviceAccountId",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.deleteServiceAccount
|
||||
// );
|
||||
|
||||
router.get(
|
||||
"/:serviceAccountId/permissions/workspace",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.getServiceAccountWorkspacePermissions
|
||||
);
|
||||
// router.get(
|
||||
// "/:serviceAccountId/permissions/workspace",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.getServiceAccountWorkspacePermissions
|
||||
// );
|
||||
|
||||
router.post(
|
||||
"/:serviceAccountId/permissions/workspace",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
body("workspaceId").exists().isString().notEmpty(),
|
||||
body("environment").exists().isString().notEmpty(),
|
||||
body("read").isBoolean().optional(),
|
||||
body("write").isBoolean().optional(),
|
||||
body("encryptedKey").exists().isString().notEmpty(),
|
||||
body("nonce").exists().isString().notEmpty(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
locationWorkspaceId: "body",
|
||||
}),
|
||||
serviceAccountsController.addServiceAccountWorkspacePermission
|
||||
);
|
||||
// router.post(
|
||||
// "/:serviceAccountId/permissions/workspace",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// body("workspaceId").exists().isString().notEmpty(),
|
||||
// body("environment").exists().isString().notEmpty(),
|
||||
// body("read").isBoolean().optional(),
|
||||
// body("write").isBoolean().optional(),
|
||||
// body("encryptedKey").exists().isString().notEmpty(),
|
||||
// body("nonce").exists().isString().notEmpty(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// requireWorkspaceAuth({
|
||||
// acceptedRoles: [ADMIN, MEMBER],
|
||||
// locationWorkspaceId: "body",
|
||||
// }),
|
||||
// serviceAccountsController.addServiceAccountWorkspacePermission
|
||||
// );
|
||||
|
||||
router.delete(
|
||||
"/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionId",
|
||||
param("serviceAccountId").exists().isString().trim(),
|
||||
param("serviceAccountWorkspacePermissionId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
requireServiceAccountWorkspacePermissionAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.deleteServiceAccountWorkspacePermission
|
||||
);
|
||||
// router.delete(
|
||||
// "/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionId",
|
||||
// param("serviceAccountId").exists().isString().trim(),
|
||||
// param("serviceAccountWorkspacePermissionId").exists().isString().trim(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// requireServiceAccountWorkspacePermissionAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.deleteServiceAccountWorkspacePermission
|
||||
// );
|
||||
|
||||
router.get(
|
||||
"/:serviceAccountId/keys",
|
||||
query("workspaceId").optional().isString(),
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT],
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED],
|
||||
}),
|
||||
serviceAccountsController.getServiceAccountKeys
|
||||
);
|
||||
// router.get(
|
||||
// "/:serviceAccountId/keys",
|
||||
// query("workspaceId").optional().isString(),
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT],
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED],
|
||||
// }),
|
||||
// serviceAccountsController.getServiceAccountKeys
|
||||
// );
|
||||
|
||||
export default router;
|
@ -9,9 +9,7 @@ import {
|
||||
import { body, param } from "express-validator";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
PERMISSION_WRITE_SECRETS
|
||||
} from "../../variables";
|
||||
@ -20,7 +18,7 @@ import { serviceTokenDataController } from "../../controllers/v2";
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_SERVICE_TOKEN]
|
||||
acceptedAuthModes: [AuthMode.SERVICE_TOKEN]
|
||||
}),
|
||||
serviceTokenDataController.getServiceTokenData
|
||||
);
|
||||
@ -28,7 +26,7 @@ router.get(
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_ACCOUNT]
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -63,7 +61,7 @@ router.post(
|
||||
router.delete(
|
||||
"/:serviceTokenDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT]
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireServiceTokenDataAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER]
|
||||
|
@ -9,14 +9,14 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/tags",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [MEMBER, ADMIN],
|
||||
@ -30,7 +30,7 @@ router.get(
|
||||
router.delete(
|
||||
"/tags/:tagId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
param("tagId").exists().trim(),
|
||||
validateRequest,
|
||||
@ -40,7 +40,7 @@ router.delete(
|
||||
router.post(
|
||||
"/:workspaceId/tags",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [MEMBER, ADMIN],
|
||||
|
@ -6,10 +6,7 @@ import {
|
||||
} from "../../middleware";
|
||||
import { body, param } from "express-validator";
|
||||
import { usersController } from "../../controllers/v2";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
} from "../../variables";
|
||||
import { AuthMode } from "../../variables";
|
||||
import {
|
||||
AuthProvider
|
||||
} from "../../models";
|
||||
@ -17,7 +14,7 @@ import {
|
||||
router.get(
|
||||
"/me",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
usersController.getMe
|
||||
);
|
||||
@ -25,7 +22,7 @@ router.get(
|
||||
router.patch(
|
||||
"/me/mfa",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
body("isMfaEnabled").exists().isBoolean(),
|
||||
validateRequest,
|
||||
@ -35,7 +32,7 @@ router.patch(
|
||||
router.patch(
|
||||
"/me/name",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
body("firstName").exists().isString(),
|
||||
body("lastName").isString(),
|
||||
@ -46,7 +43,7 @@ router.patch(
|
||||
router.patch(
|
||||
"/me/auth-provider",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
body("authProvider").exists().isString().isIn([
|
||||
AuthProvider.EMAIL,
|
||||
@ -60,7 +57,7 @@ router.patch(
|
||||
router.get(
|
||||
"/me/organizations",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
usersController.getMyOrganizations
|
||||
);
|
||||
@ -68,7 +65,7 @@ router.get(
|
||||
router.get(
|
||||
"/me/api-keys",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
usersController.getMyAPIKeys
|
||||
);
|
||||
@ -76,7 +73,7 @@ router.get(
|
||||
router.post(
|
||||
"/me/api-keys",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
body("name").exists().isString().trim(),
|
||||
body("expiresIn").isNumeric(),
|
||||
@ -87,7 +84,7 @@ router.post(
|
||||
router.delete(
|
||||
"/me/api-keys/:apiKeyDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
param("apiKeyDataId").exists().trim(),
|
||||
validateRequest,
|
||||
@ -97,7 +94,7 @@ router.delete(
|
||||
router.get(
|
||||
"/me/sessions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
usersController.getMySessions
|
||||
);
|
||||
@ -105,7 +102,7 @@ router.get(
|
||||
router.delete(
|
||||
"/me/sessions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
usersController.deleteMySessions
|
||||
);
|
||||
|
@ -9,17 +9,15 @@ import {
|
||||
} from "../../middleware";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
MEMBER,
|
||||
AuthMode,
|
||||
MEMBER
|
||||
} from "../../variables";
|
||||
import { workspaceController } from "../../controllers/v2";
|
||||
|
||||
router.post(
|
||||
"/:workspaceId/secrets",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -37,7 +35,7 @@ router.post(
|
||||
router.get(
|
||||
"/:workspaceId/secrets",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_SERVICE_TOKEN],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -53,7 +51,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/encrypted-key",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -67,7 +65,7 @@ router.get(
|
||||
router.get(
|
||||
"/:workspaceId/service-token-data",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -83,7 +81,7 @@ router.get( // new - TODO: rewire dashboard to this route
|
||||
param("workspaceId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
@ -99,7 +97,7 @@ router.patch( // TODO - rewire dashboard to this route
|
||||
body("role").exists().isString().trim().isIn([ADMIN, MEMBER]),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -118,7 +116,7 @@ router.delete( // TODO - rewire dashboard to this route
|
||||
param("membershipId").exists().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -134,7 +132,7 @@ router.delete( // TODO - rewire dashboard to this route
|
||||
router.patch(
|
||||
"/:workspaceId/auto-capitalization",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
|
@ -5,10 +5,7 @@ import { body, param, query } from "express-validator";
|
||||
import { secretsController } from "../../controllers/v3";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AuthMode,
|
||||
MEMBER,
|
||||
PERMISSION_READ_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS,
|
||||
@ -25,10 +22,9 @@ router.get(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
secretsController.getSecretsRaw
|
||||
@ -44,10 +40,9 @@ router.get(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -73,10 +68,9 @@ router.post(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -102,10 +96,9 @@ router.patch(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -130,10 +123,9 @@ router.delete(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -156,10 +148,9 @@ router.get(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -192,10 +183,9 @@ router.post(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -220,10 +210,9 @@ router.get(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -250,10 +239,9 @@ router.patch(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
@ -278,10 +266,9 @@ router.delete(
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AuthMode.JWT,
|
||||
AuthMode.API_KEY,
|
||||
AuthMode.SERVICE_TOKEN
|
||||
]
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
import { workspacesController } from "../../controllers/v3";
|
||||
import {
|
||||
ADMIN,
|
||||
AUTH_MODE_JWT,
|
||||
AuthMode
|
||||
} from "../../variables";
|
||||
import { body, param } from "express-validator";
|
||||
|
||||
@ -19,7 +19,7 @@ router.get(
|
||||
param("workspaceId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -33,7 +33,7 @@ router.get( // allow admins to get all workspace secrets (part of blind indices
|
||||
param("workspaceId").exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
@ -65,7 +65,7 @@ router.post( // allow admins to name all workspace secrets (part of blind indice
|
||||
.withMessage("secretId must be a string"),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
acceptedAuthModes: [AuthMode.JWT],
|
||||
}),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN],
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { nanoid } from "nanoid";
|
||||
import { Types } from "mongoose";
|
||||
import Folder, { TFolderSchema } from "../models/folder";
|
||||
import path from "path";
|
||||
|
||||
type TAppendFolderDTO = {
|
||||
folderName: string;
|
||||
@ -58,7 +59,7 @@ const appendChild = (folders: TFolderSchema, folderName: string) => {
|
||||
id,
|
||||
name: folderName,
|
||||
children: [],
|
||||
version: 1,
|
||||
version: 1
|
||||
});
|
||||
return { id, name: folderName };
|
||||
};
|
||||
@ -108,10 +109,7 @@ export const deleteFolderById = (folders: TFolderSchema, folderId: string) => {
|
||||
};
|
||||
|
||||
// bfs but return parent of the folderID
|
||||
export const getParentFromFolderId = (
|
||||
folders: TFolderSchema,
|
||||
folderId: string
|
||||
) => {
|
||||
export const getParentFromFolderId = (folders: TFolderSchema, folderId: string) => {
|
||||
const queue = [folders];
|
||||
while (queue.length) {
|
||||
const folder = queue.pop() as TFolderSchema;
|
||||
@ -140,10 +138,7 @@ export const getAllFolderIds = (folders: TFolderSchema) => {
|
||||
// We then record the number of childs of each root node
|
||||
// When we reach leaf node or when all childs of a root node are visited
|
||||
// We remove it from path recorded by using the total child record
|
||||
export const searchByFolderIdWithDir = (
|
||||
folders: TFolderSchema,
|
||||
folderId: string
|
||||
) => {
|
||||
export const searchByFolderIdWithDir = (folders: TFolderSchema, folderId: string) => {
|
||||
const stack = [folders];
|
||||
const dir: Array<{ id: string; name: string }> = [];
|
||||
const hits: Record<string, number> = {};
|
||||
@ -172,6 +167,20 @@ export const searchByFolderIdWithDir = (
|
||||
return;
|
||||
};
|
||||
|
||||
// used for get folder path from id
|
||||
export const getFolderWithPathFromId = (folders: TFolderSchema, parentFolderId: string) => {
|
||||
const search = searchByFolderIdWithDir(folders, parentFolderId);
|
||||
if (!search) {
|
||||
throw { message: "Folder permission denied" };
|
||||
}
|
||||
const { folder, dir } = search;
|
||||
const folderPath = path.join(
|
||||
"/",
|
||||
...dir.filter(({ name }) => name !== "root").map(({ name }) => name)
|
||||
);
|
||||
return { folder, folderPath, dir };
|
||||
};
|
||||
|
||||
// to get folder of a path given
|
||||
// Like /frontend/folder#1
|
||||
export const getFolderByPath = (folders: TFolderSchema, searchPath: string) => {
|
||||
@ -201,7 +210,7 @@ export const getFolderIdFromServiceToken = async (
|
||||
) => {
|
||||
const folders = await Folder.findOne({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
environment
|
||||
});
|
||||
|
||||
if (!folders) {
|
||||
|
@ -7,7 +7,6 @@ import EventService from "./EventService";
|
||||
import IntegrationService from "./IntegrationService";
|
||||
import TokenService from "./TokenService";
|
||||
import SecretService from "./SecretService";
|
||||
import GithubSecretScanningService from "./GithubSecretScanningService"
|
||||
|
||||
export {
|
||||
TelemetryService,
|
||||
@ -18,5 +17,4 @@ export {
|
||||
IntegrationService,
|
||||
TokenService,
|
||||
SecretService,
|
||||
GithubSecretScanningService
|
||||
}
|
||||
|
4
backend/src/types/express/index.d.ts
vendored
4
backend/src/types/express/index.d.ts
vendored
@ -1,8 +1,6 @@
|
||||
import { Types } from "mongoose";
|
||||
|
||||
|
||||
import {
|
||||
AuthData,
|
||||
AuthData
|
||||
} from "../../interfaces/middleware";
|
||||
|
||||
declare module "express" {
|
||||
|
1
backend/src/types/secret/index.d.ts
vendored
1
backend/src/types/secret/index.d.ts
vendored
@ -30,6 +30,7 @@ export interface BatchSecretRequest {
|
||||
export interface BatchSecret {
|
||||
_id: string;
|
||||
type: "shared" | "personal";
|
||||
secretName: string;
|
||||
secretBlindIndex: string;
|
||||
secretKeyCiphertext: string;
|
||||
secretKeyIV: string;
|
||||
|
@ -1,15 +1,15 @@
|
||||
const CLI_USER_AGENT_NAME = "cli"
|
||||
const K8_OPERATOR_AGENT_NAME = "k8-operator"
|
||||
export const getChannelFromUserAgent = function (userAgent: string | undefined) {
|
||||
import { UserAgentType } from "../ee/models"
|
||||
|
||||
export const getUserAgentType = function (userAgent: string | undefined) {
|
||||
if (userAgent == undefined) {
|
||||
return "other"
|
||||
} else if (userAgent == CLI_USER_AGENT_NAME) {
|
||||
return "cli"
|
||||
} else if (userAgent == K8_OPERATOR_AGENT_NAME) {
|
||||
return "k8-operator"
|
||||
return UserAgentType.OTHER;
|
||||
} else if (userAgent == UserAgentType.CLI) {
|
||||
return UserAgentType.CLI;
|
||||
} else if (userAgent == UserAgentType.K8_OPERATOR) {
|
||||
return UserAgentType.K8_OPERATOR;
|
||||
} else if (userAgent.toLowerCase().includes("mozilla")) {
|
||||
return "web"
|
||||
return UserAgentType.WEB;
|
||||
} else {
|
||||
return "other"
|
||||
return UserAgentType.OTHER;
|
||||
}
|
||||
}
|
@ -1,25 +1,15 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
Bot,
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import {
|
||||
BotNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for bot with id [botId] based
|
||||
@ -34,65 +24,24 @@ export const validateClientForBot = async ({
|
||||
botId,
|
||||
acceptedRoles,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
botId: Types.ObjectId;
|
||||
acceptedRoles: Array<"admin" | "member">;
|
||||
}) => {
|
||||
const bot = await Bot.findById(botId);
|
||||
|
||||
if (!bot) throw BotNotFoundError();
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_JWT &&
|
||||
authData.authPayload instanceof User
|
||||
) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: bot.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return bot;
|
||||
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId: bot.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
return bot;
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for bot",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
|
||||
authData.authPayload instanceof ServiceAccount
|
||||
) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: bot.workspace,
|
||||
});
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
|
||||
authData.authPayload instanceof ServiceTokenData
|
||||
) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for bot",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_API_KEY &&
|
||||
authData.authPayload instanceof User
|
||||
) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: bot.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
throw BotNotFoundError({
|
||||
message: "Failed client authorization for bot",
|
||||
});
|
||||
};
|
@ -1,15 +1,9 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
Integration,
|
||||
IntegrationAuth,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import { IntegrationService } from "../services";
|
||||
import {
|
||||
@ -17,12 +11,8 @@ import {
|
||||
IntegrationNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for integration with id [integrationId] based
|
||||
@ -39,10 +29,7 @@ export const validateClientForIntegration = async ({
|
||||
integrationId,
|
||||
acceptedRoles,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
integrationId: Types.ObjectId;
|
||||
acceptedRoles: Array<"admin" | "member">;
|
||||
}) => {
|
||||
@ -61,43 +48,19 @@ export const validateClientForIntegration = async ({
|
||||
const accessToken = (await IntegrationService.getIntegrationAuthAccess({
|
||||
integrationAuthId: integrationAuth._id,
|
||||
})).accessToken;
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: integration.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return ({ integration, accessToken });
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: integration.workspace,
|
||||
});
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId: integration.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return ({ integration, accessToken });
|
||||
return ({ integration, accessToken });
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for integration",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for integration",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: integration.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return ({ integration, accessToken });
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for integration",
|
||||
});
|
||||
}
|
@ -1,27 +1,17 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
IWorkspace,
|
||||
IntegrationAuth,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import {
|
||||
IntegrationAuthNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import { IntegrationService } from "../services";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for integration authorization with id [integrationAuthId] based
|
||||
@ -38,10 +28,7 @@ import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
acceptedRoles,
|
||||
attachAccessToken,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
integrationAuthId: Types.ObjectId;
|
||||
acceptedRoles: Array<"admin" | "member">;
|
||||
attachAccessToken?: boolean;
|
||||
@ -66,44 +53,20 @@ import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
accessId = access.accessId;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: integrationAuth.workspace._id,
|
||||
acceptedRoles,
|
||||
});
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId: integrationAuth.workspace._id,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return ({ integrationAuth, accessToken, accessId });
|
||||
return ({ integrationAuth, accessToken, accessId });
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for integration authorization",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: integrationAuth.workspace._id,
|
||||
});
|
||||
|
||||
return ({ integrationAuth, accessToken, accessId });
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for integration authorization",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: integrationAuth.workspace._id,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return ({ integrationAuth, accessToken, accessId });
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for integration authorization",
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
|
@ -1,26 +1,16 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
Membership,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import { validateServiceTokenDataClientForWorkspace } from "./serviceTokenData";
|
||||
import {
|
||||
MembershipNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for membership with id [membershipId] based
|
||||
@ -36,10 +26,7 @@ export const validateClientForMembership = async ({
|
||||
membershipId,
|
||||
acceptedRoles,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
membershipId: Types.ObjectId;
|
||||
acceptedRoles: Array<"admin" | "member">;
|
||||
}) => {
|
||||
@ -49,46 +36,22 @@ export const validateClientForMembership = async ({
|
||||
if (!membership) throw MembershipNotFoundError({
|
||||
message: "Failed to find membership",
|
||||
});
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: membership.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: membership.workspace,
|
||||
});
|
||||
|
||||
return membership;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId: membership.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return membership;
|
||||
case ActorType.SERVICE:
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload as IServiceTokenData,
|
||||
workspaceId: new Types.ObjectId(membership.workspace),
|
||||
});
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload,
|
||||
workspaceId: new Types.ObjectId(membership.workspace),
|
||||
});
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
if (authData.authMode == AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: membership.workspace,
|
||||
acceptedRoles,
|
||||
});
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for membership",
|
||||
});
|
||||
}
|
@ -1,12 +1,6 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
MembershipOrg,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import {
|
||||
validateMembershipOrg,
|
||||
@ -15,12 +9,8 @@ import {
|
||||
MembershipOrgNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for organization membership with id [membershipOrgId] based
|
||||
@ -37,10 +27,7 @@ export const validateClientForMembershipOrg = async ({
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
membershipOrgId: Types.ObjectId;
|
||||
acceptedRoles: Array<"owner" | "admin" | "member">;
|
||||
acceptedStatuses: Array<"invited" | "accepted">;
|
||||
@ -50,44 +37,20 @@ export const validateClientForMembershipOrg = async ({
|
||||
if (!membershipOrg) throw MembershipOrgNotFoundError({
|
||||
message: "Failed to find organization membership ",
|
||||
});
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateMembershipOrg({
|
||||
userId: authData.authPayload._id,
|
||||
organizationId: membershipOrg.organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
return membershipOrg;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
if (!authData.authPayload.organization.equals(membershipOrg.organization)) throw UnauthorizedRequestError({
|
||||
message: "Failed service account client authorization for organization membership",
|
||||
});
|
||||
|
||||
return membershipOrg;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service account client authorization for organization membership",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateMembershipOrg({
|
||||
userId: authData.authPayload._id,
|
||||
organizationId: membershipOrg.organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
return membershipOrg;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateMembershipOrg({
|
||||
userId: authData.authPayload._id,
|
||||
organizationId: membershipOrg.organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
return membershipOrg;
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service account client authorization for organization membership",
|
||||
});
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for organization membership",
|
||||
});
|
||||
}
|
@ -1,25 +1,15 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
Organization,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import {
|
||||
OrganizationNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import { validateUserClientForOrganization } from "./user";
|
||||
import { validateServiceAccountClientForOrganization } from "./serviceAccount";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate accepted clients for organization with id [organizationId]
|
||||
@ -33,10 +23,7 @@ export const validateClientForOrganization = async ({
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
organizationId: Types.ObjectId;
|
||||
acceptedRoles: Array<"owner" | "admin" | "member">;
|
||||
acceptedStatuses: Array<"invited" | "accepted">;
|
||||
@ -48,57 +35,21 @@ export const validateClientForOrganization = async ({
|
||||
message: "Failed to find organization",
|
||||
});
|
||||
}
|
||||
|
||||
let membershipOrg;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
membershipOrg = await validateUserClientForOrganization({
|
||||
user: authData.authPayload as IUser,
|
||||
organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_JWT &&
|
||||
authData.authPayload instanceof User
|
||||
) {
|
||||
const membershipOrg = await validateUserClientForOrganization({
|
||||
user: authData.authPayload,
|
||||
organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
return { organization, membershipOrg };
|
||||
return { organization, membershipOrg };
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for organization",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
|
||||
authData.authPayload instanceof ServiceAccount
|
||||
) {
|
||||
await validateServiceAccountClientForOrganization({
|
||||
serviceAccount: authData.authPayload,
|
||||
organization,
|
||||
});
|
||||
|
||||
return { organization };
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
|
||||
authData.authPayload instanceof ServiceTokenData
|
||||
) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for organization",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_API_KEY &&
|
||||
authData.authPayload instanceof User
|
||||
) {
|
||||
const membershipOrg = await validateUserClientForOrganization({
|
||||
user: authData.authPayload,
|
||||
organization,
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
});
|
||||
|
||||
return { organization, membershipOrg };
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for organization",
|
||||
});
|
||||
};
|
@ -1,26 +1,18 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
ISecret,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
Secret,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import { validateServiceAccountClientForSecrets, validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { validateUserClientForSecret, validateUserClientForSecrets } from "./user";
|
||||
import { validateServiceTokenDataClientForSecrets, validateServiceTokenDataClientForWorkspace } from "./serviceTokenData";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import {
|
||||
BadRequestError,
|
||||
SecretNotFoundError,
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for secrets with id [secretId] based
|
||||
@ -47,53 +39,26 @@ export const validateClientForSecret = async ({
|
||||
if (!secret) throw SecretNotFoundError({
|
||||
message: "Failed to find secret",
|
||||
});
|
||||
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForSecret({
|
||||
user: authData.authPayload as IUser,
|
||||
secret,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForSecret({
|
||||
user: authData.authPayload,
|
||||
secret,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: secret.workspace,
|
||||
environment: secret.environment,
|
||||
requiredPermissions,
|
||||
});
|
||||
return secret;
|
||||
case ActorType.SERVICE:
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload as IServiceTokenData,
|
||||
workspaceId: secret.workspace,
|
||||
environment: secret.environment,
|
||||
});
|
||||
|
||||
return secret;
|
||||
return secret;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload,
|
||||
workspaceId: secret.workspace,
|
||||
environment: secret.environment,
|
||||
});
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForSecret({
|
||||
user: authData.authPayload,
|
||||
secret,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for secret",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,48 +92,23 @@ export const validateClientForSecrets = async ({
|
||||
if (secrets.length != secretIds.length) {
|
||||
throw BadRequestError({ message: "Failed to validate non-existent secrets" })
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForSecrets({
|
||||
user: authData.authPayload,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForSecrets({
|
||||
serviceAccount: authData.authPayload,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForSecrets({
|
||||
user: authData.authPayload as IUser,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
case ActorType.SERVICE:
|
||||
await validateServiceTokenDataClientForSecrets({
|
||||
serviceTokenData: authData.authPayload as IServiceTokenData,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
await validateServiceTokenDataClientForSecrets({
|
||||
serviceTokenData: authData.authPayload,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForSecrets({
|
||||
user: authData.authPayload,
|
||||
secrets,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return secrets;
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for secrets resource",
|
||||
});
|
||||
}
|
@ -4,12 +4,9 @@ import {
|
||||
IOrganization,
|
||||
ISecret,
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
ServiceAccount,
|
||||
ServiceAccountWorkspacePermission,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
} from "../models";
|
||||
import { validateUserClientForServiceAccount } from "./user";
|
||||
import {
|
||||
@ -18,23 +15,18 @@ import {
|
||||
UnauthorizedRequestError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
PERMISSION_READ_SECRETS,
|
||||
PERMISSION_WRITE_SECRETS,
|
||||
} from "../variables";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { ActorType } from "../ee/models";
|
||||
|
||||
export const validateClientForServiceAccount = async ({
|
||||
authData,
|
||||
serviceAccountId,
|
||||
requiredPermissions,
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
},
|
||||
authData: AuthData;
|
||||
serviceAccountId: Types.ObjectId;
|
||||
requiredPermissions?: string[];
|
||||
}) => {
|
||||
@ -46,45 +38,20 @@ export const validateClientForServiceAccount = async ({
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForServiceAccount({
|
||||
user: authData.authPayload,
|
||||
serviceAccount,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return serviceAccount;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForServiceAccount({
|
||||
user: authData.authPayload as IUser,
|
||||
serviceAccount,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return serviceAccount;
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for service account resource",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForServiceAccount({
|
||||
serviceAccount: authData.authPayload,
|
||||
targetServiceAccount: serviceAccount,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return serviceAccount;
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for service account resource",
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForServiceAccount({
|
||||
user: authData.authPayload,
|
||||
serviceAccount,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return serviceAccount;
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for service account resource",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,22 +1,14 @@
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
ISecret,
|
||||
IServiceAccount,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User
|
||||
} from "../models";
|
||||
import { ServiceTokenDataNotFoundError, UnauthorizedRequestError } from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN
|
||||
} from "../variables";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { ActorType } from "../ee/models";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
|
||||
/**
|
||||
* Validate authenticated clients for service token with id [serviceTokenId] based
|
||||
@ -31,10 +23,7 @@ export const validateClientForServiceTokenData = async ({
|
||||
serviceTokenDataId,
|
||||
acceptedRoles
|
||||
}: {
|
||||
authData: {
|
||||
authMode: string;
|
||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||
};
|
||||
authData: AuthData;
|
||||
serviceTokenDataId: Types.ObjectId;
|
||||
acceptedRoles: Array<"admin" | "member">;
|
||||
}) => {
|
||||
@ -42,55 +31,24 @@ export const validateClientForServiceTokenData = async ({
|
||||
.select("+encryptedKey +iv +tag")
|
||||
.populate<{ user: IUser }>("user");
|
||||
|
||||
if (!serviceTokenData)
|
||||
throw ServiceTokenDataNotFoundError({
|
||||
message: "Failed to find service token data"
|
||||
});
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: serviceTokenData.workspace,
|
||||
acceptedRoles
|
||||
});
|
||||
|
||||
return serviceTokenData;
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
|
||||
authData.authPayload instanceof ServiceAccount
|
||||
) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId: serviceTokenData.workspace
|
||||
});
|
||||
|
||||
return serviceTokenData;
|
||||
}
|
||||
|
||||
if (
|
||||
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
|
||||
authData.authPayload instanceof ServiceTokenData
|
||||
) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for service token data"
|
||||
});
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId: serviceTokenData.workspace,
|
||||
acceptedRoles
|
||||
});
|
||||
|
||||
return serviceTokenData;
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for service token data"
|
||||
if (!serviceTokenData) throw ServiceTokenDataNotFoundError({
|
||||
message: "Failed to find service token data"
|
||||
});
|
||||
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId: serviceTokenData.workspace,
|
||||
acceptedRoles
|
||||
});
|
||||
|
||||
return serviceTokenData;
|
||||
case ActorType.SERVICE:
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed service token authorization for service token data"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,16 +1,15 @@
|
||||
import net from "net";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
SecretBlindIndexData,
|
||||
ServiceAccount,
|
||||
ServiceTokenData,
|
||||
User,
|
||||
IServiceTokenData,
|
||||
IUser,
|
||||
SecretBlindIndexData,
|
||||
Workspace,
|
||||
} from "../models";
|
||||
import {
|
||||
ActorType,
|
||||
TrustedIP
|
||||
} from "../ee/models";
|
||||
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
|
||||
import { validateUserClientForWorkspace } from "./user";
|
||||
import { validateServiceTokenDataClientForWorkspace } from "./serviceTokenData";
|
||||
import {
|
||||
@ -18,12 +17,6 @@ import {
|
||||
UnauthorizedRequestError,
|
||||
WorkspaceNotFoundError,
|
||||
} from "../utils/errors";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN,
|
||||
} from "../variables";
|
||||
import { BotService } from "../services";
|
||||
import { AuthData } from "../interfaces/middleware";
|
||||
import { extractIPDetails } from "../utils/ip";
|
||||
@ -85,89 +78,60 @@ export const validateClientForWorkspace = async ({
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let membership;
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER:
|
||||
membership = await validateUserClientForWorkspace({
|
||||
user: authData.authPayload as IUser,
|
||||
workspaceId,
|
||||
environment,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return ({ membership, workspace });
|
||||
case ActorType.SERVICE:
|
||||
if (checkIPAllowlist) {
|
||||
const trustedIps = await TrustedIP.find({
|
||||
workspace: workspaceId
|
||||
});
|
||||
|
||||
if (trustedIps.length > 0) {
|
||||
// case: check the IP address of the inbound request against trusted IPs
|
||||
|
||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||
const membership = await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId,
|
||||
environment,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
const blockList = new net.BlockList();
|
||||
|
||||
return ({ membership, workspace });
|
||||
}
|
||||
for (const trustedIp of trustedIps) {
|
||||
if (trustedIp.prefix !== undefined) {
|
||||
blockList.addSubnet(
|
||||
trustedIp.ipAddress,
|
||||
trustedIp.prefix,
|
||||
trustedIp.type
|
||||
);
|
||||
} else {
|
||||
blockList.addAddress(
|
||||
trustedIp.ipAddress,
|
||||
trustedIp.type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const { type } = extractIPDetails(authData.ipAddress);
|
||||
const check = blockList.check(authData.ipAddress, type);
|
||||
|
||||
if (!check) throw UnauthorizedRequestError({
|
||||
message: "Failed workspace authorization"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||
await validateServiceAccountClientForWorkspace({
|
||||
serviceAccount: authData.authPayload,
|
||||
workspaceId,
|
||||
environment,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||
if (checkIPAllowlist) {
|
||||
const trustedIps = await TrustedIP.find({
|
||||
workspace: workspaceId
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload as IServiceTokenData,
|
||||
workspaceId,
|
||||
environment,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
if (trustedIps.length > 0) {
|
||||
// case: check the IP address of the inbound request against trusted IPs
|
||||
|
||||
const blockList = new net.BlockList();
|
||||
|
||||
for (const trustedIp of trustedIps) {
|
||||
if (trustedIp.prefix !== undefined) {
|
||||
blockList.addSubnet(
|
||||
trustedIp.ipAddress,
|
||||
trustedIp.prefix,
|
||||
trustedIp.type
|
||||
);
|
||||
} else {
|
||||
blockList.addAddress(
|
||||
trustedIp.ipAddress,
|
||||
trustedIp.type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const { type } = extractIPDetails(authData.authIP);
|
||||
const check = blockList.check(authData.authIP, type);
|
||||
|
||||
if (!check) throw UnauthorizedRequestError({
|
||||
message: "Failed workspace authorization"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await validateServiceTokenDataClientForWorkspace({
|
||||
serviceTokenData: authData.authPayload,
|
||||
workspaceId,
|
||||
environment,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return {};
|
||||
return {};
|
||||
}
|
||||
|
||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||
const membership = await validateUserClientForWorkspace({
|
||||
user: authData.authPayload,
|
||||
workspaceId,
|
||||
environment,
|
||||
acceptedRoles,
|
||||
requiredPermissions,
|
||||
});
|
||||
|
||||
return ({ membership, workspace });
|
||||
}
|
||||
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed client authorization for workspace",
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export const AUTH_MODE_JWT = "jwt";
|
||||
export const AUTH_MODE_SERVICE_ACCOUNT = "serviceAccount";
|
||||
export const AUTH_MODE_SERVICE_TOKEN = "serviceToken";
|
||||
export const AUTH_MODE_API_KEY = "apiKey"; // TODO: deprecate
|
||||
export enum AuthMode {
|
||||
JWT = "jwt",
|
||||
SERVICE_TOKEN = "serviceToken",
|
||||
API_KEY = "apiKey"
|
||||
}
|
@ -1,29 +1,29 @@
|
||||
import { describe, expect, test } from "@jest/globals";
|
||||
import { getChannelFromUserAgent } from "../../../src/utils/posthog";
|
||||
import { getUserAgentType } from "../../../src/utils/posthog";
|
||||
|
||||
describe("posthog getChannelFromUserAgent", () => {
|
||||
test("should return 'web' when userAgent includes 'mozilla'", () => {
|
||||
const userAgent =
|
||||
"Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.115 Mobile Safari/537.36";
|
||||
const channel = getChannelFromUserAgent(userAgent);
|
||||
const channel = getUserAgentType(userAgent);
|
||||
expect(channel).toBe("web");
|
||||
});
|
||||
|
||||
test("should return 'cli'", () => {
|
||||
const userAgent = "cli";
|
||||
const channel = getChannelFromUserAgent(userAgent);
|
||||
const channel = getUserAgentType(userAgent);
|
||||
expect(channel).toBe("cli");
|
||||
});
|
||||
|
||||
test("should return 'k8-operator'", () => {
|
||||
const userAgent = "k8-operator";
|
||||
const channel = getChannelFromUserAgent(userAgent);
|
||||
const channel = getUserAgentType(userAgent);
|
||||
expect(channel).toBe("k8-operator");
|
||||
});
|
||||
|
||||
test("should return undefined if no userAgent", () => {
|
||||
const userAgent = undefined;
|
||||
const channel = getChannelFromUserAgent(userAgent);
|
||||
const channel = getUserAgentType(userAgent);
|
||||
expect(channel).toBe("other");
|
||||
});
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user