mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Implement workaround for swagger-autogen edgecase and expose folders, secret imports API
This commit is contained in:
12
backend/package-lock.json
generated
12
backend/package-lock.json
generated
@@ -55,7 +55,6 @@
|
|||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
"rate-limit-mongo": "^2.3.2",
|
"rate-limit-mongo": "^2.3.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"swagger-autogen": "^2.22.0",
|
|
||||||
"swagger-ui-express": "^4.6.2",
|
"swagger-ui-express": "^4.6.2",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
"tweetnacl-util": "^0.15.1",
|
"tweetnacl-util": "^0.15.1",
|
||||||
@@ -96,6 +95,7 @@
|
|||||||
"npm": "^8.19.3",
|
"npm": "^8.19.3",
|
||||||
"smee-client": "^1.2.3",
|
"smee-client": "^1.2.3",
|
||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
|
"swagger-autogen": "^2.23.5",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"ts-node": "^10.9.1"
|
"ts-node": "^10.9.1"
|
||||||
}
|
}
|
||||||
@@ -10023,6 +10023,7 @@
|
|||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"json5": "lib/cli.js"
|
"json5": "lib/cli.js"
|
||||||
},
|
},
|
||||||
@@ -15559,6 +15560,7 @@
|
|||||||
"version": "2.23.5",
|
"version": "2.23.5",
|
||||||
"resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.5.tgz",
|
"resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.5.tgz",
|
||||||
"integrity": "sha512-4Tl2+XhZMyHoBYkABnScHtQE0lKPKUD3NBt09mClrI6UKOUYljKlYw1xiFVwsHCTGR2hAXmhT4PpgjruCtt1ZA==",
|
"integrity": "sha512-4Tl2+XhZMyHoBYkABnScHtQE0lKPKUD3NBt09mClrI6UKOUYljKlYw1xiFVwsHCTGR2hAXmhT4PpgjruCtt1ZA==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^7.4.1",
|
"acorn": "^7.4.1",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
@@ -15570,6 +15572,7 @@
|
|||||||
"version": "7.4.1",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -24521,7 +24524,8 @@
|
|||||||
"json5": {
|
"json5": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
|
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"jsonwebtoken": {
|
"jsonwebtoken": {
|
||||||
"version": "9.0.1",
|
"version": "9.0.1",
|
||||||
@@ -28614,6 +28618,7 @@
|
|||||||
"version": "2.23.5",
|
"version": "2.23.5",
|
||||||
"resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.5.tgz",
|
"resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.5.tgz",
|
||||||
"integrity": "sha512-4Tl2+XhZMyHoBYkABnScHtQE0lKPKUD3NBt09mClrI6UKOUYljKlYw1xiFVwsHCTGR2hAXmhT4PpgjruCtt1ZA==",
|
"integrity": "sha512-4Tl2+XhZMyHoBYkABnScHtQE0lKPKUD3NBt09mClrI6UKOUYljKlYw1xiFVwsHCTGR2hAXmhT4PpgjruCtt1ZA==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"acorn": "^7.4.1",
|
"acorn": "^7.4.1",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
@@ -28624,7 +28629,8 @@
|
|||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.4.1",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
"rate-limit-mongo": "^2.3.2",
|
"rate-limit-mongo": "^2.3.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"swagger-autogen": "^2.22.0",
|
|
||||||
"swagger-ui-express": "^4.6.2",
|
"swagger-ui-express": "^4.6.2",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
"tweetnacl-util": "^0.15.1",
|
"tweetnacl-util": "^0.15.1",
|
||||||
@@ -114,6 +113,7 @@
|
|||||||
"npm": "^8.19.3",
|
"npm": "^8.19.3",
|
||||||
"smee-client": "^1.2.3",
|
"smee-client": "^1.2.3",
|
||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
|
"swagger-autogen": "^2.23.5",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"ts-node": "^10.9.1"
|
"ts-node": "^10.9.1"
|
||||||
},
|
},
|
||||||
|
|||||||
3387
backend/spec.json
3387
backend/spec.json
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ import * as userController from "./userController";
|
|||||||
import * as workspaceController from "./workspaceController";
|
import * as workspaceController from "./workspaceController";
|
||||||
import * as secretScanningController from "./secretScanningController";
|
import * as secretScanningController from "./secretScanningController";
|
||||||
import * as webhookController from "./webhookController";
|
import * as webhookController from "./webhookController";
|
||||||
import * as secretImportController from "./secretImportController";
|
import * as secretImpsController from "./secretImpsController";
|
||||||
import * as roleController from "./roleController";
|
import * as roleController from "./roleController";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -37,5 +37,5 @@ export {
|
|||||||
secretScanningController,
|
secretScanningController,
|
||||||
webhookController,
|
webhookController,
|
||||||
roleController,
|
roleController,
|
||||||
secretImportController
|
secretImpsController
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,81 @@ import {
|
|||||||
} from "../../services/ProjectRoleService";
|
} from "../../services/ProjectRoleService";
|
||||||
import { ForbiddenError, subject } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
export const createSecretImport = async (req: Request, res: Response) => {
|
export const createSecretImp = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Create secret import'
|
||||||
|
#swagger.description = 'Create a new secret import for a specified workspace and environment'
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaceId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the workspace where the secret import will be created",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Environment to import to",
|
||||||
|
"example": "production"
|
||||||
|
},
|
||||||
|
"folderId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Folder ID. Use root for the root folder.",
|
||||||
|
"example": "my_folder"
|
||||||
|
},
|
||||||
|
"secretImport": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Import from environment",
|
||||||
|
"example": "development"
|
||||||
|
},
|
||||||
|
"secretPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Import from secret path",
|
||||||
|
"example": "/user/oauth"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["workspaceId", "environment", "folderName"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "successfully created secret import"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Confirmation of secret import creation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: "Bad Request. For example, 'Secret import already exist'"
|
||||||
|
}
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: "Unauthorized request. For example, 'Folder Permission Denied'"
|
||||||
|
}
|
||||||
|
#swagger.responses[404] = {
|
||||||
|
description: "Resource Not Found. For example, 'Failed to find folder'"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
const {
|
const {
|
||||||
body: { workspaceId, environment, folderId, secretImport }
|
body: { workspaceId, environment, folderId, secretImport }
|
||||||
} = await validateRequest(reqValidator.CreateSecretImportV1, req);
|
} = await validateRequest(reqValidator.CreateSecretImportV1, req);
|
||||||
@@ -129,7 +203,88 @@ export const createSecretImport = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
// to keep the ordering, you must pass all the imports in here not the only updated one
|
// to keep the ordering, you must pass all the imports in here not the only updated one
|
||||||
// this is because the order decide which import gets overriden
|
// this is because the order decide which import gets overriden
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update secret import
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const updateSecretImport = async (req: Request, res: Response) => {
|
export const updateSecretImport = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Update a secret import'
|
||||||
|
#swagger.description = 'Updates an existing secret import based on the provided ID and new import details'
|
||||||
|
|
||||||
|
#swagger.parameters['id'] = {
|
||||||
|
in: 'path',
|
||||||
|
description: 'ID of the secret import to be updated',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
example: 'import12345'
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretImports": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "List of new secret imports",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Environment of the secret import",
|
||||||
|
"example": "production"
|
||||||
|
},
|
||||||
|
"secretPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path of the secret import",
|
||||||
|
"example": "/path/to/secret"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["environment", "secretPath"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["secretImports"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
description: 'Successfully updated the secret import',
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "successfully updated secret import"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: 'Bad Request - Import not found',
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[403] = {
|
||||||
|
description: 'Forbidden access due to insufficient permissions',
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: 'Unauthorized access due to invalid token or scope',
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
body: { secretImports },
|
body: { secretImports },
|
||||||
params: { id }
|
params: { id }
|
||||||
@@ -202,7 +357,65 @@ export const updateSecretImport = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).json({ message: "successfully updated secret import" });
|
return res.status(200).json({ message: "successfully updated secret import" });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete secret import
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const deleteSecretImport = async (req: Request, res: Response) => {
|
export const deleteSecretImport = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete secret import'
|
||||||
|
#swagger.description = 'Delete secret import'
|
||||||
|
|
||||||
|
#swagger.parameters['id'] = {
|
||||||
|
in: 'path',
|
||||||
|
description: 'ID of the secret import',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
example: '12345abcde'
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretImportEnv": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Import from environment",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"secretImportPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Import from secret path",
|
||||||
|
"example": "production"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["id", "secretImportEnv", "secretImportPath"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "successfully delete secret import"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Confirmation of secret import deletion"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { id },
|
params: { id },
|
||||||
body: { secretImportEnv, secretImportPath }
|
body: { secretImportEnv, secretImportPath }
|
||||||
@@ -274,7 +487,66 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).json({ message: "successfully delete secret import" });
|
return res.status(200).json({ message: "successfully delete secret import" });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get secret imports
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const getSecretImports = async (req: Request, res: Response) => {
|
export const getSecretImports = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Retrieve secret imports'
|
||||||
|
#swagger.description = 'Fetches the secret imports based on the workspaceId, environment, and folderId'
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
in: 'query',
|
||||||
|
description: 'ID of the workspace of secret imports to get',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
example: 'workspace12345'
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['environment'] = {
|
||||||
|
in: 'query',
|
||||||
|
description: 'Environment of secret imports to get',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
example: 'production'
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['folderId'] = {
|
||||||
|
in: 'query',
|
||||||
|
description: 'ID of the folder containing the secret imports. Default: root',
|
||||||
|
required: false,
|
||||||
|
type: 'string',
|
||||||
|
example: 'folder12345'
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
description: 'Successfully retrieved secret import',
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"secretImport": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Details of a secret import"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[403] = {
|
||||||
|
description: 'Forbidden access due to insufficient permissions',
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: 'Unauthorized access due to invalid token or scope',
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
query: { workspaceId, environment, folderId }
|
query: { workspaceId, environment, folderId }
|
||||||
} = await validateRequest(reqValidator.GetSecretImportsV1, req);
|
} = await validateRequest(reqValidator.GetSecretImportsV1, req);
|
||||||
@@ -326,6 +598,12 @@ export const getSecretImports = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).json({ secretImport: importSecDoc });
|
return res.status(200).json({ secretImport: importSecDoc });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all secret imports
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const getAllSecretsFromImport = async (req: Request, res: Response) => {
|
export const getAllSecretsFromImport = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
query: { workspaceId, environment, folderId }
|
query: { workspaceId, environment, folderId }
|
||||||
@@ -25,8 +25,87 @@ import {
|
|||||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||||
import * as reqValidator from "../../validation/folders";
|
import * as reqValidator from "../../validation/folders";
|
||||||
|
|
||||||
// verify workspace id/environment
|
/**
|
||||||
|
* Create folder with name [folderName] for workspace with id [workspaceId]
|
||||||
|
* and environment [environment]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const createFolder = async (req: Request, res: Response) => {
|
export const createFolder = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Create a folder'
|
||||||
|
#swagger.description = 'Create a new folder in a specified workspace and environment'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaceId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the workspace where the folder will be created",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Environment where the folder will reside",
|
||||||
|
"example": "production"
|
||||||
|
},
|
||||||
|
"folderName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the folder to be created",
|
||||||
|
"example": "my_folder"
|
||||||
|
},
|
||||||
|
"parentFolderId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the parent folder under which this folder will be created. If not specified, it will be created at the root level.",
|
||||||
|
"example": "someParentFolderId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["workspaceId", "environment", "folderName"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"folder": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderId"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "my_folder"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Details of the created folder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: "Bad Request. For example, 'Folder name cannot contain spaces. Only underscore and dashes'"
|
||||||
|
}
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: "Unauthorized request. For example, 'Folder Permission Denied'"
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
body: { workspaceId, environment, folderName, parentFolderId }
|
body: { workspaceId, environment, folderName, parentFolderId }
|
||||||
} = await validateRequest(reqValidator.CreateFolderV1, req);
|
} = await validateRequest(reqValidator.CreateFolderV1, req);
|
||||||
@@ -164,7 +243,94 @@ export const createFolder = async (req: Request, res: Response) => {
|
|||||||
return res.json({ folder });
|
return res.json({ folder });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update folder with id [folderId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const updateFolderById = async (req: Request, res: Response) => {
|
export const updateFolderById = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Update a folder by ID'
|
||||||
|
#swagger.description = 'Update the name of a folder in a specified workspace and environment by its ID'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['folderId'] = {
|
||||||
|
"description": "ID of the folder to be updated",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaceId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the workspace where the folder is located",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Environment where the folder is located",
|
||||||
|
"example": "production"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "New name for the folder",
|
||||||
|
"example": "updated_folder_name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["workspaceId", "environment", "name"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Successfully updated folder"
|
||||||
|
},
|
||||||
|
"folder": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "updated_folder_name"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Details of the updated folder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: "Bad Request. Reasons can include 'The folder doesn't exist' or 'Folder name cannot contain spaces. Only underscore and dashes'"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: "Unauthorized request. For example, 'Folder Permission Denied'"
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
body: { workspaceId, environment, name },
|
body: { workspaceId, environment, name },
|
||||||
params: { folderId }
|
params: { folderId }
|
||||||
@@ -252,7 +418,92 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete folder with id [folderId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const deleteFolder = async (req: Request, res: Response) => {
|
export const deleteFolder = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete a folder by ID'
|
||||||
|
#swagger.description = 'Delete the specified folder from a specified workspace and environment using its ID'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['folderId'] = {
|
||||||
|
"description": "ID of the folder to be deleted",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaceId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the workspace where the folder is located",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Environment where the folder is located",
|
||||||
|
"example": "production"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["workspaceId", "environment"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "successfully deleted folders"
|
||||||
|
},
|
||||||
|
"folders": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderId"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "List of IDs and names of the deleted folders"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: "Bad Request. Reasons can include 'The folder doesn't exist'"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: "Unauthorized request. For example, 'Folder Permission Denied'"
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { folderId },
|
params: { folderId },
|
||||||
body: { environment, workspaceId }
|
body: { environment, workspaceId }
|
||||||
@@ -327,8 +578,104 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
|||||||
res.send({ message: "successfully deleted folders", folders: delFolderIds });
|
res.send({ message: "successfully deleted folders", folders: delFolderIds });
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: validate workspace
|
/**
|
||||||
|
* Get folders for workspace with id [workspaceId] and environment [environment]
|
||||||
|
* considering [parentFolderId] and [parentFolderPath]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const getFolders = async (req: Request, res: Response) => {
|
export const getFolders = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Retrieve folders based on specific conditions'
|
||||||
|
#swagger.description = 'Fetches folders from the specified workspace and environment, optionally providing either a parentFolderId or a parentFolderPath to narrow down results'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of the workspace from which the folders are to be fetched",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['environment'] = {
|
||||||
|
"description": "Environment where the folder is located",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['parentFolderId'] = {
|
||||||
|
"description": "ID of the parent folder",
|
||||||
|
"required": false,
|
||||||
|
"type": "string",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['parentFolderPath'] = {
|
||||||
|
"description": "Path of the parent folder, like /folder1/folder2",
|
||||||
|
"required": false,
|
||||||
|
"type": "string",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"folders": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderId"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someFolderName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "List of folders"
|
||||||
|
},
|
||||||
|
"dir": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "parentFolderName"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "parentFolderId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "List of directories"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[400] = {
|
||||||
|
description: "Bad Request. For instance, 'The folder doesn't exist'"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[401] = {
|
||||||
|
description: "Unauthorized request. For example, 'Folder Permission Denied'"
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
query: { workspaceId, environment, parentFolderId, parentFolderPath }
|
query: { workspaceId, environment, parentFolderId, parentFolderPath }
|
||||||
} = await validateRequest(reqValidator.GetFoldersV1, req);
|
} = await validateRequest(reqValidator.GetFoldersV1, req);
|
||||||
|
|||||||
@@ -23,12 +23,98 @@ import {
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new workspace environment named [environmentName] under workspace with id
|
* Create new workspace environment named [environmentName]
|
||||||
|
* with slug [environmentSlug] under workspace with id
|
||||||
* @param req
|
* @param req
|
||||||
* @param res
|
* @param res
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createWorkspaceEnvironment = async (req: Request, res: Response) => {
|
export const createWorkspaceEnvironment = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Create environment'
|
||||||
|
#swagger.description = 'Create environment'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Create environment'
|
||||||
|
#swagger.description = 'Create environment'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the environment",
|
||||||
|
"example": "development"
|
||||||
|
},
|
||||||
|
"environmentSlug": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Slug of the environment",
|
||||||
|
"example": "dev-environment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["environmentName", "environmentSlug"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Successfully created new environment"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someEnvironmentName"
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someEnvironmentSlug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Response after creating a new environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { workspaceId },
|
params: { workspaceId },
|
||||||
body: { environmentName, environmentSlug }
|
body: { environmentName, environmentSlug }
|
||||||
@@ -156,6 +242,79 @@ export const reorderWorkspaceEnvironments = async (req: Request, res: Response)
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const renameWorkspaceEnvironment = async (req: Request, res: Response) => {
|
export const renameWorkspaceEnvironment = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Rename workspace environment'
|
||||||
|
#swagger.description = 'Rename a specific environment within a workspace'
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of the workspace",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "New name for the environment",
|
||||||
|
"example": "Staging-Renamed"
|
||||||
|
},
|
||||||
|
"environmentSlug": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "New slug for the environment",
|
||||||
|
"example": "staging-renamed"
|
||||||
|
},
|
||||||
|
"oldEnvironmentSlug": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Current slug of the environment to rename",
|
||||||
|
"example": "staging-old"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["environmentName", "environmentSlug", "oldEnvironmentSlug"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Successfully update environment"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Staging-Renamed"
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "staging-renamed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Details of the renamed environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { workspaceId },
|
params: { workspaceId },
|
||||||
body: { environmentName, environmentSlug, oldEnvironmentSlug }
|
body: { environmentName, environmentSlug, oldEnvironmentSlug }
|
||||||
@@ -259,6 +418,64 @@ export const renameWorkspaceEnvironment = async (req: Request, res: Response) =>
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const deleteWorkspaceEnvironment = async (req: Request, res: Response) => {
|
export const deleteWorkspaceEnvironment = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete workspace environment'
|
||||||
|
#swagger.description = 'Delete a specific environment from a workspace'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of the workspace",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentSlug": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Slug of the environment to delete",
|
||||||
|
"example": "dev-environment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["environmentSlug"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Successfully deleted environment"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "someWorkspaceId"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "dev-environment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Response after deleting an environment from a workspace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { workspaceId },
|
params: { workspaceId },
|
||||||
body: { environmentSlug }
|
body: { environmentSlug }
|
||||||
@@ -344,6 +561,58 @@ export const deleteWorkspaceEnvironment = async (req: Request, res: Response) =>
|
|||||||
|
|
||||||
// TODO(akhilmhdh) after rbac this can be completely removed
|
// TODO(akhilmhdh) after rbac this can be completely removed
|
||||||
export const getAllAccessibleEnvironmentsOfWorkspace = async (req: Request, res: Response) => {
|
export const getAllAccessibleEnvironmentsOfWorkspace = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Get all accessible environments of a workspace'
|
||||||
|
#swagger.description = 'Fetch all environments that the user has access to in a specified workspace'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of the workspace",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
"in": "path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"accessibleEnvironments": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Development"
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "development"
|
||||||
|
},
|
||||||
|
"isWriteDenied": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
|
"isReadDenied": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "List of environments the user has access to in the specified workspace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
const {
|
const {
|
||||||
params: { workspaceId }
|
params: { workspaceId }
|
||||||
} = await validateRequest(reqValidator.GetAllAccessibileEnvironmentsOfWorkspaceV2, req);
|
} = await validateRequest(reqValidator.GetAllAccessibileEnvironmentsOfWorkspaceV2, req);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import {
|
|||||||
organization as v1OrganizationRouter,
|
organization as v1OrganizationRouter,
|
||||||
password as v1PasswordRouter,
|
password as v1PasswordRouter,
|
||||||
role as v1RoleRouter,
|
role as v1RoleRouter,
|
||||||
secretImport as v1SecretImportRouter,
|
secretImps as v1SecretImpsRouter,
|
||||||
secret as v1SecretRouter,
|
secret as v1SecretRouter,
|
||||||
secretsFolder as v1SecretsFolder,
|
secretsFolder as v1SecretsFolder,
|
||||||
serviceToken as v1ServiceTokenRouter,
|
serviceToken as v1ServiceTokenRouter,
|
||||||
@@ -138,6 +138,7 @@ const main = async () => {
|
|||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
// default to IP address provided by Cloudflare
|
// default to IP address provided by Cloudflare
|
||||||
|
// #swagger.ignore = true
|
||||||
const cfIp = req.headers["cf-connecting-ip"];
|
const cfIp = req.headers["cf-connecting-ip"];
|
||||||
req.realIP = Array.isArray(cfIp) ? cfIp[0] : (cfIp as string) || req.ip;
|
req.realIP = Array.isArray(cfIp) ? cfIp[0] : (cfIp as string) || req.ip;
|
||||||
next();
|
next();
|
||||||
@@ -153,7 +154,7 @@ const main = async () => {
|
|||||||
app.use("/api/v1/sso", eeSSORouter);
|
app.use("/api/v1/sso", eeSSORouter);
|
||||||
app.use("/api/v1/cloud-products", eeCloudProductsRouter);
|
app.use("/api/v1/cloud-products", eeCloudProductsRouter);
|
||||||
|
|
||||||
// v1 routes (default)
|
// v1 routes
|
||||||
app.use("/api/v1/signup", v1SignupRouter);
|
app.use("/api/v1/signup", v1SignupRouter);
|
||||||
app.use("/api/v1/auth", v1AuthRouter);
|
app.use("/api/v1/auth", v1AuthRouter);
|
||||||
app.use("/api/v1/bot", v1BotRouter);
|
app.use("/api/v1/bot", v1BotRouter);
|
||||||
@@ -162,7 +163,7 @@ const main = async () => {
|
|||||||
app.use("/api/v1/organization", v1OrganizationRouter);
|
app.use("/api/v1/organization", v1OrganizationRouter);
|
||||||
app.use("/api/v1/workspace", v1WorkspaceRouter);
|
app.use("/api/v1/workspace", v1WorkspaceRouter);
|
||||||
app.use("/api/v1/membership-org", v1MembershipOrgRouter);
|
app.use("/api/v1/membership-org", v1MembershipOrgRouter);
|
||||||
app.use("/api/v1/membership", v1MembershipRouter);
|
app.use("/api/v1/membership", v1MembershipRouter); //
|
||||||
app.use("/api/v1/key", v1KeyRouter);
|
app.use("/api/v1/key", v1KeyRouter);
|
||||||
app.use("/api/v1/invite-org", v1InviteOrgRouter);
|
app.use("/api/v1/invite-org", v1InviteOrgRouter);
|
||||||
app.use("/api/v1/secret", v1SecretRouter); // deprecate
|
app.use("/api/v1/secret", v1SecretRouter); // deprecate
|
||||||
@@ -173,7 +174,7 @@ const main = async () => {
|
|||||||
app.use("/api/v1/folders", v1SecretsFolder);
|
app.use("/api/v1/folders", v1SecretsFolder);
|
||||||
app.use("/api/v1/secret-scanning", v1SecretScanningRouter);
|
app.use("/api/v1/secret-scanning", v1SecretScanningRouter);
|
||||||
app.use("/api/v1/webhooks", v1WebhooksRouter);
|
app.use("/api/v1/webhooks", v1WebhooksRouter);
|
||||||
app.use("/api/v1/secret-imports", v1SecretImportRouter);
|
app.use("/api/v1/secret-imports", v1SecretImpsRouter);
|
||||||
app.use("/api/v1/roles", v1RoleRouter);
|
app.use("/api/v1/roles", v1RoleRouter);
|
||||||
|
|
||||||
// v2 routes (improvements)
|
// v2 routes (improvements)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import integration from "./integration";
|
|||||||
import integrationAuth from "./integrationAuth";
|
import integrationAuth from "./integrationAuth";
|
||||||
import secretsFolder from "./secretsFolder";
|
import secretsFolder from "./secretsFolder";
|
||||||
import webhooks from "./webhook";
|
import webhooks from "./webhook";
|
||||||
import secretImport from "./secretImport";
|
import secretImps from "./secretImps";
|
||||||
import role from "./role";
|
import role from "./role";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -38,6 +38,6 @@ export {
|
|||||||
integrationAuth,
|
integrationAuth,
|
||||||
secretsFolder,
|
secretsFolder,
|
||||||
webhooks,
|
webhooks,
|
||||||
secretImport,
|
secretImps,
|
||||||
role
|
role
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { secretImportController } from "../../controllers/v1";
|
|
||||||
import { requireAuth } from "../../middleware";
|
|
||||||
import { AuthMode } from "../../variables";
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
import { requireAuth } from "../../middleware";
|
||||||
|
import { secretImpsController } from "../../controllers/v1";
|
||||||
|
import { AuthMode } from "../../variables";
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
"/",
|
"/",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
||||||
}),
|
}),
|
||||||
secretImportController.createSecretImport
|
secretImpsController.createSecretImp
|
||||||
);
|
);
|
||||||
|
|
||||||
router.put(
|
router.put(
|
||||||
@@ -17,7 +17,7 @@ router.put(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
||||||
}),
|
}),
|
||||||
secretImportController.updateSecretImport
|
secretImpsController.updateSecretImport
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
@@ -25,7 +25,7 @@ router.delete(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
||||||
}),
|
}),
|
||||||
secretImportController.deleteSecretImport
|
secretImpsController.deleteSecretImport
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -33,7 +33,7 @@ router.get(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
||||||
}),
|
}),
|
||||||
secretImportController.getSecretImports
|
secretImpsController.getSecretImports
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -41,7 +41,7 @@ router.get(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.SERVICE_TOKEN]
|
||||||
}),
|
}),
|
||||||
secretImportController.getAllSecretsFromImport
|
secretImpsController.getAllSecretsFromImport
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
|
const router = express.Router();
|
||||||
|
import { requireAuth } from "../../middleware";
|
||||||
import {
|
import {
|
||||||
createFolder,
|
createFolder,
|
||||||
deleteFolder,
|
deleteFolder,
|
||||||
getFolders,
|
getFolders,
|
||||||
updateFolderById
|
updateFolderById
|
||||||
} from "../../controllers/v1/secretsFolderController";
|
} from "../../controllers/v1/secretsFolderController";
|
||||||
import { requireAuth } from "../../middleware";
|
|
||||||
import { AuthMode } from "../../variables";
|
import { AuthMode } from "../../variables";
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
"/",
|
"/",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { AuthMode } from "../../variables";
|
|||||||
router.post(
|
router.post(
|
||||||
"/:workspaceId/environments",
|
"/:workspaceId/environments",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||||
}),
|
}),
|
||||||
environmentController.createWorkspaceEnvironment
|
environmentController.createWorkspaceEnvironment
|
||||||
);
|
);
|
||||||
@@ -15,7 +15,7 @@ router.post(
|
|||||||
router.put(
|
router.put(
|
||||||
"/:workspaceId/environments",
|
"/:workspaceId/environments",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||||
}),
|
}),
|
||||||
environmentController.renameWorkspaceEnvironment
|
environmentController.renameWorkspaceEnvironment
|
||||||
);
|
);
|
||||||
@@ -31,7 +31,7 @@ router.patch(
|
|||||||
router.delete(
|
router.delete(
|
||||||
"/:workspaceId/environments",
|
"/:workspaceId/environments",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||||
}),
|
}),
|
||||||
environmentController.deleteWorkspaceEnvironment
|
environmentController.deleteWorkspaceEnvironment
|
||||||
);
|
);
|
||||||
@@ -39,7 +39,7 @@ router.delete(
|
|||||||
router.get(
|
router.get(
|
||||||
"/:workspaceId/environments",
|
"/:workspaceId/environments",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||||
}),
|
}),
|
||||||
environmentController.getAllAccessibleEnvironmentsOfWorkspace
|
environmentController.getAllAccessibleEnvironmentsOfWorkspace
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -223,7 +223,8 @@ const generateOpenAPISpec = async () => {
|
|||||||
const endpointsFiles = ["../src/index.ts"];
|
const endpointsFiles = ["../src/index.ts"];
|
||||||
|
|
||||||
const spec = await swaggerAutogen(outputJSONFile, endpointsFiles, doc);
|
const spec = await swaggerAutogen(outputJSONFile, endpointsFiles, doc);
|
||||||
|
|
||||||
await fs.writeFile(outputYAMLFile, yaml.dump(spec.data));
|
await fs.writeFile(outputYAMLFile, yaml.dump(spec.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
generateOpenAPISpec();
|
generateOpenAPISpec();
|
||||||
4
docs/api-reference/endpoints/folders/create.mdx
Normal file
4
docs/api-reference/endpoints/folders/create.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Create"
|
||||||
|
openapi: "POST /api/v1/folders/"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/folders/delete.mdx
Normal file
4
docs/api-reference/endpoints/folders/delete.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Delete"
|
||||||
|
openapi: "DELETE /api/v1/folders/{folderId}"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/folders/list.mdx
Normal file
4
docs/api-reference/endpoints/folders/list.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "List"
|
||||||
|
openapi: "GET /api/v1/folders/"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/folders/update.mdx
Normal file
4
docs/api-reference/endpoints/folders/update.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Update"
|
||||||
|
openapi: "PATCH /api/v1/folders/{folderId}"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/secret-imports/create.mdx
Normal file
4
docs/api-reference/endpoints/secret-imports/create.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Create"
|
||||||
|
openapi: "POST /api/v1/secret-imports/"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/secret-imports/delete.mdx
Normal file
4
docs/api-reference/endpoints/secret-imports/delete.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Delete"
|
||||||
|
openapi: "DELETE /api/v1/secret-imports/{id}"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/secret-imports/list.mdx
Normal file
4
docs/api-reference/endpoints/secret-imports/list.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "List"
|
||||||
|
openapi: "GET /api/v1/secret-imports/"
|
||||||
|
---
|
||||||
4
docs/api-reference/endpoints/secret-imports/update.mdx
Normal file
4
docs/api-reference/endpoints/secret-imports/update.mdx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Update"
|
||||||
|
openapi: "PUT /api/v1/secret-imports/{id}"
|
||||||
|
---
|
||||||
@@ -5,7 +5,6 @@ openapi: "POST /api/v3/secrets/{secretName}"
|
|||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Using this route requires understanding Infisical's system and cryptography.
|
Using this route requires understanding Infisical's system and cryptography.
|
||||||
It may be helpful to read through the
|
You should consult the [examples](https://infisical.com/docs/api-reference/overview/examples/note) for how to use
|
||||||
[introduction](/api-reference/overview/introduction) and [guide for creating
|
this endpoint.
|
||||||
secrets](/api-reference/overview/examples/create-secret).
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Delete"
|
title: "Delete"
|
||||||
openapi: "DELETE /api/v3/secrets/{secretName}"
|
openapi: "DELETE /api/v3/secrets/{secretName}"
|
||||||
---
|
---
|
||||||
@@ -5,7 +5,7 @@ openapi: "GET /api/v3/secrets/"
|
|||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Using this route requires understanding Infisical's system and cryptography.
|
Using this route requires understanding Infisical's system and cryptography.
|
||||||
It may be helpful to read through the
|
You should consult the [examples](https://infisical.com/docs/api-reference/overview/examples/note) for how to use
|
||||||
[introduction](/api-reference/overview/introduction) and [guide for retrieving
|
this endpoint.
|
||||||
secrets](/api-reference/overview/examples/retrieve-secret).
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ openapi: "GET /api/v3/secrets/{secretName}"
|
|||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Using this route requires understanding Infisical's system and cryptography.
|
Using this route requires understanding Infisical's system and cryptography.
|
||||||
It may be helpful to read through the
|
You should consult the [examples](https://infisical.com/docs/api-reference/overview/examples/note) for how to use
|
||||||
[introduction](/api-reference/overview/introduction) and [guide for retrieving
|
this endpoint.
|
||||||
secrets](/api-reference/overview/examples/retrieve-secret).
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ openapi: "PATCH /api/v3/secrets/{secretName}"
|
|||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Using this route requires understanding Infisical's system and cryptography.
|
Using this route requires understanding Infisical's system and cryptography.
|
||||||
It may be helpful to read through the
|
You should consult the [examples](https://infisical.com/docs/api-reference/overview/examples/note) for how to use
|
||||||
[introduction](/api-reference/overview/introduction) and [guide for updating
|
this endpoint.
|
||||||
secrets](/api-reference/overview/examples/update-secret).
|
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,15 @@
|
|||||||
"api-reference/endpoints/environments/delete"
|
"api-reference/endpoints/environments/delete"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group": "Folders",
|
||||||
|
"pages": [
|
||||||
|
"api-reference/endpoints/folders/list",
|
||||||
|
"api-reference/endpoints/folders/create",
|
||||||
|
"api-reference/endpoints/folders/update",
|
||||||
|
"api-reference/endpoints/folders/delete"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group": "Secrets",
|
"group": "Secrets",
|
||||||
"pages": [
|
"pages": [
|
||||||
@@ -343,6 +352,15 @@
|
|||||||
"api-reference/endpoints/secrets/rollback-version"
|
"api-reference/endpoints/secrets/rollback-version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"group": "Secret imports",
|
||||||
|
"pages": [
|
||||||
|
"api-reference/endpoints/secret-imports/list",
|
||||||
|
"api-reference/endpoints/secret-imports/create",
|
||||||
|
"api-reference/endpoints/secret-imports/update",
|
||||||
|
"api-reference/endpoints/secret-imports/delete"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group": "Service Tokens",
|
"group": "Service Tokens",
|
||||||
"pages": ["api-reference/endpoints/service-tokens/get"]
|
"pages": ["api-reference/endpoints/service-tokens/get"]
|
||||||
|
|||||||
2222
docs/spec.yaml
2222
docs/spec.yaml
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user