Files
optima/API_ROUTES.md
T
2026-02-15 16:38:04 -06:00

16 KiB

TTSCM API Routes Documentation

This document provides a comprehensive overview of all API routes available in the TTSCM API.

Base URL

http://localhost:3000/v1

Authentication Routes

Get Authentication URI

GET /auth/uri

Get the Microsoft OAuth authentication URI for user login.

Authentication Required: No

Response:

{
  "status": 200,
  "message": "Successfully fetch Auth URI",
  "data": {
    "uri": "https://login.microsoftonline.com/...",
    "callbackKey": "ck123..."
  },
  "successful": true
}

OAuth Redirect Handler

GET /auth/redirect

Handles the OAuth redirect callback from Microsoft. This endpoint processes the authorization code and creates a user session.

Authentication Required: No

Query Parameters:

  • code - Authorization code from Microsoft
  • state - Callback key for WebSocket notification

Response: Closes the browser window and emits authentication tokens via WebSocket.


Refresh Access Token

POST /auth/refresh

Refresh an expired access token using a valid refresh token.

Authentication Required: Yes (Refresh Token)

Headers:

  • x-refresh-token - The refresh token

Response:

{
  "status": 201,
  "message": "Token refreshed successfully!",
  "data": {
    "accessToken": "eyJhbGc...",
    "refreshToken": "eyJhbGc..."
  },
  "successful": true
}

User Routes

Get Current User

GET /user/@me

Fetch the currently authenticated user's information.

Authentication Required: Yes

Required Scopes: user.read

Response:

{
  "status": 200,
  "message": "Fetched user.",
  "data": {
    "id": "ckx...",
    "name": "John Doe",
    "email": "john.doe@example.com",
    "login": "john.doe",
    "image": "https://...",
    "roles": ["admin"],
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-02-14T00:00:00.000Z"
  },
  "successful": true
}

Update Current User

PATCH /user/@me

Update the currently authenticated user's information.

Authentication Required: Yes

Required Scopes: user.write

Request Body:

{
  "name": "Jane Doe",
  "image": "https://example.com/avatar.jpg"
}

Response:

{
  "status": 200,
  "message": "Successfully updated user.",
  "data": {
    "id": "ckx...",
    "name": "Jane Doe",
    "email": "jane.doe@example.com",
    "image": "https://example.com/avatar.jpg"
  },
  "successful": true
}

Company Routes

Get All Companies

GET /company/companies

Fetch a paginated list of all companies with optional search functionality.

Authentication Required: Yes

Required Permissions: company.fetch.many

Query Parameters:

  • page (optional) - Page number (default: 1)
  • rpp (optional) - Records per page (default: 30)
  • search (optional) - Search query to filter companies

Response:

{
  "status": 200,
  "message": "Companies Fetched Successfully!",
  "data": [
    {
      "id": "ckx...",
      "name": "Acme Corp",
      "cw_CompanyId": 12345,
      "cw_Identifier": "AcmeCorp"
    }
  ],
  "pagination": {
    "previousPage": null,
    "currentPage": 1,
    "nextPage": 2,
    "totalPages": 10,
    "totalRecords": 300,
    "listedRecords": 30
  },
  "successful": true
}

Get Company by ID

GET /company/companies/:identifier

Fetch a single company by its ID.

Authentication Required: Yes

Required Permissions: company.fetch

URL Parameters:

  • identifier - Company ID

Response:

{
  "status": 200,
  "message": "Company Fetched Successfully!",
  "data": {
    "id": "ckx...",
    "name": "Acme Corp",
    "cw_CompanyId": 12345,
    "cw_Identifier": "AcmeCorp"
  },
  "successful": true
}

Get Company Configurations

GET /company/companies/:identifier/configurations

Fetch configurations for a specific company from ConnectWise.

Authentication Required: Yes

Required Permissions: company.fetch, company.fetch.configurations

