Fix merge conflicts

This commit is contained in:
Tuan Dang
2023-09-29 11:42:47 +01:00
145 changed files with 8601 additions and 5093 deletions
@@ -29,7 +29,7 @@ import {
import { EESecretService } from "../../services";
import { getLatestSecretVersionIds } from "../../helpers/secretVersion";
// import Folder, { TFolderSchema } from "../../../models/folder";
import { searchByFolderId } from "../../../services/FolderService";
import { getFolderByPath, searchByFolderId } from "../../../services/FolderService";
import { EEAuditLogService, EELicenseService } from "../../services";
import { extractIPDetails, isValidIpOrCidr } from "../../../utils/ip";
import { validateRequest } from "../../../helpers/validation";
@@ -106,7 +106,7 @@ export const getWorkspaceSecretSnapshots = async (req: Request, res: Response) =
*/
const {
params: { workspaceId },
query: { environment, folderId, offset, limit }
query: { environment, directory, offset, limit }
} = await validateRequest(GetWorkspaceSecretSnapshotsV1, req);
const { permission } = await getUserProjectPermissions(req.user._id, workspaceId);
@@ -115,10 +115,20 @@ export const getWorkspaceSecretSnapshots = async (req: Request, res: Response) =
ProjectPermissionSub.SecretRollback
);
let folderId = "root";
const folders = await Folder.findOne({ workspace: workspaceId, environment });
if (!folders && directory !== "/") throw BadRequestError({ message: "Folder not found" });
if (folders) {
const folder = getFolderByPath(folders?.nodes, directory);
if (!folder) throw BadRequestError({ message: "Invalid folder id" });
folderId = folder.id;
}
const secretSnapshots = await SecretSnapshot.find({
workspace: workspaceId,
environment,
folderId: folderId || "root"
folderId
})
.sort({ createdAt: -1 })
.skip(offset)
@@ -137,7 +147,7 @@ export const getWorkspaceSecretSnapshots = async (req: Request, res: Response) =
export const getWorkspaceSecretSnapshotsCount = async (req: Request, res: Response) => {
const {
params: { workspaceId },
query: { environment, folderId }
query: { environment, directory }
} = await validateRequest(GetWorkspaceSecretSnapshotsCountV1, req);
const { permission } = await getUserProjectPermissions(req.user._id, workspaceId);
@@ -146,10 +156,20 @@ export const getWorkspaceSecretSnapshotsCount = async (req: Request, res: Respon
ProjectPermissionSub.SecretRollback
);
let folderId = "root";
const folders = await Folder.findOne({ workspace: workspaceId, environment });
if (!folders && directory !== "/") throw BadRequestError({ message: "Folder not found" });
if (folders) {
const folder = getFolderByPath(folders?.nodes, directory);
if (!folder) throw BadRequestError({ message: "Invalid folder id" });
folderId = folder.id;
}
const count = await SecretSnapshot.countDocuments({
workspace: workspaceId,
environment,
folderId: folderId || "root"
folderId
});
return res.status(200).send({
@@ -217,7 +237,7 @@ export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Respons
const {
params: { workspaceId },
body: { folderId, environment, version }
body: { directory, environment, version }
} = await validateRequest(RollbackWorkspaceSecretSnapshotV1, req);
const { permission } = await getUserProjectPermissions(req.user._id, workspaceId);
@@ -226,6 +246,16 @@ export const rollbackWorkspaceSecretSnapshot = async (req: Request, res: Respons
ProjectPermissionSub.SecretRollback
);
let folderId = "root";
const folders = await Folder.findOne({ workspace: workspaceId, environment });
if (!folders && directory !== "/") throw BadRequestError({ message: "Folder not found" });
if (folders) {
const folder = getFolderByPath(folders?.nodes, directory);
if (!folder) throw BadRequestError({ message: "Invalid folder id" });
folderId = folder.id;
}
// validate secret snapshot
const secretSnapshot = await SecretSnapshot.findOne({
workspace: workspaceId,
+7 -4
View File
@@ -5,10 +5,10 @@ export enum ActorType {
}
export enum UserAgentType {
WEB = "web",
CLI = "cli",
K8_OPERATOR = "k8-operator",
OTHER = "other"
WEB = "web",
CLI = "cli",
K8_OPERATOR = "k8-operator",
OTHER = "other"
}
export enum EventType {
@@ -16,8 +16,11 @@ export enum EventType {
GET_SECRET = "get-secret",
REVEAL_SECRET = "reveal-secret",
CREATE_SECRET = "create-secret",
CREATE_SECRETS = "create-secrets",
UPDATE_SECRET = "update-secret",
UPDATE_SECRETS = "update-secrets",
DELETE_SECRET = "delete-secret",
DELETE_SECRETS = "delete-secrets",
GET_WORKSPACE_KEY = "get-workspace-key",
AUTHORIZE_INTEGRATION = "authorize-integration",
UNAUTHORIZE_INTEGRATION = "unauthorize-integration",
+274 -244
View File
@@ -7,23 +7,23 @@ import {
} from "../../../models/serviceTokenDataV3";
interface UserActorMetadata {
userId: string;
email: string;
userId: string;
email: string;
}
interface ServiceActorMetadata {
serviceId: string;
name: string;
serviceId: string;
name: string;
}
export interface UserActor {
type: ActorType.USER;
metadata: UserActorMetadata;
type: ActorType.USER;
metadata: UserActorMetadata;
}
export interface ServiceActor {
type: ActorType.SERVICE;
metadata: ServiceActorMetadata;
type: ActorType.SERVICE;
metadata: ServiceActorMetadata;
}
export interface ServiceActorV3 {
@@ -37,164 +37,191 @@ export type Actor =
| ServiceActorV3;
interface GetSecretsEvent {
type: EventType.GET_SECRETS;
metadata: {
environment: string;
secretPath: string;
numberOfSecrets: number;
};
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;
};
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;
}
type: EventType.CREATE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
};
}
interface CreateSecretBatchEvent {
type: EventType.CREATE_SECRETS;
metadata: {
environment: string;
secretPath: string;
secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>;
};
}
interface UpdateSecretEvent {
type: EventType.UPDATE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
}
type: EventType.UPDATE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
};
}
interface UpdateSecretBatchEvent {
type: EventType.UPDATE_SECRETS;
metadata: {
environment: string;
secretPath: string;
secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>;
};
}
interface DeleteSecretEvent {
type: EventType.DELETE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
}
type: EventType.DELETE_SECRET;
metadata: {
environment: string;
secretPath: string;
secretId: string;
secretKey: string;
secretVersion: number;
};
}
interface DeleteSecretBatchEvent {
type: EventType.DELETE_SECRETS;
metadata: {
environment: string;
secretPath: string;
secrets: Array<{ secretId: string; secretKey: string; secretVersion: number }>;
};
}
interface GetWorkspaceKeyEvent {
type: EventType.GET_WORKSPACE_KEY,
metadata: {
keyId: string;
}
type: EventType.GET_WORKSPACE_KEY;
metadata: {
keyId: string;
};
}
interface AuthorizeIntegrationEvent {
type: EventType.AUTHORIZE_INTEGRATION;
metadata: {
integration: string;
}
type: EventType.AUTHORIZE_INTEGRATION;
metadata: {
integration: string;
};
}
interface UnauthorizeIntegrationEvent {
type: EventType.UNAUTHORIZE_INTEGRATION;
metadata: {
integration: string;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}>;
}
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;
}>;
}
type: EventType.DELETE_SERVICE_TOKEN;
metadata: {
name: string;
scopes: Array<{
environment: string;
secretPath: string;
}>;
};
}
interface CreateServiceTokenV3Event {
@@ -228,171 +255,171 @@ interface DeleteServiceTokenV3Event {
}
interface CreateEnvironmentEvent {
type: EventType.CREATE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
}
type: EventType.CREATE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
};
}
interface UpdateEnvironmentEvent {
type: EventType.UPDATE_ENVIRONMENT;
metadata: {
oldName: string;
newName: string;
oldSlug: string;
newSlug: string;
}
type: EventType.UPDATE_ENVIRONMENT;
metadata: {
oldName: string;
newName: string;
oldSlug: string;
newSlug: string;
};
}
interface DeleteEnvironmentEvent {
type: EventType.DELETE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
}
type: EventType.DELETE_ENVIRONMENT;
metadata: {
name: string;
slug: string;
};
}
interface AddWorkspaceMemberEvent {
type: EventType.ADD_WORKSPACE_MEMBER;
metadata: {
userId: string;
email: string;
}
type: EventType.ADD_WORKSPACE_MEMBER;
metadata: {
userId: string;
email: string;
};
}
interface RemoveWorkspaceMemberEvent {
type: EventType.REMOVE_WORKSPACE_MEMBER;
metadata: {
userId: string;
email: string;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}[]
}
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;
}
type: EventType.DELETE_SECRET_IMPORT;
metadata: {
secretImportId: string;
folderId: string;
importFromEnvironment: string;
importFromSecretPath: string;
importToEnvironment: string;
importToSecretPath: string;
};
}
interface UpdateUserRole {
type: EventType.UPDATE_USER_WORKSPACE_ROLE,
metadata: {
userId: string;
email: string;
oldRole: string;
newRole: string;
}
type: EventType.UPDATE_USER_WORKSPACE_ROLE;
metadata: {
userId: string;
email: string;
oldRole: string;
newRole: string;
};
}
interface UpdateUserDeniedPermissions {
@@ -411,8 +438,11 @@ export type Event =
| GetSecretsEvent
| GetSecretEvent
| CreateSecretEvent
| CreateSecretBatchEvent
| UpdateSecretEvent
| UpdateSecretBatchEvent
| DeleteSecretEvent
| DeleteSecretBatchEvent
| GetWorkspaceKeyEvent
| AuthorizeIntegrationEvent
| UnauthorizeIntegrationEvent
+26 -24
View File
@@ -4,7 +4,7 @@ import {
ENCODING_SCHEME_BASE64,
ENCODING_SCHEME_UTF8,
SECRET_PERSONAL,
SECRET_SHARED,
SECRET_SHARED
} from "../../variables";
export interface ISecretVersion {
@@ -23,6 +23,7 @@ export interface ISecretVersion {
secretValueCiphertext: string;
secretValueIV: string;
secretValueTag: string;
skipMultilineEncoding?: boolean;
algorithm: "aes-256-gcm";
keyEncoding: "utf8" | "base64";
createdAt: string;
@@ -36,95 +37,96 @@ const secretVersionSchema = new Schema<ISecretVersion>(
// could be deleted
type: Schema.Types.ObjectId,
ref: "Secret",
required: true,
required: true
},
version: {
type: Number,
default: 1,
required: true,
required: true
},
workspace: {
type: Schema.Types.ObjectId,
ref: "Workspace",
required: true,
required: true
},
type: {
type: String,
enum: [SECRET_SHARED, SECRET_PERSONAL],
required: true,
required: true
},
user: {
// user associated with the personal secret
type: Schema.Types.ObjectId,
ref: "User",
ref: "User"
},
environment: {
type: String,
required: true,
required: true
},
isDeleted: {
// consider removing field
type: Boolean,
default: false,
required: true,
required: true
},
secretBlindIndex: {
type: String,
select: false,
select: false
},
secretKeyCiphertext: {
type: String,
required: true,
required: true
},
secretKeyIV: {
type: String, // symmetric
required: true,
required: true
},
secretKeyTag: {
type: String, // symmetric
required: true,
required: true
},
secretValueCiphertext: {
type: String,
required: true,
required: true
},
secretValueIV: {
type: String, // symmetric
required: true,
required: true
},
secretValueTag: {
type: String, // symmetric
required: true,
required: true
},
skipMultilineEncoding: {
type: Boolean,
required: false
},
algorithm: {
// the encryption algorithm used
type: String,
enum: [ALGORITHM_AES_256_GCM],
required: true,
default: ALGORITHM_AES_256_GCM,
default: ALGORITHM_AES_256_GCM
},
keyEncoding: {
type: String,
enum: [ENCODING_SCHEME_UTF8, ENCODING_SCHEME_BASE64],
required: true,
default: ENCODING_SCHEME_UTF8,
default: ENCODING_SCHEME_UTF8
},
folder: {
type: String,
required: true,
required: true
},
tags: {
ref: "Tag",
type: [Schema.Types.ObjectId],
default: [],
default: []
}
},
{
timestamps: true,
timestamps: true
}
);
export const SecretVersion = model<ISecretVersion>(
"SecretVersion",
secretVersionSchema
);
export const SecretVersion = model<ISecretVersion>("SecretVersion", secretVersionSchema);
+11 -1
View File
@@ -49,7 +49,8 @@ export enum ProjectPermissionSub {
IpAllowList = "ip-allowlist",
Workspace = "workspace",
Secrets = "secrets",
SecretRollback = "secret-rollback"
SecretRollback = "secret-rollback",
SecretApproval = "secret-approval"
}
type SubjectFields = {
@@ -72,6 +73,7 @@ export type ProjectPermissionSet =
| [ProjectPermissionActions, ProjectPermissionSub.IpAllowList]
| [ProjectPermissionActions, ProjectPermissionSub.Settings]
| [ProjectPermissionActions, ProjectPermissionSub.ServiceTokens]
| [ProjectPermissionActions, ProjectPermissionSub.SecretApproval]
| [ProjectPermissionActions.Delete, ProjectPermissionSub.Workspace]
| [ProjectPermissionActions.Edit, ProjectPermissionSub.Workspace]
| [ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback]
@@ -85,6 +87,11 @@ const buildAdminPermission = () => {
can(ProjectPermissionActions.Edit, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback);
@@ -154,6 +161,8 @@ const buildMemberPermission = () => {
can(ProjectPermissionActions.Edit, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback);
@@ -203,6 +212,7 @@ const buildViewerPermission = () => {
const { can, build } = new AbilityBuilder<MongoAbility<ProjectPermissionSet>>(createMongoAbility);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Role);