mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 20:26:44 +00:00
Merge pull request #225 from Infisical/expand-open-api
Add new organization endpoints to API reference
This commit is contained in:
+511
-53
@@ -2258,6 +2258,368 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v2/users/me/organizations": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Return organizations that current user is part of",
|
||||||
|
"description": "Return organizations that current user is part of",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"organizations": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Organization"
|
||||||
|
},
|
||||||
|
"description": "Organizations that user is part of"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/organizations/{organizationId}/memberships": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Return organization memberships",
|
||||||
|
"description": "Return organization memberships",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "organizationId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"memberships": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/MembershipOrg"
|
||||||
|
},
|
||||||
|
"description": "Memberships of organization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/organizations/{organizationId}/memberships/{membershipId}": {
|
||||||
|
"patch": {
|
||||||
|
"summary": "Update organization membership",
|
||||||
|
"description": "Update organization membership",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "organizationId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "membershipId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization membership to update"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
"$ref": "#/components/schemas/MembershipOrg",
|
||||||
|
"description": "Updated organization membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Role of organization membership - either owner, admin, or member"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete organization membership",
|
||||||
|
"description": "Delete organization membership",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "organizationId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "membershipId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization membership to delete"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
"$ref": "#/components/schemas/MembershipOrg",
|
||||||
|
"description": "Deleted organization membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/organizations/{organizationId}/workspaces": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Return projects in organization that user is part of",
|
||||||
|
"description": "Return projects in organization that user is part of",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "organizationId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of organization"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaces": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Project"
|
||||||
|
},
|
||||||
|
"description": "Projects of organization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/workspace/{workspaceId}/environments": {
|
||||||
|
"post": {
|
||||||
|
"description": "",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentName": {
|
||||||
|
"example": "any"
|
||||||
|
},
|
||||||
|
"environmentSlug": {
|
||||||
|
"example": "any"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentName": {
|
||||||
|
"example": "any"
|
||||||
|
},
|
||||||
|
"environmentSlug": {
|
||||||
|
"example": "any"
|
||||||
|
},
|
||||||
|
"oldEnvironmentSlug": {
|
||||||
|
"example": "any"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"environmentSlug": {
|
||||||
|
"example": "any"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v2/workspace/{workspaceId}/secrets": {
|
"/api/v2/workspace/{workspaceId}/secrets": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "",
|
"description": "",
|
||||||
@@ -2450,56 +2812,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v2/workspace/{workspaceId}/memberships/{membershipId}": {
|
"/api/v2/workspace/{workspaceId}/memberships/{membershipId}": {
|
||||||
"delete": {
|
|
||||||
"summary": "Delete project membership",
|
|
||||||
"description": "Delete project membership",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "workspaceId",
|
|
||||||
"in": "path",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"description": "ID of project"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "membershipId",
|
|
||||||
"in": "path",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"description": "ID of membership"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"membership": {
|
|
||||||
"$ref": "#/components/schemas/Membership",
|
|
||||||
"description": "Deleted membership"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"description": "Bad Request"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"apiKeyAuth": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"patch": {
|
"patch": {
|
||||||
"summary": "Update project membership",
|
"summary": "Update project membership",
|
||||||
"description": "Update project membership",
|
"description": "Update project membership",
|
||||||
@@ -2520,7 +2832,7 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"description": "ID of membership"
|
"description": "ID of project membership to update"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -2565,6 +2877,56 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete project membership",
|
||||||
|
"description": "Delete project membership",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "membershipId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "ID of project membership to delete"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
"$ref": "#/components/schemas/Membership",
|
||||||
|
"description": "Deleted membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}": {
|
"/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}": {
|
||||||
@@ -3131,7 +3493,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v2/api-key-data/": {
|
"/api/v2/api-key/": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"parameters": [],
|
"parameters": [],
|
||||||
@@ -3174,7 +3536,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/v2/api-key-data/{apiKeyDataId}": {
|
"/api/v2/api-key/{apiKeyDataId}": {
|
||||||
"delete": {
|
"delete": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
@@ -3302,6 +3664,102 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MembershipOrg": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"user": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"publicKey": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"updatedAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"organization": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "owner"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "accepted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Organization": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"_id": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"customerId": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Project": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "My Project"
|
||||||
|
},
|
||||||
|
"organization": {
|
||||||
|
"type": "string",
|
||||||
|
"example": ""
|
||||||
|
},
|
||||||
|
"environments": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "development"
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ProjectKey": {
|
"ProjectKey": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
+6
-5
@@ -42,9 +42,10 @@ import {
|
|||||||
} from './routes/v1';
|
} from './routes/v1';
|
||||||
import {
|
import {
|
||||||
users as v2UsersRouter,
|
users as v2UsersRouter,
|
||||||
|
organizations as v2OrganizationsRouter,
|
||||||
|
workspace as v2WorkspaceRouter,
|
||||||
secret as v2SecretRouter, // begin to phase out
|
secret as v2SecretRouter, // begin to phase out
|
||||||
secrets as v2SecretsRouter,
|
secrets as v2SecretsRouter,
|
||||||
workspace as v2WorkspaceRouter,
|
|
||||||
serviceTokenData as v2ServiceTokenDataRouter,
|
serviceTokenData as v2ServiceTokenDataRouter,
|
||||||
apiKeyData as v2APIKeyDataRouter,
|
apiKeyData as v2APIKeyDataRouter,
|
||||||
environment as v2EnvironmentRouter,
|
environment as v2EnvironmentRouter,
|
||||||
@@ -98,7 +99,7 @@ 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);
|
app.use('/api/v1/secret', v1SecretRouter);
|
||||||
app.use('/api/v1/service-token', v1ServiceTokenRouter); // stop supporting
|
app.use('/api/v1/service-token', v1ServiceTokenRouter); // deprecated
|
||||||
app.use('/api/v1/password', v1PasswordRouter);
|
app.use('/api/v1/password', v1PasswordRouter);
|
||||||
app.use('/api/v1/stripe', v1StripeRouter);
|
app.use('/api/v1/stripe', v1StripeRouter);
|
||||||
app.use('/api/v1/integration', v1IntegrationRouter);
|
app.use('/api/v1/integration', v1IntegrationRouter);
|
||||||
@@ -106,9 +107,10 @@ app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
|
|||||||
|
|
||||||
// v2 routes
|
// v2 routes
|
||||||
app.use('/api/v2/users', v2UsersRouter);
|
app.use('/api/v2/users', v2UsersRouter);
|
||||||
|
app.use('/api/v2/organizations', v2OrganizationsRouter);
|
||||||
app.use('/api/v2/workspace', v2EnvironmentRouter);
|
app.use('/api/v2/workspace', v2EnvironmentRouter);
|
||||||
app.use('/api/v2/workspace', v2WorkspaceRouter); // TODO: turn into plural route
|
app.use('/api/v2/workspace', v2WorkspaceRouter);
|
||||||
app.use('/api/v2/secret', v2SecretRouter); // stop supporting, TODO: revise
|
app.use('/api/v2/secret', v2SecretRouter); // deprecated
|
||||||
app.use('/api/v2/secrets', v2SecretsRouter);
|
app.use('/api/v2/secrets', v2SecretsRouter);
|
||||||
app.use('/api/v2/service-token', v2ServiceTokenDataRouter); // TODO: turn into plural route
|
app.use('/api/v2/service-token', v2ServiceTokenDataRouter); // TODO: turn into plural route
|
||||||
app.use('/api/v2/api-key', v2APIKeyDataRouter);
|
app.use('/api/v2/api-key', v2APIKeyDataRouter);
|
||||||
@@ -128,7 +130,6 @@ app.use((req, res, next) => {
|
|||||||
//* Error Handling Middleware (must be after all routing logic)
|
//* Error Handling Middleware (must be after all routing logic)
|
||||||
app.use(requestErrorHandler)
|
app.use(requestErrorHandler)
|
||||||
|
|
||||||
|
|
||||||
export const server = app.listen(PORT, () => {
|
export const server = app.listen(PORT, () => {
|
||||||
getLogger("backend-main").info(`Server started listening at port ${PORT}`)
|
getLogger("backend-main").info(`Server started listening at port ${PORT}`)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ const productToPriceMap = {
|
|||||||
cardAuth: STRIPE_PRODUCT_CARD_AUTH
|
cardAuth: STRIPE_PRODUCT_CARD_AUTH
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Return organizations that user is part of
|
|
||||||
* @param req
|
|
||||||
* @param res
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const getOrganizations = async (req: Request, res: Response) => {
|
export const getOrganizations = async (req: Request, res: Response) => {
|
||||||
let organizations;
|
let organizations;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as usersController from './usersController';
|
import * as usersController from './usersController';
|
||||||
|
import * as organizationsController from './organizationsController';
|
||||||
import * as workspaceController from './workspaceController';
|
import * as workspaceController from './workspaceController';
|
||||||
import * as serviceTokenDataController from './serviceTokenDataController';
|
import * as serviceTokenDataController from './serviceTokenDataController';
|
||||||
import * as apiKeyDataController from './apiKeyDataController';
|
import * as apiKeyDataController from './apiKeyDataController';
|
||||||
@@ -8,6 +9,7 @@ import * as environmentController from './environmentController';
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
usersController,
|
usersController,
|
||||||
|
organizationsController,
|
||||||
workspaceController,
|
workspaceController,
|
||||||
serviceTokenDataController,
|
serviceTokenDataController,
|
||||||
apiKeyDataController,
|
apiKeyDataController,
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
import { Request, Response } from 'express';
|
||||||
|
import * as Sentry from '@sentry/node';
|
||||||
|
import {
|
||||||
|
MembershipOrg,
|
||||||
|
Membership,
|
||||||
|
Workspace
|
||||||
|
} from '../../models';
|
||||||
|
import { deleteMembershipOrg } from '../../helpers/membershipOrg';
|
||||||
|
import { updateSubscriptionOrgQuantity } from '../../helpers/organization';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return memberships for organization with id [organizationId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
|
export const getOrganizationMemberships = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return organization memberships'
|
||||||
|
#swagger.description = 'Return organization memberships'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['organizationId'] = {
|
||||||
|
"description": "ID of organization",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"memberships": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/MembershipOrg"
|
||||||
|
},
|
||||||
|
"description": "Memberships of organization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let memberships;
|
||||||
|
try {
|
||||||
|
const { organizationId } = req.params;
|
||||||
|
|
||||||
|
memberships = await MembershipOrg.find({
|
||||||
|
organization: organizationId
|
||||||
|
}).populate('user', '+publicKey');
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to get organization memberships'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
memberships
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update role of membership with id [membershipId] to role [role]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
|
export const updateOrganizationMembership = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Update organization membership'
|
||||||
|
#swagger.description = 'Update organization membership'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['organizationId'] = {
|
||||||
|
"description": "ID of organization",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['membershipId'] = {
|
||||||
|
"description": "ID of organization membership to update",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.requestBody = {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Role of organization membership - either owner, admin, or member",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
$ref: "#/components/schemas/MembershipOrg",
|
||||||
|
"description": "Updated organization membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
const { membershipId } = req.params;
|
||||||
|
const { role } = req.body;
|
||||||
|
|
||||||
|
membership = await MembershipOrg.findByIdAndUpdate(
|
||||||
|
membershipId,
|
||||||
|
{
|
||||||
|
role
|
||||||
|
}, {
|
||||||
|
new: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to update organization membership'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
membership
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete organization membership with id [membershipId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const deleteOrganizationMembership = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete organization membership'
|
||||||
|
#swagger.description = 'Delete organization membership'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['organizationId'] = {
|
||||||
|
"description": "ID of organization",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['membershipId'] = {
|
||||||
|
"description": "ID of organization membership to delete",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
$ref: "#/components/schemas/MembershipOrg",
|
||||||
|
"description": "Deleted organization membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
const { membershipId } = req.params;
|
||||||
|
|
||||||
|
// delete organization membership
|
||||||
|
membership = await deleteMembershipOrg({
|
||||||
|
membershipOrgId: membershipId
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateSubscriptionOrgQuantity({
|
||||||
|
organizationId: membership.organization.toString()
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to delete organization membership'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
membership
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return workspaces for organization with id [organizationId] that user has
|
||||||
|
* access to
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
|
export const getOrganizationWorkspaces = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return projects in organization that user is part of'
|
||||||
|
#swagger.description = 'Return projects in organization that user is part of'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['organizationId'] = {
|
||||||
|
"description": "ID of organization",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspaces": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Project"
|
||||||
|
},
|
||||||
|
"description": "Projects of organization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let workspaces;
|
||||||
|
try {
|
||||||
|
const { organizationId } = req.params;
|
||||||
|
|
||||||
|
const workspacesSet = new Set(
|
||||||
|
(
|
||||||
|
await Workspace.find(
|
||||||
|
{
|
||||||
|
organization: organizationId
|
||||||
|
},
|
||||||
|
'_id'
|
||||||
|
)
|
||||||
|
).map((w) => w._id.toString())
|
||||||
|
);
|
||||||
|
|
||||||
|
workspaces = (
|
||||||
|
await Membership.find({
|
||||||
|
user: req.user._id
|
||||||
|
}).populate('workspace')
|
||||||
|
)
|
||||||
|
.filter((m) => workspacesSet.has(m.workspace._id.toString()))
|
||||||
|
.map((m) => m.workspace);
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to get organization workspaces'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
workspaces
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import {
|
import {
|
||||||
User
|
User,
|
||||||
|
MembershipOrg
|
||||||
} from '../../models';
|
} from '../../models';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current user.
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const getMe = async (req: Request, res: Response) => {
|
export const getMe = async (req: Request, res: Response) => {
|
||||||
/*
|
/*
|
||||||
#swagger.summary = "Retrieve the current user on the request"
|
#swagger.summary = "Retrieve the current user on the request"
|
||||||
@@ -39,11 +46,64 @@ export const getMe = async (req: Request, res: Response) => {
|
|||||||
Sentry.setUser({ email: req.user.email });
|
Sentry.setUser({ email: req.user.email });
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
return res.status(400).send({
|
return res.status(400).send({
|
||||||
message: 'Failed to get user'
|
message: 'Failed to get current user'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
user
|
user
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return organizations that the current user is part of.
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
|
export const getMyOrganizations = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Return organizations that current user is part of'
|
||||||
|
#swagger.description = 'Return organizations that current user is part of'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"organizations": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
$ref: "#/components/schemas/Organization"
|
||||||
|
},
|
||||||
|
"description": "Organizations that user is part of"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let organizations;
|
||||||
|
try {
|
||||||
|
organizations = (
|
||||||
|
await MembershipOrg.find({
|
||||||
|
user: req.user._id
|
||||||
|
}).populate('organization')
|
||||||
|
).map((m) => m.organization);
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: "Failed to get current user's organizations"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
organizations
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -311,76 +311,6 @@ export const getWorkspaceMemberships = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete workspace membership with id [membershipId]
|
|
||||||
* @param req
|
|
||||||
* @param res
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const deleteWorkspaceMembership = async (req: Request, res: Response) => {
|
|
||||||
/*
|
|
||||||
#swagger.summary = 'Delete project membership'
|
|
||||||
#swagger.description = 'Delete project membership'
|
|
||||||
|
|
||||||
#swagger.security = [{
|
|
||||||
"apiKeyAuth": []
|
|
||||||
}]
|
|
||||||
|
|
||||||
#swagger.parameters['workspaceId'] = {
|
|
||||||
"description": "ID of project",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
|
|
||||||
#swagger.parameters['membershipId'] = {
|
|
||||||
"description": "ID of membership",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
|
|
||||||
#swagger.responses[200] = {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"membership": {
|
|
||||||
$ref: "#/components/schemas/Membership",
|
|
||||||
"description": "Deleted membership"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
let membership;
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
membershipId
|
|
||||||
} = req.params;
|
|
||||||
|
|
||||||
membership = await Membership.findByIdAndDelete(membershipId);
|
|
||||||
|
|
||||||
if (!membership) throw new Error('Failed to delete workspace membership');
|
|
||||||
|
|
||||||
await Key.deleteMany({
|
|
||||||
receiver: membership.user,
|
|
||||||
workspace: membership.workspace
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
Sentry.setUser({ email: req.user.email });
|
|
||||||
Sentry.captureException(err);
|
|
||||||
return res.status(400).send({
|
|
||||||
message: 'Failed to delete workspace membership'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(200).send({
|
|
||||||
membership
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update role of membership with id [membershipId] to role [role]
|
* Update role of membership with id [membershipId] to role [role]
|
||||||
* @param req
|
* @param req
|
||||||
@@ -403,7 +333,7 @@ export const updateWorkspaceMembership = async (req: Request, res: Response) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#swagger.parameters['membershipId'] = {
|
#swagger.parameters['membershipId'] = {
|
||||||
"description": "ID of membership",
|
"description": "ID of project membership to update",
|
||||||
"required": true,
|
"required": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -467,4 +397,74 @@ export const updateWorkspaceMembership = async (req: Request, res: Response) =>
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
membership
|
membership
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete workspace membership with id [membershipId]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const deleteWorkspaceMembership = async (req: Request, res: Response) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Delete project membership'
|
||||||
|
#swagger.description = 'Delete project membership'
|
||||||
|
|
||||||
|
#swagger.security = [{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}]
|
||||||
|
|
||||||
|
#swagger.parameters['workspaceId'] = {
|
||||||
|
"description": "ID of project",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.parameters['membershipId'] = {
|
||||||
|
"description": "ID of project membership to delete",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
#swagger.responses[200] = {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"membership": {
|
||||||
|
$ref: "#/components/schemas/Membership",
|
||||||
|
"description": "Deleted membership"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
membershipId
|
||||||
|
} = req.params;
|
||||||
|
|
||||||
|
membership = await Membership.findByIdAndDelete(membershipId);
|
||||||
|
|
||||||
|
if (!membership) throw new Error('Failed to delete workspace membership');
|
||||||
|
|
||||||
|
await Key.deleteMany({
|
||||||
|
receiver: membership.user,
|
||||||
|
workspace: membership.workspace
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to delete workspace membership'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
membership
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import { Membership, Key } from '../models';
|
|||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String} obj.userId - id of user to validate
|
* @param {String} obj.userId - id of user to validate
|
||||||
* @param {String} obj.workspaceId - id of workspace
|
* @param {String} obj.workspaceId - id of workspace
|
||||||
|
* @returns {Membership} membership - membership of user with id [userId] for workspace with id [workspaceId]
|
||||||
*/
|
*/
|
||||||
const validateMembership = async ({
|
const validateMembership = async ({
|
||||||
userId,
|
userId,
|
||||||
|
|||||||
@@ -1,6 +1,42 @@
|
|||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
|
import { Types } from 'mongoose';
|
||||||
import { MembershipOrg, Workspace, Membership, Key } from '../models';
|
import { MembershipOrg, Workspace, Membership, Key } from '../models';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that user with id [userId] is a member of organization with id [organizationId]
|
||||||
|
* and has at least one of the roles in [acceptedRoles]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const validateMembership = async ({
|
||||||
|
userId,
|
||||||
|
organizationId,
|
||||||
|
acceptedRoles
|
||||||
|
}: {
|
||||||
|
userId: string;
|
||||||
|
organizationId: string;
|
||||||
|
acceptedRoles: string[];
|
||||||
|
}) => {
|
||||||
|
let membership;
|
||||||
|
try {
|
||||||
|
membership = await MembershipOrg.findOne({
|
||||||
|
user: new Types.ObjectId(userId),
|
||||||
|
organization: new Types.ObjectId(organizationId)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!membership) throw new Error('Failed to find organization membership');
|
||||||
|
|
||||||
|
if (!acceptedRoles.includes(membership.role)) {
|
||||||
|
throw new Error('Failed to validate organization membership role');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser(null);
|
||||||
|
Sentry.captureException(err);
|
||||||
|
throw new Error('Failed to validate organization membership');
|
||||||
|
}
|
||||||
|
|
||||||
|
return membership;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return organization membership matching criteria specified in
|
* Return organization membership matching criteria specified in
|
||||||
* query [queryObj]
|
* query [queryObj]
|
||||||
@@ -84,6 +120,8 @@ const deleteMembershipOrg = async ({
|
|||||||
_id: membershipOrgId
|
_id: membershipOrgId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!deletedMembershipOrg) throw new Error('Failed to delete organization membership');
|
||||||
|
|
||||||
// delete keys associated with organization membership
|
// delete keys associated with organization membership
|
||||||
if (deletedMembershipOrg?.user) {
|
if (deletedMembershipOrg?.user) {
|
||||||
// case: organization membership had a registered user
|
// case: organization membership had a registered user
|
||||||
@@ -117,4 +155,9 @@ const deleteMembershipOrg = async ({
|
|||||||
return deletedMembershipOrg;
|
return deletedMembershipOrg;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { findMembershipOrg, addMembershipsOrg, deleteMembershipOrg };
|
export {
|
||||||
|
validateMembership,
|
||||||
|
findMembershipOrg,
|
||||||
|
addMembershipsOrg,
|
||||||
|
deleteMembershipOrg
|
||||||
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import requireBotAuth from './requireBotAuth';
|
|||||||
import requireSignupAuth from './requireSignupAuth';
|
import requireSignupAuth from './requireSignupAuth';
|
||||||
import requireWorkspaceAuth from './requireWorkspaceAuth';
|
import requireWorkspaceAuth from './requireWorkspaceAuth';
|
||||||
import requireMembershipAuth from './requireMembershipAuth';
|
import requireMembershipAuth from './requireMembershipAuth';
|
||||||
|
import requireMembershipOrgAuth from './requireMembershipOrgAuth';
|
||||||
import requireOrganizationAuth from './requireOrganizationAuth';
|
import requireOrganizationAuth from './requireOrganizationAuth';
|
||||||
import requireIntegrationAuth from './requireIntegrationAuth';
|
import requireIntegrationAuth from './requireIntegrationAuth';
|
||||||
import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizationAuth';
|
import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizationAuth';
|
||||||
@@ -18,6 +19,7 @@ export {
|
|||||||
requireSignupAuth,
|
requireSignupAuth,
|
||||||
requireWorkspaceAuth,
|
requireWorkspaceAuth,
|
||||||
requireMembershipAuth,
|
requireMembershipAuth,
|
||||||
|
requireMembershipOrgAuth,
|
||||||
requireOrganizationAuth,
|
requireOrganizationAuth,
|
||||||
requireIntegrationAuth,
|
requireIntegrationAuth,
|
||||||
requireIntegrationAuthorizationAuth,
|
requireIntegrationAuthorizationAuth,
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import {
|
|||||||
import { validateMembership } from '../helpers/membership';
|
import { validateMembership } from '../helpers/membership';
|
||||||
|
|
||||||
type req = 'params' | 'body' | 'query';
|
type req = 'params' | 'body' | 'query';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate membership with id [membershipId] and that user with id
|
* Validate membership with id [membershipId] and that user with id
|
||||||
* [req.user._id] can modify that membership.
|
* [req.user._id] can modify that membership.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles for JWT auth
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
||||||
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
||||||
*/
|
*/
|
||||||
const requireMembershipAuth = ({
|
const requireMembershipAuth = ({
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import { UnauthorizedRequestError } from '../utils/errors';
|
||||||
|
import {
|
||||||
|
MembershipOrg
|
||||||
|
} from '../models';
|
||||||
|
import { validateMembership } from '../helpers/membershipOrg';
|
||||||
|
|
||||||
|
|
||||||
|
type req = 'params' | 'body' | 'query';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate (organization) membership id [membershipId] and that user with id
|
||||||
|
* [req.user._id] can modify that membership.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @param {String[]} obj.acceptedRoles - accepted organization roles
|
||||||
|
* @param {String[]} obj.location - location of [membershipId] on request (e.g. params, body) for parsing
|
||||||
|
*/
|
||||||
|
const requireMembershipOrgAuth = ({
|
||||||
|
acceptedRoles,
|
||||||
|
location = 'params'
|
||||||
|
}: {
|
||||||
|
acceptedRoles: string[];
|
||||||
|
location?: req;
|
||||||
|
}) => {
|
||||||
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const { membershipId } = req[location];
|
||||||
|
const membershipOrg = await MembershipOrg.findById(membershipId);
|
||||||
|
|
||||||
|
if (!membershipOrg) throw new Error('Failed to find target organization membership');
|
||||||
|
|
||||||
|
const targetMembership = await validateMembership({
|
||||||
|
userId: req.user._id.toString(),
|
||||||
|
organizationId: membershipOrg.organization.toString(),
|
||||||
|
acceptedRoles
|
||||||
|
});
|
||||||
|
|
||||||
|
req.targetMembership = targetMembership;
|
||||||
|
|
||||||
|
return next();
|
||||||
|
} catch (err) {
|
||||||
|
return next(UnauthorizedRequestError({
|
||||||
|
message: 'Unable to validate organization membership'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default requireMembershipOrgAuth;
|
||||||
@@ -4,6 +4,8 @@ import { body, param } from 'express-validator';
|
|||||||
import { requireAuth, validateRequest } from '../../middleware';
|
import { requireAuth, validateRequest } from '../../middleware';
|
||||||
import { membershipController } from '../../controllers/v1';
|
import { membershipController } from '../../controllers/v1';
|
||||||
|
|
||||||
|
// note: ALL DEPRECIATED (moved to api/v2/workspace/:workspaceId/memberships/:membershipId)
|
||||||
|
|
||||||
router.get( // used for old CLI (deprecate)
|
router.get( // used for old CLI (deprecate)
|
||||||
'/:workspaceId/connect',
|
'/:workspaceId/connect',
|
||||||
requireAuth({
|
requireAuth({
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import { OWNER, ADMIN, MEMBER, ACCEPTED } from '../../variables';
|
import { OWNER, ADMIN, MEMBER, ACCEPTED } from '../../variables';
|
||||||
import { organizationController } from '../../controllers/v1';
|
import { organizationController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get(
|
router.get( // deprecated (moved to api/v2/users/me/organizations)
|
||||||
'/',
|
'/',
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
@@ -41,7 +41,7 @@ router.get(
|
|||||||
organizationController.getOrganization
|
organizationController.getOrganization
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get( // deprecated (moved to api/v2/organizations/:organizationId/memberships)
|
||||||
'/:organizationId/users',
|
'/:organizationId/users',
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
@@ -56,7 +56,7 @@ router.get(
|
|||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:organizationId/my-workspaces',
|
'/:organizationId/my-workspaces', // deprecated (moved to api/v2/organizations/:organizationId/workspaces)
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import users from './users';
|
import users from './users';
|
||||||
import secret from './secret'; // stop-supporting
|
import organizations from './organizations';
|
||||||
import secrets from './secrets';
|
|
||||||
import workspace from './workspace';
|
import workspace from './workspace';
|
||||||
|
import secret from './secret'; // deprecated
|
||||||
|
import secrets from './secrets';
|
||||||
import serviceTokenData from './serviceTokenData';
|
import serviceTokenData from './serviceTokenData';
|
||||||
import apiKeyData from './apiKeyData';
|
import apiKeyData from './apiKeyData';
|
||||||
import environment from "./environment"
|
import environment from "./environment"
|
||||||
|
|
||||||
export {
|
export {
|
||||||
users,
|
users,
|
||||||
|
organizations,
|
||||||
|
workspace,
|
||||||
secret,
|
secret,
|
||||||
secrets,
|
secrets,
|
||||||
workspace,
|
|
||||||
serviceTokenData,
|
serviceTokenData,
|
||||||
apiKeyData,
|
apiKeyData,
|
||||||
environment
|
environment
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import express from 'express';
|
||||||
|
const router = express.Router();
|
||||||
|
import {
|
||||||
|
requireAuth,
|
||||||
|
requireOrganizationAuth,
|
||||||
|
requireMembershipOrgAuth,
|
||||||
|
validateRequest
|
||||||
|
} from '../../middleware';
|
||||||
|
import { body, param, query } from 'express-validator';
|
||||||
|
import { OWNER, ADMIN, MEMBER, ACCEPTED } from '../../variables';
|
||||||
|
import { organizationsController } from '../../controllers/v2';
|
||||||
|
|
||||||
|
// TODO: /POST to create membership
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/:organizationId/memberships',
|
||||||
|
param('organizationId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
requireOrganizationAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||||
|
acceptedStatuses: [ACCEPTED]
|
||||||
|
}),
|
||||||
|
organizationsController.getOrganizationMemberships
|
||||||
|
);
|
||||||
|
|
||||||
|
router.patch(
|
||||||
|
'/:organizationId/memberships/:membershipId',
|
||||||
|
param('organizationId').exists().trim(),
|
||||||
|
param('membershipId').exists().trim(),
|
||||||
|
body('role').exists().isString().trim().isIn([ADMIN, MEMBER]),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
requireOrganizationAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN],
|
||||||
|
acceptedStatuses: [ACCEPTED]
|
||||||
|
}),
|
||||||
|
requireMembershipOrgAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN]
|
||||||
|
}),
|
||||||
|
organizationsController.updateOrganizationMembership
|
||||||
|
);
|
||||||
|
|
||||||
|
router.delete(
|
||||||
|
'/:organizationId/memberships/:membershipId',
|
||||||
|
param('organizationId').exists().trim(),
|
||||||
|
param('membershipId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
requireOrganizationAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN],
|
||||||
|
acceptedStatuses: [ACCEPTED]
|
||||||
|
}),
|
||||||
|
requireMembershipOrgAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN]
|
||||||
|
}),
|
||||||
|
organizationsController.deleteOrganizationMembership
|
||||||
|
);
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/:organizationId/workspaces',
|
||||||
|
param('organizationId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
requireOrganizationAuth({
|
||||||
|
acceptedRoles: [OWNER, ADMIN],
|
||||||
|
acceptedStatuses: [ACCEPTED]
|
||||||
|
}),
|
||||||
|
organizationsController.getOrganizationWorkspaces
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -10,7 +10,7 @@ import { ADMIN, MEMBER } from '../../variables';
|
|||||||
import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret';
|
import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret';
|
||||||
import { secretController } from '../../controllers/v2';
|
import { secretController } from '../../controllers/v2';
|
||||||
|
|
||||||
// note to devs: stop supporting
|
// note to devs: stop supporting these routes [deprecated]
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
|||||||
@@ -13,4 +13,12 @@ router.get(
|
|||||||
usersController.getMe
|
usersController.getMe
|
||||||
);
|
);
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/me/organizations',
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
usersController.getMyOrganizations
|
||||||
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
@@ -83,23 +83,6 @@ router.get( // new - TODO: rewire dashboard to this route
|
|||||||
workspaceController.getWorkspaceMemberships
|
workspaceController.getWorkspaceMemberships
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete( // TODO - rewire dashboard to this route
|
|
||||||
'/:workspaceId/memberships/:membershipId',
|
|
||||||
param('workspaceId').exists().trim(),
|
|
||||||
param('membershipId').exists().trim(),
|
|
||||||
validateRequest,
|
|
||||||
requireAuth({
|
|
||||||
acceptedAuthModes: ['jwt', 'apiKey']
|
|
||||||
}),
|
|
||||||
requireWorkspaceAuth({
|
|
||||||
acceptedRoles: [ADMIN],
|
|
||||||
}),
|
|
||||||
requireMembershipAuth({
|
|
||||||
acceptedRoles: [ADMIN]
|
|
||||||
}),
|
|
||||||
workspaceController.deleteWorkspaceMembership
|
|
||||||
);
|
|
||||||
|
|
||||||
router.patch( // TODO - rewire dashboard to this route
|
router.patch( // TODO - rewire dashboard to this route
|
||||||
'/:workspaceId/memberships/:membershipId',
|
'/:workspaceId/memberships/:membershipId',
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
@@ -118,4 +101,21 @@ router.patch( // TODO - rewire dashboard to this route
|
|||||||
workspaceController.updateWorkspaceMembership
|
workspaceController.updateWorkspaceMembership
|
||||||
);
|
);
|
||||||
|
|
||||||
|
router.delete( // TODO - rewire dashboard to this route
|
||||||
|
'/:workspaceId/memberships/:membershipId',
|
||||||
|
param('workspaceId').exists().trim(),
|
||||||
|
param('membershipId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
|
}),
|
||||||
|
requireWorkspaceAuth({
|
||||||
|
acceptedRoles: [ADMIN],
|
||||||
|
}),
|
||||||
|
requireMembershipAuth({
|
||||||
|
acceptedRoles: [ADMIN]
|
||||||
|
}),
|
||||||
|
workspaceController.deleteWorkspaceMembership
|
||||||
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -66,6 +66,33 @@ const generateOpenAPISpec = async () => {
|
|||||||
workspace: '',
|
workspace: '',
|
||||||
role: 'admin'
|
role: 'admin'
|
||||||
},
|
},
|
||||||
|
MembershipOrg: {
|
||||||
|
user: {
|
||||||
|
_id: '',
|
||||||
|
email: '',
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
publicKey: '',
|
||||||
|
updatedAt: '',
|
||||||
|
createdAt: ''
|
||||||
|
},
|
||||||
|
organization: '',
|
||||||
|
role: 'owner',
|
||||||
|
status: 'accepted'
|
||||||
|
},
|
||||||
|
Organization: {
|
||||||
|
_id: '',
|
||||||
|
name: '',
|
||||||
|
customerId: ''
|
||||||
|
},
|
||||||
|
Project: {
|
||||||
|
name: 'My Project',
|
||||||
|
organization: '',
|
||||||
|
environments: [{
|
||||||
|
name: 'development',
|
||||||
|
slug: 'dev'
|
||||||
|
}]
|
||||||
|
},
|
||||||
ProjectKey: {
|
ProjectKey: {
|
||||||
encryptedkey: '',
|
encryptedkey: '',
|
||||||
nonce: '',
|
nonce: '',
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Delete Membership"
|
||||||
|
openapi: "DELETE /api/v2/organizations/{organizationId}/memberships/{membershipId}"
|
||||||
|
---
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Get Memberships"
|
||||||
|
openapi: "GET /api/v2/organizations/{organizationId}/memberships"
|
||||||
|
---
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Update Membership"
|
||||||
|
openapi: "PATCH /api/v2/organizations/{organizationId}/memberships/{membershipId}"
|
||||||
|
---
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Get Projects"
|
||||||
|
openapi: "GET /api/v2/organizations/{organizationId}/workspaces"
|
||||||
|
---
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Get Current User"
|
title: "Get My User"
|
||||||
openapi: "GET /api/v2/users/me"
|
openapi: "GET /api/v2/users/me"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Get My Organizations"
|
||||||
|
openapi: "GET /api/v2/users/me/organizations"
|
||||||
|
---
|
||||||
+11
-1
@@ -162,7 +162,17 @@
|
|||||||
{
|
{
|
||||||
"group": "Users",
|
"group": "Users",
|
||||||
"pages": [
|
"pages": [
|
||||||
"api-reference/endpoints/users/me"
|
"api-reference/endpoints/users/me",
|
||||||
|
"api-reference/endpoints/users/my-organizations"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "Organizations",
|
||||||
|
"pages": [
|
||||||
|
"api-reference/endpoints/organizations/memberships",
|
||||||
|
"api-reference/endpoints/organizations/update-membership",
|
||||||
|
"api-reference/endpoints/organizations/delete-membership",
|
||||||
|
"api-reference/endpoints/organizations/workspaces"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+325
-34
@@ -1392,6 +1392,229 @@ paths:
|
|||||||
description: Bad Request
|
description: Bad Request
|
||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- apiKeyAuth: []
|
||||||
|
/api/v2/users/me/organizations:
|
||||||
|
get:
|
||||||
|
summary: Return organizations that current user is part of
|
||||||
|
description: Return organizations that current user is part of
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
organizations:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Organization'
|
||||||
|
description: Organizations that user is part of
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
/api/v2/organizations/{organizationId}/memberships:
|
||||||
|
get:
|
||||||
|
summary: Return organization memberships
|
||||||
|
description: Return organization memberships
|
||||||
|
parameters:
|
||||||
|
- name: organizationId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
memberships:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/MembershipOrg'
|
||||||
|
description: Memberships of organization
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
/api/v2/organizations/{organizationId}/memberships/{membershipId}:
|
||||||
|
patch:
|
||||||
|
summary: Update organization membership
|
||||||
|
description: Update organization membership
|
||||||
|
parameters:
|
||||||
|
- name: organizationId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization
|
||||||
|
- name: membershipId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization membership to update
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
$ref: '#/components/schemas/MembershipOrg'
|
||||||
|
description: Updated organization membership
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
role:
|
||||||
|
type: string
|
||||||
|
description: >-
|
||||||
|
Role of organization membership - either owner, admin, or
|
||||||
|
member
|
||||||
|
delete:
|
||||||
|
summary: Delete organization membership
|
||||||
|
description: Delete organization membership
|
||||||
|
parameters:
|
||||||
|
- name: organizationId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization
|
||||||
|
- name: membershipId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization membership to delete
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
$ref: '#/components/schemas/MembershipOrg'
|
||||||
|
description: Deleted organization membership
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
/api/v2/organizations/{organizationId}/workspaces:
|
||||||
|
get:
|
||||||
|
summary: Return projects in organization that user is part of
|
||||||
|
description: Return projects in organization that user is part of
|
||||||
|
parameters:
|
||||||
|
- name: organizationId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of organization
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
workspaces:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Project'
|
||||||
|
description: Projects of organization
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
|
/api/v2/workspace/{workspaceId}/environments:
|
||||||
|
post:
|
||||||
|
description: ''
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
environmentName:
|
||||||
|
example: any
|
||||||
|
environmentSlug:
|
||||||
|
example: any
|
||||||
|
put:
|
||||||
|
description: ''
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
environmentName:
|
||||||
|
example: any
|
||||||
|
environmentSlug:
|
||||||
|
example: any
|
||||||
|
oldEnvironmentSlug:
|
||||||
|
example: any
|
||||||
|
delete:
|
||||||
|
description: ''
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
environmentSlug:
|
||||||
|
example: any
|
||||||
/api/v2/workspace/{workspaceId}/secrets:
|
/api/v2/workspace/{workspaceId}/secrets:
|
||||||
post:
|
post:
|
||||||
description: ''
|
description: ''
|
||||||
@@ -1509,37 +1732,6 @@ paths:
|
|||||||
security:
|
security:
|
||||||
- apiKeyAuth: []
|
- apiKeyAuth: []
|
||||||
/api/v2/workspace/{workspaceId}/memberships/{membershipId}:
|
/api/v2/workspace/{workspaceId}/memberships/{membershipId}:
|
||||||
delete:
|
|
||||||
summary: Delete project membership
|
|
||||||
description: Delete project membership
|
|
||||||
parameters:
|
|
||||||
- name: workspaceId
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
description: ID of project
|
|
||||||
- name: membershipId
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
description: ID of membership
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
membership:
|
|
||||||
$ref: '#/components/schemas/Membership'
|
|
||||||
description: Deleted membership
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
security:
|
|
||||||
- apiKeyAuth: []
|
|
||||||
patch:
|
patch:
|
||||||
summary: Update project membership
|
summary: Update project membership
|
||||||
description: Update project membership
|
description: Update project membership
|
||||||
@@ -1555,7 +1747,7 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
description: ID of membership
|
description: ID of project membership to update
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
@@ -1581,6 +1773,37 @@ paths:
|
|||||||
role:
|
role:
|
||||||
type: string
|
type: string
|
||||||
description: Role of membership - either admin or member
|
description: Role of membership - either admin or member
|
||||||
|
delete:
|
||||||
|
summary: Delete project membership
|
||||||
|
description: Delete project membership
|
||||||
|
parameters:
|
||||||
|
- name: workspaceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of project
|
||||||
|
- name: membershipId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
description: ID of project membership to delete
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
$ref: '#/components/schemas/Membership'
|
||||||
|
description: Deleted membership
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
security:
|
||||||
|
- apiKeyAuth: []
|
||||||
/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}:
|
/api/v2/secret/batch-create/workspace/{workspaceId}/environment/{environment}:
|
||||||
post:
|
post:
|
||||||
description: ''
|
description: ''
|
||||||
@@ -1927,7 +2150,7 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
'400':
|
'400':
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
/api/v2/api-key-data/:
|
/api/v2/api-key/:
|
||||||
get:
|
get:
|
||||||
description: ''
|
description: ''
|
||||||
parameters: []
|
parameters: []
|
||||||
@@ -1954,7 +2177,7 @@ paths:
|
|||||||
example: any
|
example: any
|
||||||
expiresIn:
|
expiresIn:
|
||||||
example: any
|
example: any
|
||||||
/api/v2/api-key-data/{apiKeyDataId}:
|
/api/v2/api-key/{apiKeyDataId}:
|
||||||
delete:
|
delete:
|
||||||
description: ''
|
description: ''
|
||||||
parameters:
|
parameters:
|
||||||
@@ -2043,6 +2266,74 @@ components:
|
|||||||
role:
|
role:
|
||||||
type: string
|
type: string
|
||||||
example: admin
|
example: admin
|
||||||
|
MembershipOrg:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
publicKey:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
organization:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
role:
|
||||||
|
type: string
|
||||||
|
example: owner
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: accepted
|
||||||
|
Organization:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
_id:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
customerId:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
Project:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: My Project
|
||||||
|
organization:
|
||||||
|
type: string
|
||||||
|
example: ''
|
||||||
|
environments:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: development
|
||||||
|
slug:
|
||||||
|
type: string
|
||||||
|
example: dev
|
||||||
ProjectKey:
|
ProjectKey:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
Reference in New Issue
Block a user