URL Parameters:

  • identifier - Company ID

Response:

{
  "status": 200,
  "message": "Company Configurations Fetched Successfully!",
  "data": {
    // ConnectWise configuration data
  },
  "successful": true
}

Credential Routes

Get Credential by ID

GET /credential/credentials/:id

Fetch a single credential by its ID.

Authentication Required: Yes

Required Permissions: credential.fetch

URL Parameters:

  • id - Credential ID

Response:

{
  "status": 200,
  "message": "Credential Fetched Successfully!",
  "data": {
    "id": "ckx...",
    "name": "AWS Credentials",
    "typeId": "cky...",
    "companyId": "ckz...",
    "fields": {
      "accountId": "123456789"
    },
    "type": {
      "id": "cky...",
      "name": "AWS",
      "fields": [...],
      "permissionScope": "aws.credentials"
    },
    "company": {
      "id": "ckz...",
      "name": "Acme Corp"
    },
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-02-14T00:00:00.000Z"
  },
  "successful": true
}

Get Credentials by Company

GET /credential/credentials/company/:companyId

Fetch all credentials associated with a specific company.

Authentication Required: Yes

Required Permissions: credential.fetch.many

URL Parameters:

  • companyId - Company ID

Response:

{
  "status": 200,
  "message": "Company Credentials Fetched Successfully!",
  "data": [
    {
      "id": "ckx...",
      "name": "AWS Credentials",
      "typeId": "cky...",
      "companyId": "ckz...",
      "fields": {...},
      "type": {...},
      "company": {...}
    }
  ],
  "successful": true
}

Create Credential

POST /credential/credentials

Create a new credential with validated and encrypted fields.

Authentication Required: Yes

Required Permissions: credential.create

Request Body:

{
  "name": "Production AWS Credentials",
  "typeId": "cky...",
  "companyId": "ckz...",
  "fields": [
    {
      "id": "ckx1...",
      "fieldId": "accessKeyId",
      "value": "AKIAIOSFODNN7EXAMPLE"
    },
    {
      "id": "ckx2...",
      "fieldId": "secretAccessKey",
      "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    }
  ]
}

Response:

{
  "status": 201,
  "message": "Credential Created Successfully!",
  "data": {
    "id": "ckx...",
    "name": "Production AWS Credentials",
    "typeId": "cky...",
    "companyId": "ckz...",
    "fields": {...}
  },
  "successful": true
}

Update Credential

PATCH /credential/credentials/:id

Update a credential's basic properties (name).

Authentication Required: Yes

Required Permissions: credential.update

URL Parameters:

  • id - Credential ID

Request Body:

{
  "name": "Updated Credential Name"
}

Response:

{
  "status": 200,
  "message": "Credential Updated Successfully!",
  "data": {
    "id": "ckx...",
    "name": "Updated Credential Name",
    ...
  },
  "successful": true
}

Update Credential Fields

PUT /credential/credentials/:id/fields

Validate and update credential field values. Secure fields are automatically encrypted.

Authentication Required: Yes

Required Permissions: credential.update, credential.fields.update

URL Parameters:

  • id - Credential ID

Request Body:

{
  "fields": [
    {
      "id": "ckx1...",
      "fieldId": "accessKeyId",
      "value": "AKIAIOSFODNN7NEWVALUE"
    },
    {
      "id": "ckx2...",
      "fieldId": "secretAccessKey",
      "value": "newSecretKeyValue123"
    }
  ]
}

Response:

{
  "status": 200,
  "message": "Credential Fields Updated Successfully!",
  "data": {
    "id": "ckx...",
    "name": "Production AWS Credentials",
    "fields": {...}
  },
  "successful": true
}

Get Credential Fields

GET /credential/credentials/:id/fields

Fetch all field values for a credential (secure fields returned encrypted).

Authentication Required: Yes

Required Permissions: credential.fetch, credential.fields.fetch

URL Parameters:

  • id - Credential ID

Response:

{
  "status": 200,
  "message": "Credential Fields Fetched Successfully!",
  "data": [
    {
      "id": "ckx-accessKeyId",
      "fieldId": "accessKeyId",
      "value": "AKIAIOSFODNN7EXAMPLE"
    },
    {
      "id": "ckx1...",
      "fieldId": "secretAccessKey",
      "value": "base64EncryptedValue=="
    }
  ],
  "successful": true
}

Read Secure Values

GET /credential/credentials/:id/secure-values

Decrypt and return all secure field values for a credential.

Authentication Required: Yes

Required Permissions: credential.fetch, credential.secure_values.read

URL Parameters:

  • id - Credential ID

Response:

{
  "status": 200,
  "message": "Secure Values Fetched Successfully!",
  "data": {
    "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "apiKey": "sk_live_123456789abcdef"
  },
  "successful": true
}

Delete Credential

DELETE /credential/credentials/:id

Delete a credential and all associated secure values.

Authentication Required: Yes

Required Permissions: credential.delete

URL Parameters:

  • id - Credential ID

Response:

{
  "status": 200,
  "message": "Credential Deleted Successfully!",
  "data": null,
  "successful": true
}

Credential Type Routes

Get Credential Type by ID or Name

GET /credential-type/:identifier

Fetch a single credential type by its ID or name.

Authentication Required: Yes

Required Permissions: credential_type.fetch

URL Parameters:

  • identifier - Credential Type ID or name

Response:

{
  "status": 200,
  "message": "Credential Type Fetched Successfully!",
  "data": {
    "id": "cky...",
    "name": "AWS",
    "permissionScope": "aws.credentials",
    "icon": "https://aws.amazon.com/favicon.ico",
    "fields": [
      {
        "id": "accessKeyId",
        "name": "Access Key ID",
        "required": true,
        "secure": false,
        "valueType": "plain_text"
      },
      {
        "id": "secretAccessKey",
        "name": "Secret Access Key",
        "required": true,
        "secure": true,
        "valueType": "password"
      }
    ],
    "credentialCount": 5,
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-02-14T00:00:00.000Z"
  },
  "successful": true
}

Get All Credential Types

GET /credential-type

Fetch all credential types in the system.

Authentication Required: Yes

Required Permissions: credential_type.fetch.many

Response:

{
  "status": 200,
  "message": "Credential Types Fetched Successfully!",
  "data": [
    {
      "id": "cky...",
      "name": "AWS",
      "permissionScope": "aws.credentials",
      "icon": "https://aws.amazon.com/favicon.ico",
      "fields": [...],
      "credentialCount": 5
    },
    {
      "id": "ckz...",
      "name": "Azure",
      "permissionScope": "azure.credentials",
      "icon": "https://azure.microsoft.com/favicon.ico",
      "fields": [...],
      "credentialCount": 3
    }
  ],
  "successful": true
}

Create Credential Type

POST /credential-type

Create a new credential type with field definitions.

Authentication Required: Yes

Required Permissions: credential_type.create

Request Body:

{
  "name": "GitHub",
  "permissionScope": "github.credentials",
  "icon": "https://github.com/favicon.ico",
  "fields": [
    {
      "id": "username",
      "name": "Username",
      "required": true,
      "secure": false,
      "valueType": "plain_text"
    },
    {
      "id": "personalAccessToken",
      "name": "Personal Access Token",
      "required": true,
      "secure": true,
      "valueType": "password"
    }
  ]
}

Response:

{
  "status": 201,
  "message": "Credential Type Created Successfully!",
  "data": {
    "id": "ck1...",
    "name": "GitHub",
    "permissionScope": "github.credentials",
    "icon": "https://github.com/favicon.ico",
    "fields": [...]
  },
  "successful": true
}

Update Credential Type

PATCH /credential-type/:id

Update a credential type's properties or field definitions.

Authentication Required: Yes

Required Permissions: credential_type.update

URL Parameters:

  • id - Credential Type ID

Request Body:

{
  "name": "GitHub Enterprise",
  "icon": "https://github.enterprise.com/favicon.ico",
  "fields": [
    {
      "id": "username",
      "name": "Username",
      "required": true,
      "secure": false,
      "valueType": "plain_text"
    },
    {
      "id": "personalAccessToken",
      "name": "Personal Access Token",
      "required": true,
      "secure": true,
      "valueType": "password"
    },
    {
      "id": "enterpriseUrl",
      "name": "Enterprise URL",
      "required": true,
      "secure": false,
      "valueType": "plain_text"
    }
  ]
}

Response:

{
  "status": 200,
  "message": "Credential Type Updated Successfully!",
  "data": {
    "id": "ck1...",
    "name": "GitHub Enterprise",
    "fields": [...]
  },
  "successful": true
}

Delete Credential Type

DELETE /credential-type/:id

Delete a credential type. This will cascade delete all credentials of this type.

Authentication Required: Yes

Required Permissions: credential_type.delete

URL Parameters:

  • id - Credential Type ID

Response:

{
  "status": 200,
  "message": "Credential Type Deleted Successfully!",
  "data": null,
  "successful": true
}

Get Credentials by Type

GET /credential-type/:id/credentials

Fetch all credentials that use a specific credential type.

Authentication Required: Yes

Required Permissions: credential_type.fetch, credential.fetch.many

URL Parameters:

  • id - Credential Type ID

Response:

{
  "status": 200,
  "message": "Credentials Fetched Successfully!",
  "data": [
    {
      "id": "ckx...",
      "name": "Production AWS",
      "typeId": "cky...",
      "companyId": "ckz...",
      "fields": {...}
    },
    {
      "id": "ck2...",
      "name": "Staging AWS",
      "typeId": "cky...",
      "companyId": "ckz...",
      "fields": {...}
    }
  ],
  "successful": true
}

Utility Routes

Teapot

GET /teapot

A fun Easter egg endpoint that returns HTTP 418 (I'm a teapot).

Authentication Required: No

Response:

{
  "status": 418,
  "message": "I'm a teapot",
  "successful": false
}

Error Responses

All endpoints may return error responses in the following format:

400 Bad Request

{
  "status": 400,
  "message": "Validation error",
  "errors": [
    {
      "path": ["field"],
      "message": "Field is required"
    }
  ],
  "successful": false
}

401 Unauthorized

{
  "status": 401,
  "message": "Unauthorized",
  "successful": false
}

403 Forbidden

{
  "status": 403,
  "message": "Insufficient permissions",
  "successful": false
}

404 Not Found

{
  "status": 404,
  "message": "Resource not found",
  "successful": false
}

500 Internal Server Error

{
  "status": 500,
  "message": "Internal server error",
  "successful": false
}

Authentication

Most endpoints require authentication via an access token in the request headers:

Authorization: Bearer <access_token>

Tokens are obtained through the Microsoft OAuth flow:

  1. Call GET /auth/uri to get the authentication URL
  2. Redirect user to the Microsoft login page
  3. User authenticates and is redirected to /auth/redirect
  4. Access and refresh tokens are provided via WebSocket or response
  5. Use the access token in subsequent API requests

When the access token expires, use POST /auth/refresh with the refresh token to obtain a new access token.


Permission System

The API uses a granular permission system. Each endpoint requires specific permissions that are checked via the authMiddleware. Permissions are granted through roles assigned to users.

Common permission patterns:

  • resource.fetch - Read a single resource
  • resource.fetch.many - Read multiple resources
  • resource.create - Create a new resource
  • resource.update - Update a resource
  • resource.delete - Delete a resource
  • resource.field.action - Perform specific field operations

Users can have multiple roles, and permissions are accumulated from all assigned roles.