CREDENTIAL TYPE MANAGEMENT WORKS
This commit is contained in:
+981
@@ -0,0 +1,981 @@
|
|||||||
|
# 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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Jane Doe",
|
||||||
|
"image": "https://example.com/avatar.jpg"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Production AWS Credentials",
|
||||||
|
"typeId": "cky...",
|
||||||
|
"companyId": "ckz...",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "ckx1...",
|
||||||
|
"fieldId": "accessKeyId",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ckx2...",
|
||||||
|
"fieldId": "secretAccessKey",
|
||||||
|
"value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Updated Credential Name"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "ckx1...",
|
||||||
|
"fieldId": "accessKeyId",
|
||||||
|
"value": "AKIAIOSFODNN7NEWVALUE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ckx2...",
|
||||||
|
"fieldId": "secretAccessKey",
|
||||||
|
"value": "newSecretKeyValue123"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Credential Deleted Successfully!",
|
||||||
|
"data": null,
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Credential Type Routes
|
||||||
|
|
||||||
|
### Get Credential Type by ID or Name
|
||||||
|
|
||||||
|
**GET** `/credential-type/credential-types/: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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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/credential-types`
|
||||||
|
|
||||||
|
Fetch all credential types in the system.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `credential_type.fetch.many`
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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/credential-types`
|
||||||
|
|
||||||
|
Create a new credential type with field definitions.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `credential_type.create`
|
||||||
|
|
||||||
|
**Request Body:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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/credential-types/: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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Credential Type Updated Successfully!",
|
||||||
|
"data": {
|
||||||
|
"id": "ck1...",
|
||||||
|
"name": "GitHub Enterprise",
|
||||||
|
"fields": [...]
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Delete Credential Type
|
||||||
|
|
||||||
|
**DELETE** `/credential-type/credential-types/: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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Credential Type Deleted Successfully!",
|
||||||
|
"data": null,
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Get Credentials by Type
|
||||||
|
|
||||||
|
**GET** `/credential-type/credential-types/: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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 418,
|
||||||
|
"message": "I'm a teapot",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Responses
|
||||||
|
|
||||||
|
All endpoints may return error responses in the following format:
|
||||||
|
|
||||||
|
### 400 Bad Request
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 400,
|
||||||
|
"message": "Validation error",
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"path": ["field"],
|
||||||
|
"message": "Field is required"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 401 Unauthorized
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 401,
|
||||||
|
"message": "Unauthorized",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 403 Forbidden
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 403,
|
||||||
|
"message": "Insufficient permissions",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 404 Not Found
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 404,
|
||||||
|
"message": "Resource not found",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 500 Internal Server Error
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"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.
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
"@prisma/client": "^7.3.0",
|
"@prisma/client": "^7.3.0",
|
||||||
"@socket.io/bun-engine": "^0.1.0",
|
"@socket.io/bun-engine": "^0.1.0",
|
||||||
"axios": "^1.13.3",
|
"axios": "^1.13.3",
|
||||||
|
"blakets": "^0.1.12",
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"cuid": "^3.0.0",
|
"cuid": "^3.0.0",
|
||||||
"hono": "^4.11.5",
|
"hono": "^4.11.5",
|
||||||
@@ -84,6 +85,8 @@
|
|||||||
|
|
||||||
"@prisma/studio-core": ["@prisma/studio-core@0.13.1", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-agdqaPEePRHcQ7CexEfkX1RvSH9uWDb6pXrZnhCRykhDFAV0/0P3d07WtfiY8hZWb7oRU4v+NkT4cGFHkQJIPg=="],
|
"@prisma/studio-core": ["@prisma/studio-core@0.13.1", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-agdqaPEePRHcQ7CexEfkX1RvSH9uWDb6pXrZnhCRykhDFAV0/0P3d07WtfiY8hZWb7oRU4v+NkT4cGFHkQJIPg=="],
|
||||||
|
|
||||||
|
"@prokopschield/argv": ["@prokopschield/argv@0.1.3", "", { "bin": { "argv": "lib/cli.js" } }, "sha512-4/yMUKdaFIKBUOOu5+qhC2kMuAECk7FaKamo5NSu4iAzuw36hj6E3UY3CYVKXPnA5dldwiwW60Ss5Ss5QdxVCw=="],
|
||||||
|
|
||||||
"@socket.io/bun-engine": ["@socket.io/bun-engine@0.1.0", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-B1z6GuAxZlfvjgaa3BHZBOfqHJNfnpebTw15p+Un1HuBL4YM7wUxO9sJa7K4NDTe7XbUBeqLIwTDA5tOOjffog=="],
|
"@socket.io/bun-engine": ["@socket.io/bun-engine@0.1.0", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-B1z6GuAxZlfvjgaa3BHZBOfqHJNfnpebTw15p+Un1HuBL4YM7wUxO9sJa7K4NDTe7XbUBeqLIwTDA5tOOjffog=="],
|
||||||
|
|
||||||
"@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="],
|
"@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="],
|
||||||
@@ -112,6 +115,8 @@
|
|||||||
|
|
||||||
"base64id": ["base64id@2.0.0", "", {}, "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="],
|
"base64id": ["base64id@2.0.0", "", {}, "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="],
|
||||||
|
|
||||||
|
"blakets": ["blakets@0.1.12", "", { "dependencies": { "@prokopschield/argv": "^0.1.0-2" }, "bin": { "blake": "lib/demo.js", "blake2b": "lib/cli.js", "blake2s": "lib/cli.js", "blakejs": "lib/demo.js", "blakets": "lib/demo.js" } }, "sha512-ReOnLTDRlbExlTXbJZoA2xkvhzauJ7ldpvhKnb1cUNw8gdAHWHWOWG8XMjwpxQmmEZCDAR7VZiM5BYTUSOLVrw=="],
|
||||||
|
|
||||||
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
|
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
|
||||||
|
|||||||
@@ -37,3 +37,18 @@ export type Role = Prisma.RoleModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Company = Prisma.CompanyModel
|
export type Company = Prisma.CompanyModel
|
||||||
|
/**
|
||||||
|
* Model CredentialType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type CredentialType = Prisma.CredentialTypeModel
|
||||||
|
/**
|
||||||
|
* Model SecureValue
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type SecureValue = Prisma.SecureValueModel
|
||||||
|
/**
|
||||||
|
* Model Credential
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Credential = Prisma.CredentialModel
|
||||||
|
|||||||
@@ -59,3 +59,18 @@ export type Role = Prisma.RoleModel
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type Company = Prisma.CompanyModel
|
export type Company = Prisma.CompanyModel
|
||||||
|
/**
|
||||||
|
* Model CredentialType
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type CredentialType = Prisma.CredentialTypeModel
|
||||||
|
/**
|
||||||
|
* Model SecureValue
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type SecureValue = Prisma.SecureValueModel
|
||||||
|
/**
|
||||||
|
* Model Credential
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Credential = Prisma.CredentialModel
|
||||||
|
|||||||
@@ -175,6 +175,57 @@ export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
|||||||
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type JsonFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonWithAggregatesFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonWithAggregatesFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
export type NestedStringFilter<$PrismaModel = never> = {
|
export type NestedStringFilter<$PrismaModel = never> = {
|
||||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
@@ -349,4 +400,28 @@ export type NestedFloatFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NestedJsonFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<NestedJsonFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<NestedJsonFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type NestedJsonFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = {
|
|||||||
"clientVersion": "7.3.0",
|
"clientVersion": "7.3.0",
|
||||||
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
||||||
"activeProvider": "postgresql",
|
"activeProvider": "postgresql",
|
||||||
"inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Company {\n id String @id @default(cuid())\n name String\n\n cw_CompanyId Int @unique\n cw_Identifier String @unique\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
|
"inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Session {\n id String @id @default(uuid())\n sessionKey String @unique @default(cuid())\n userId String\n expires DateTime\n refreshTokenGenerated Boolean @default(false)\n refreshedAt DateTime?\n invalidatedAt DateTime?\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel User {\n id String @id @default(cuid())\n roles Role[]\n permissions String?\n login String @unique\n name String?\n email String @unique\n emailVerified DateTime?\n image String?\n\n userId String @unique\n token String?\n\n sessions Session[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Role {\n id String @id @default(uuid())\n title String\n moniker String @unique // e.g. admin, super_admin, moderator\n\n permissions String\n users User[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Company {\n id String @id @default(cuid())\n name String\n\n cw_CompanyId Int @unique\n cw_Identifier String @unique\n\n credentials Credential[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel CredentialType {\n id String @id @default(cuid())\n name String @unique\n\n permissionScope String\n icon String?\n fields Json\n\n credentials Credential[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel SecureValue {\n id String @id @default(cuid())\n name String\n\n content String // Encrypted content\n hash String // Hash of the original content for integrity verification and Search\n\n credentialId String\n credential Credential @relation(fields: [credentialId], references: [id], onDelete: Cascade)\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Credential {\n id String @id @default(cuid())\n name String\n\n typeId String\n type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)\n\n fields Json\n\n companyId String\n company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)\n\n securevalues SecureValue[]\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
|
||||||
"runtimeDataModel": {
|
"runtimeDataModel": {
|
||||||
"models": {},
|
"models": {},
|
||||||
"enums": {},
|
"enums": {},
|
||||||
@@ -28,7 +28,7 @@ const config: runtime.GetPrismaClientConfig = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Company\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cw_CompanyId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cw_Identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}")
|
config.runtimeDataModel = JSON.parse("{\"models\":{\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessionKey\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expires\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenGenerated\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"refreshedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"invalidatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":null},\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roles\",\"kind\":\"object\",\"type\":\"Role\",\"relationName\":\"RoleToUser\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"login\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Role\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"moniker\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissions\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"RoleToUser\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Company\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cw_CompanyId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"cw_Identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"CredentialType\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"permissionScope\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"icon\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"credentials\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"SecureValue\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"hash\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credentialId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"credential\",\"kind\":\"object\",\"type\":\"Credential\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"Credential\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"typeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"object\",\"type\":\"CredentialType\",\"relationName\":\"CredentialToCredentialType\"},{\"name\":\"fields\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"companyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"object\",\"type\":\"Company\",\"relationName\":\"CompanyToCredential\"},{\"name\":\"securevalues\",\"kind\":\"object\",\"type\":\"SecureValue\",\"relationName\":\"CredentialToSecureValue\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}")
|
||||||
|
|
||||||
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
||||||
const { Buffer } = await import('node:buffer')
|
const { Buffer } = await import('node:buffer')
|
||||||
@@ -215,6 +215,36 @@ export interface PrismaClient<
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
get company(): Prisma.CompanyDelegate<ExtArgs, { omit: OmitOpts }>;
|
get company(): Prisma.CompanyDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.credentialType`: Exposes CRUD operations for the **CredentialType** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more CredentialTypes
|
||||||
|
* const credentialTypes = await prisma.credentialType.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get credentialType(): Prisma.CredentialTypeDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.secureValue`: Exposes CRUD operations for the **SecureValue** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more SecureValues
|
||||||
|
* const secureValues = await prisma.secureValue.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get secureValue(): Prisma.SecureValueDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.credential`: Exposes CRUD operations for the **Credential** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more Credentials
|
||||||
|
* const credentials = await prisma.credential.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get credential(): Prisma.CredentialDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPrismaClientClass(): PrismaClientConstructor {
|
export function getPrismaClientClass(): PrismaClientConstructor {
|
||||||
|
|||||||
@@ -387,7 +387,10 @@ export const ModelName = {
|
|||||||
Session: 'Session',
|
Session: 'Session',
|
||||||
User: 'User',
|
User: 'User',
|
||||||
Role: 'Role',
|
Role: 'Role',
|
||||||
Company: 'Company'
|
Company: 'Company',
|
||||||
|
CredentialType: 'CredentialType',
|
||||||
|
SecureValue: 'SecureValue',
|
||||||
|
Credential: 'Credential'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||||
@@ -403,7 +406,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
|||||||
omit: GlobalOmitOptions
|
omit: GlobalOmitOptions
|
||||||
}
|
}
|
||||||
meta: {
|
meta: {
|
||||||
modelProps: "session" | "user" | "role" | "company"
|
modelProps: "session" | "user" | "role" | "company" | "credentialType" | "secureValue" | "credential"
|
||||||
txIsolationLevel: TransactionIsolationLevel
|
txIsolationLevel: TransactionIsolationLevel
|
||||||
}
|
}
|
||||||
model: {
|
model: {
|
||||||
@@ -703,6 +706,228 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CredentialType: {
|
||||||
|
payload: Prisma.$CredentialTypePayload<ExtArgs>
|
||||||
|
fields: Prisma.CredentialTypeFieldRefs
|
||||||
|
operations: {
|
||||||
|
findUnique: {
|
||||||
|
args: Prisma.CredentialTypeFindUniqueArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload> | null
|
||||||
|
}
|
||||||
|
findUniqueOrThrow: {
|
||||||
|
args: Prisma.CredentialTypeFindUniqueOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
findFirst: {
|
||||||
|
args: Prisma.CredentialTypeFindFirstArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload> | null
|
||||||
|
}
|
||||||
|
findFirstOrThrow: {
|
||||||
|
args: Prisma.CredentialTypeFindFirstOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
findMany: {
|
||||||
|
args: Prisma.CredentialTypeFindManyArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>[]
|
||||||
|
}
|
||||||
|
create: {
|
||||||
|
args: Prisma.CredentialTypeCreateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
createMany: {
|
||||||
|
args: Prisma.CredentialTypeCreateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
createManyAndReturn: {
|
||||||
|
args: Prisma.CredentialTypeCreateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>[]
|
||||||
|
}
|
||||||
|
delete: {
|
||||||
|
args: Prisma.CredentialTypeDeleteArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
update: {
|
||||||
|
args: Prisma.CredentialTypeUpdateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
deleteMany: {
|
||||||
|
args: Prisma.CredentialTypeDeleteManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateMany: {
|
||||||
|
args: Prisma.CredentialTypeUpdateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateManyAndReturn: {
|
||||||
|
args: Prisma.CredentialTypeUpdateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>[]
|
||||||
|
}
|
||||||
|
upsert: {
|
||||||
|
args: Prisma.CredentialTypeUpsertArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialTypePayload>
|
||||||
|
}
|
||||||
|
aggregate: {
|
||||||
|
args: Prisma.CredentialTypeAggregateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.AggregateCredentialType>
|
||||||
|
}
|
||||||
|
groupBy: {
|
||||||
|
args: Prisma.CredentialTypeGroupByArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.CredentialTypeGroupByOutputType>[]
|
||||||
|
}
|
||||||
|
count: {
|
||||||
|
args: Prisma.CredentialTypeCountArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.CredentialTypeCountAggregateOutputType> | number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SecureValue: {
|
||||||
|
payload: Prisma.$SecureValuePayload<ExtArgs>
|
||||||
|
fields: Prisma.SecureValueFieldRefs
|
||||||
|
operations: {
|
||||||
|
findUnique: {
|
||||||
|
args: Prisma.SecureValueFindUniqueArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload> | null
|
||||||
|
}
|
||||||
|
findUniqueOrThrow: {
|
||||||
|
args: Prisma.SecureValueFindUniqueOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
findFirst: {
|
||||||
|
args: Prisma.SecureValueFindFirstArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload> | null
|
||||||
|
}
|
||||||
|
findFirstOrThrow: {
|
||||||
|
args: Prisma.SecureValueFindFirstOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
findMany: {
|
||||||
|
args: Prisma.SecureValueFindManyArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>[]
|
||||||
|
}
|
||||||
|
create: {
|
||||||
|
args: Prisma.SecureValueCreateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
createMany: {
|
||||||
|
args: Prisma.SecureValueCreateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
createManyAndReturn: {
|
||||||
|
args: Prisma.SecureValueCreateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>[]
|
||||||
|
}
|
||||||
|
delete: {
|
||||||
|
args: Prisma.SecureValueDeleteArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
update: {
|
||||||
|
args: Prisma.SecureValueUpdateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
deleteMany: {
|
||||||
|
args: Prisma.SecureValueDeleteManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateMany: {
|
||||||
|
args: Prisma.SecureValueUpdateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateManyAndReturn: {
|
||||||
|
args: Prisma.SecureValueUpdateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>[]
|
||||||
|
}
|
||||||
|
upsert: {
|
||||||
|
args: Prisma.SecureValueUpsertArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$SecureValuePayload>
|
||||||
|
}
|
||||||
|
aggregate: {
|
||||||
|
args: Prisma.SecureValueAggregateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.AggregateSecureValue>
|
||||||
|
}
|
||||||
|
groupBy: {
|
||||||
|
args: Prisma.SecureValueGroupByArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.SecureValueGroupByOutputType>[]
|
||||||
|
}
|
||||||
|
count: {
|
||||||
|
args: Prisma.SecureValueCountArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.SecureValueCountAggregateOutputType> | number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Credential: {
|
||||||
|
payload: Prisma.$CredentialPayload<ExtArgs>
|
||||||
|
fields: Prisma.CredentialFieldRefs
|
||||||
|
operations: {
|
||||||
|
findUnique: {
|
||||||
|
args: Prisma.CredentialFindUniqueArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload> | null
|
||||||
|
}
|
||||||
|
findUniqueOrThrow: {
|
||||||
|
args: Prisma.CredentialFindUniqueOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
findFirst: {
|
||||||
|
args: Prisma.CredentialFindFirstArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload> | null
|
||||||
|
}
|
||||||
|
findFirstOrThrow: {
|
||||||
|
args: Prisma.CredentialFindFirstOrThrowArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
findMany: {
|
||||||
|
args: Prisma.CredentialFindManyArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>[]
|
||||||
|
}
|
||||||
|
create: {
|
||||||
|
args: Prisma.CredentialCreateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
createMany: {
|
||||||
|
args: Prisma.CredentialCreateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
createManyAndReturn: {
|
||||||
|
args: Prisma.CredentialCreateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>[]
|
||||||
|
}
|
||||||
|
delete: {
|
||||||
|
args: Prisma.CredentialDeleteArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
update: {
|
||||||
|
args: Prisma.CredentialUpdateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
deleteMany: {
|
||||||
|
args: Prisma.CredentialDeleteManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateMany: {
|
||||||
|
args: Prisma.CredentialUpdateManyArgs<ExtArgs>
|
||||||
|
result: BatchPayload
|
||||||
|
}
|
||||||
|
updateManyAndReturn: {
|
||||||
|
args: Prisma.CredentialUpdateManyAndReturnArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>[]
|
||||||
|
}
|
||||||
|
upsert: {
|
||||||
|
args: Prisma.CredentialUpsertArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.PayloadToResult<Prisma.$CredentialPayload>
|
||||||
|
}
|
||||||
|
aggregate: {
|
||||||
|
args: Prisma.CredentialAggregateArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.AggregateCredential>
|
||||||
|
}
|
||||||
|
groupBy: {
|
||||||
|
args: Prisma.CredentialGroupByArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.CredentialGroupByOutputType>[]
|
||||||
|
}
|
||||||
|
count: {
|
||||||
|
args: Prisma.CredentialCountArgs<ExtArgs>
|
||||||
|
result: runtime.Types.Utils.Optional<Prisma.CredentialCountAggregateOutputType> | number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} & {
|
} & {
|
||||||
other: {
|
other: {
|
||||||
@@ -796,6 +1021,45 @@ export const CompanyScalarFieldEnum = {
|
|||||||
export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum]
|
export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const CredentialTypeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
permissionScope: 'permissionScope',
|
||||||
|
icon: 'icon',
|
||||||
|
fields: 'fields',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type CredentialTypeScalarFieldEnum = (typeof CredentialTypeScalarFieldEnum)[keyof typeof CredentialTypeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const SecureValueScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
content: 'content',
|
||||||
|
hash: 'hash',
|
||||||
|
credentialId: 'credentialId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type SecureValueScalarFieldEnum = (typeof SecureValueScalarFieldEnum)[keyof typeof SecureValueScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const CredentialScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
typeId: 'typeId',
|
||||||
|
fields: 'fields',
|
||||||
|
companyId: 'companyId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type CredentialScalarFieldEnum = (typeof CredentialScalarFieldEnum)[keyof typeof CredentialScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
export const SortOrder = {
|
||||||
asc: 'asc',
|
asc: 'asc',
|
||||||
desc: 'desc'
|
desc: 'desc'
|
||||||
@@ -804,6 +1068,13 @@ export const SortOrder = {
|
|||||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueInput = {
|
||||||
|
JsonNull: JsonNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput]
|
||||||
|
|
||||||
|
|
||||||
export const QueryMode = {
|
export const QueryMode = {
|
||||||
default: 'default',
|
default: 'default',
|
||||||
insensitive: 'insensitive'
|
insensitive: 'insensitive'
|
||||||
@@ -820,6 +1091,15 @@ export const NullsOrder = {
|
|||||||
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueFilter = {
|
||||||
|
DbNull: DbNull,
|
||||||
|
JsonNull: JsonNull,
|
||||||
|
AnyNull: AnyNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueFilter = (typeof JsonNullValueFilter)[keyof typeof JsonNullValueFilter]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field references
|
* Field references
|
||||||
@@ -875,6 +1155,20 @@ export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'Json'
|
||||||
|
*/
|
||||||
|
export type JsonFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Json'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'QueryMode'
|
||||||
|
*/
|
||||||
|
export type EnumQueryModeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'QueryMode'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a field of type 'Float'
|
* Reference to a field of type 'Float'
|
||||||
*/
|
*/
|
||||||
@@ -987,6 +1281,9 @@ export type GlobalOmitConfig = {
|
|||||||
user?: Prisma.UserOmit
|
user?: Prisma.UserOmit
|
||||||
role?: Prisma.RoleOmit
|
role?: Prisma.RoleOmit
|
||||||
company?: Prisma.CompanyOmit
|
company?: Prisma.CompanyOmit
|
||||||
|
credentialType?: Prisma.CredentialTypeOmit
|
||||||
|
secureValue?: Prisma.SecureValueOmit
|
||||||
|
credential?: Prisma.CredentialOmit
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Types for Logging */
|
/* Types for Logging */
|
||||||
|
|||||||
@@ -54,7 +54,10 @@ export const ModelName = {
|
|||||||
Session: 'Session',
|
Session: 'Session',
|
||||||
User: 'User',
|
User: 'User',
|
||||||
Role: 'Role',
|
Role: 'Role',
|
||||||
Company: 'Company'
|
Company: 'Company',
|
||||||
|
CredentialType: 'CredentialType',
|
||||||
|
SecureValue: 'SecureValue',
|
||||||
|
Credential: 'Credential'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||||
@@ -127,6 +130,45 @@ export const CompanyScalarFieldEnum = {
|
|||||||
export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum]
|
export type CompanyScalarFieldEnum = (typeof CompanyScalarFieldEnum)[keyof typeof CompanyScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const CredentialTypeScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
permissionScope: 'permissionScope',
|
||||||
|
icon: 'icon',
|
||||||
|
fields: 'fields',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type CredentialTypeScalarFieldEnum = (typeof CredentialTypeScalarFieldEnum)[keyof typeof CredentialTypeScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const SecureValueScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
content: 'content',
|
||||||
|
hash: 'hash',
|
||||||
|
credentialId: 'credentialId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type SecureValueScalarFieldEnum = (typeof SecureValueScalarFieldEnum)[keyof typeof SecureValueScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const CredentialScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
name: 'name',
|
||||||
|
typeId: 'typeId',
|
||||||
|
fields: 'fields',
|
||||||
|
companyId: 'companyId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type CredentialScalarFieldEnum = (typeof CredentialScalarFieldEnum)[keyof typeof CredentialScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
export const SortOrder = {
|
export const SortOrder = {
|
||||||
asc: 'asc',
|
asc: 'asc',
|
||||||
desc: 'desc'
|
desc: 'desc'
|
||||||
@@ -135,6 +177,13 @@ export const SortOrder = {
|
|||||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueInput = {
|
||||||
|
JsonNull: JsonNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput]
|
||||||
|
|
||||||
|
|
||||||
export const QueryMode = {
|
export const QueryMode = {
|
||||||
default: 'default',
|
default: 'default',
|
||||||
insensitive: 'insensitive'
|
insensitive: 'insensitive'
|
||||||
@@ -150,3 +199,12 @@ export const NullsOrder = {
|
|||||||
|
|
||||||
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueFilter = {
|
||||||
|
DbNull: DbNull,
|
||||||
|
JsonNull: JsonNull,
|
||||||
|
AnyNull: AnyNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueFilter = (typeof JsonNullValueFilter)[keyof typeof JsonNullValueFilter]
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,7 @@ export type * from './models/Session.ts'
|
|||||||
export type * from './models/User.ts'
|
export type * from './models/User.ts'
|
||||||
export type * from './models/Role.ts'
|
export type * from './models/Role.ts'
|
||||||
export type * from './models/Company.ts'
|
export type * from './models/Company.ts'
|
||||||
|
export type * from './models/CredentialType.ts'
|
||||||
|
export type * from './models/SecureValue.ts'
|
||||||
|
export type * from './models/Credential.ts'
|
||||||
export type * from './commonInputTypes.ts'
|
export type * from './commonInputTypes.ts'
|
||||||
@@ -224,6 +224,7 @@ export type CompanyWhereInput = {
|
|||||||
cw_Identifier?: Prisma.StringFilter<"Company"> | string
|
cw_Identifier?: Prisma.StringFilter<"Company"> | string
|
||||||
createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
||||||
|
credentials?: Prisma.CredentialListRelationFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyOrderByWithRelationInput = {
|
export type CompanyOrderByWithRelationInput = {
|
||||||
@@ -233,6 +234,7 @@ export type CompanyOrderByWithRelationInput = {
|
|||||||
cw_Identifier?: Prisma.SortOrder
|
cw_Identifier?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
|
credentials?: Prisma.CredentialOrderByRelationAggregateInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyWhereUniqueInput = Prisma.AtLeast<{
|
export type CompanyWhereUniqueInput = Prisma.AtLeast<{
|
||||||
@@ -245,6 +247,7 @@ export type CompanyWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
name?: Prisma.StringFilter<"Company"> | string
|
name?: Prisma.StringFilter<"Company"> | string
|
||||||
createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"Company"> | Date | string
|
||||||
|
credentials?: Prisma.CredentialListRelationFilter
|
||||||
}, "id" | "cw_CompanyId" | "cw_Identifier">
|
}, "id" | "cw_CompanyId" | "cw_Identifier">
|
||||||
|
|
||||||
export type CompanyOrderByWithAggregationInput = {
|
export type CompanyOrderByWithAggregationInput = {
|
||||||
@@ -280,6 +283,7 @@ export type CompanyCreateInput = {
|
|||||||
cw_Identifier: string
|
cw_Identifier: string
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
|
credentials?: Prisma.CredentialCreateNestedManyWithoutCompanyInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyUncheckedCreateInput = {
|
export type CompanyUncheckedCreateInput = {
|
||||||
@@ -289,6 +293,7 @@ export type CompanyUncheckedCreateInput = {
|
|||||||
cw_Identifier: string
|
cw_Identifier: string
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
|
credentials?: Prisma.CredentialUncheckedCreateNestedManyWithoutCompanyInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyUpdateInput = {
|
export type CompanyUpdateInput = {
|
||||||
@@ -298,6 +303,7 @@ export type CompanyUpdateInput = {
|
|||||||
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
credentials?: Prisma.CredentialUpdateManyWithoutCompanyNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyUncheckedUpdateInput = {
|
export type CompanyUncheckedUpdateInput = {
|
||||||
@@ -307,6 +313,7 @@ export type CompanyUncheckedUpdateInput = {
|
|||||||
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
credentials?: Prisma.CredentialUncheckedUpdateManyWithoutCompanyNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyCreateManyInput = {
|
export type CompanyCreateManyInput = {
|
||||||
@@ -371,6 +378,11 @@ export type CompanySumOrderByAggregateInput = {
|
|||||||
cw_CompanyId?: Prisma.SortOrder
|
cw_CompanyId?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CompanyScalarRelationFilter = {
|
||||||
|
is?: Prisma.CompanyWhereInput
|
||||||
|
isNot?: Prisma.CompanyWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
export type IntFieldUpdateOperationsInput = {
|
export type IntFieldUpdateOperationsInput = {
|
||||||
set?: number
|
set?: number
|
||||||
increment?: number
|
increment?: number
|
||||||
@@ -379,6 +391,101 @@ export type IntFieldUpdateOperationsInput = {
|
|||||||
divide?: number
|
divide?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateNestedOneWithoutCredentialsInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutCredentialsInput
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateOneRequiredWithoutCredentialsNestedInput = {
|
||||||
|
create?: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
||||||
|
connectOrCreate?: Prisma.CompanyCreateOrConnectWithoutCredentialsInput
|
||||||
|
upsert?: Prisma.CompanyUpsertWithoutCredentialsInput
|
||||||
|
connect?: Prisma.CompanyWhereUniqueInput
|
||||||
|
update?: Prisma.XOR<Prisma.XOR<Prisma.CompanyUpdateToOneWithWhereWithoutCredentialsInput, Prisma.CompanyUpdateWithoutCredentialsInput>, Prisma.CompanyUncheckedUpdateWithoutCredentialsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateWithoutCredentialsInput = {
|
||||||
|
id?: string
|
||||||
|
name: string
|
||||||
|
cw_CompanyId: number
|
||||||
|
cw_Identifier: string
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedCreateWithoutCredentialsInput = {
|
||||||
|
id?: string
|
||||||
|
name: string
|
||||||
|
cw_CompanyId: number
|
||||||
|
cw_Identifier: string
|
||||||
|
createdAt?: Date | string
|
||||||
|
updatedAt?: Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCreateOrConnectWithoutCredentialsInput = {
|
||||||
|
where: Prisma.CompanyWhereUniqueInput
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpsertWithoutCredentialsInput = {
|
||||||
|
update: Prisma.XOR<Prisma.CompanyUpdateWithoutCredentialsInput, Prisma.CompanyUncheckedUpdateWithoutCredentialsInput>
|
||||||
|
create: Prisma.XOR<Prisma.CompanyCreateWithoutCredentialsInput, Prisma.CompanyUncheckedCreateWithoutCredentialsInput>
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateToOneWithWhereWithoutCredentialsInput = {
|
||||||
|
where?: Prisma.CompanyWhereInput
|
||||||
|
data: Prisma.XOR<Prisma.CompanyUpdateWithoutCredentialsInput, Prisma.CompanyUncheckedUpdateWithoutCredentialsInput>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUpdateWithoutCredentialsInput = {
|
||||||
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyUncheckedUpdateWithoutCredentialsInput = {
|
||||||
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
cw_CompanyId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
|
cw_Identifier?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count Type CompanyCountOutputType
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type CompanyCountOutputType = {
|
||||||
|
credentials: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompanyCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
credentials?: boolean | CompanyCountOutputTypeCountCredentialsArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompanyCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type CompanyCountOutputTypeDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the CompanyCountOutputType
|
||||||
|
*/
|
||||||
|
select?: Prisma.CompanyCountOutputTypeSelect<ExtArgs> | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompanyCountOutputType without action
|
||||||
|
*/
|
||||||
|
export type CompanyCountOutputTypeCountCredentialsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
where?: Prisma.CredentialWhereInput
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export type CompanySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type CompanySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
@@ -388,6 +495,8 @@ export type CompanySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
|||||||
cw_Identifier?: boolean
|
cw_Identifier?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
|
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
||||||
|
_count?: boolean | Prisma.CompanyCountOutputTypeDefaultArgs<ExtArgs>
|
||||||
}, ExtArgs["result"]["company"]>
|
}, ExtArgs["result"]["company"]>
|
||||||
|
|
||||||
export type CompanySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type CompanySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
@@ -418,10 +527,18 @@ export type CompanySelectScalar = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type CompanyOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "cw_CompanyId" | "cw_Identifier" | "createdAt" | "updatedAt", ExtArgs["result"]["company"]>
|
export type CompanyOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "cw_CompanyId" | "cw_Identifier" | "createdAt" | "updatedAt", ExtArgs["result"]["company"]>
|
||||||
|
export type CompanyInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
credentials?: boolean | Prisma.Company$credentialsArgs<ExtArgs>
|
||||||
|
_count?: boolean | Prisma.CompanyCountOutputTypeDefaultArgs<ExtArgs>
|
||||||
|
}
|
||||||
|
export type CompanyIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||||
|
export type CompanyIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||||
|
|
||||||
export type $CompanyPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type $CompanyPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
name: "Company"
|
name: "Company"
|
||||||
objects: {}
|
objects: {
|
||||||
|
credentials: Prisma.$CredentialPayload<ExtArgs>[]
|
||||||
|
}
|
||||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@@ -823,6 +940,7 @@ readonly fields: CompanyFieldRefs;
|
|||||||
*/
|
*/
|
||||||
export interface Prisma__CompanyClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
export interface Prisma__CompanyClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
||||||
readonly [Symbol.toStringTag]: "PrismaPromise"
|
readonly [Symbol.toStringTag]: "PrismaPromise"
|
||||||
|
credentials<T extends Prisma.Company$credentialsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.Company$credentialsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CredentialPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||||
/**
|
/**
|
||||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||||
@@ -874,6 +992,10 @@ export type CompanyFindUniqueArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Company to fetch.
|
* Filter, which Company to fetch.
|
||||||
*/
|
*/
|
||||||
@@ -892,6 +1014,10 @@ export type CompanyFindUniqueOrThrowArgs<ExtArgs extends runtime.Types.Extension
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Company to fetch.
|
* Filter, which Company to fetch.
|
||||||
*/
|
*/
|
||||||
@@ -910,6 +1036,10 @@ export type CompanyFindFirstArgs<ExtArgs extends runtime.Types.Extensions.Intern
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Company to fetch.
|
* Filter, which Company to fetch.
|
||||||
*/
|
*/
|
||||||
@@ -958,6 +1088,10 @@ export type CompanyFindFirstOrThrowArgs<ExtArgs extends runtime.Types.Extensions
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Company to fetch.
|
* Filter, which Company to fetch.
|
||||||
*/
|
*/
|
||||||
@@ -1006,6 +1140,10 @@ export type CompanyFindManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter, which Companies to fetch.
|
* Filter, which Companies to fetch.
|
||||||
*/
|
*/
|
||||||
@@ -1049,6 +1187,10 @@ export type CompanyCreateArgs<ExtArgs extends runtime.Types.Extensions.InternalA
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The data needed to create a Company.
|
* The data needed to create a Company.
|
||||||
*/
|
*/
|
||||||
@@ -1097,6 +1239,10 @@ export type CompanyUpdateArgs<ExtArgs extends runtime.Types.Extensions.InternalA
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The data needed to update a Company.
|
* The data needed to update a Company.
|
||||||
*/
|
*/
|
||||||
@@ -1163,6 +1309,10 @@ export type CompanyUpsertArgs<ExtArgs extends runtime.Types.Extensions.InternalA
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* The filter to search for the Company to update in case it exists.
|
* The filter to search for the Company to update in case it exists.
|
||||||
*/
|
*/
|
||||||
@@ -1189,6 +1339,10 @@ export type CompanyDeleteArgs<ExtArgs extends runtime.Types.Extensions.InternalA
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
/**
|
/**
|
||||||
* Filter which Company to delete.
|
* Filter which Company to delete.
|
||||||
*/
|
*/
|
||||||
@@ -1209,6 +1363,30 @@ export type CompanyDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
|||||||
limit?: number
|
limit?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Company.credentials
|
||||||
|
*/
|
||||||
|
export type Company$credentialsArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
|
/**
|
||||||
|
* Select specific fields to fetch from the Credential
|
||||||
|
*/
|
||||||
|
select?: Prisma.CredentialSelect<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Omit specific fields from the Credential
|
||||||
|
*/
|
||||||
|
omit?: Prisma.CredentialOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CredentialInclude<ExtArgs> | null
|
||||||
|
where?: Prisma.CredentialWhereInput
|
||||||
|
orderBy?: Prisma.CredentialOrderByWithRelationInput | Prisma.CredentialOrderByWithRelationInput[]
|
||||||
|
cursor?: Prisma.CredentialWhereUniqueInput
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
distinct?: Prisma.CredentialScalarFieldEnum | Prisma.CredentialScalarFieldEnum[]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Company without action
|
* Company without action
|
||||||
*/
|
*/
|
||||||
@@ -1221,4 +1399,8 @@ export type CompanyDefaultArgs<ExtArgs extends runtime.Types.Extensions.Internal
|
|||||||
* Omit specific fields from the Company
|
* Omit specific fields from the Company
|
||||||
*/
|
*/
|
||||||
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
omit?: Prisma.CompanyOmit<ExtArgs> | null
|
||||||
|
/**
|
||||||
|
* Choose, which related nodes to fetch as well
|
||||||
|
*/
|
||||||
|
include?: Prisma.CompanyInclude<ExtArgs> | null
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@
|
|||||||
"@prisma/client": "^7.3.0",
|
"@prisma/client": "^7.3.0",
|
||||||
"@socket.io/bun-engine": "^0.1.0",
|
"@socket.io/bun-engine": "^0.1.0",
|
||||||
"axios": "^1.13.3",
|
"axios": "^1.13.3",
|
||||||
|
"blakets": "^0.1.12",
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
"cuid": "^3.0.0",
|
"cuid": "^3.0.0",
|
||||||
"hono": "^4.11.5",
|
"hono": "^4.11.5",
|
||||||
|
|||||||
@@ -62,6 +62,54 @@ model Company {
|
|||||||
cw_CompanyId Int @unique
|
cw_CompanyId Int @unique
|
||||||
cw_Identifier String @unique
|
cw_Identifier String @unique
|
||||||
|
|
||||||
|
credentials Credential[]
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model CredentialType {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
name String @unique
|
||||||
|
|
||||||
|
permissionScope String
|
||||||
|
icon String?
|
||||||
|
fields Json
|
||||||
|
|
||||||
|
credentials Credential[]
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model SecureValue {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
name String
|
||||||
|
|
||||||
|
content String // Encrypted content
|
||||||
|
hash String // Hash of the original content for integrity verification and Search
|
||||||
|
|
||||||
|
credentialId String
|
||||||
|
credential Credential @relation(fields: [credentialId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model Credential {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
name String
|
||||||
|
|
||||||
|
typeId String
|
||||||
|
type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
fields Json
|
||||||
|
|
||||||
|
companyId String
|
||||||
|
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
securevalues SecureValue[]
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/* /v1/credential-type */
|
||||||
|
export default createRoute(
|
||||||
|
"post",
|
||||||
|
["/"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
name: z.string().min(1, "Name is required"),
|
||||||
|
permissionScope: z.string().min(1, "Permission scope is required"),
|
||||||
|
icon: z.string().optional(),
|
||||||
|
fields: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
required: z.boolean(),
|
||||||
|
secure: z.boolean(),
|
||||||
|
valueType: z.enum(["plain_text", "password"]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
const credentialType = await credentialTypes.create(data as any);
|
||||||
|
|
||||||
|
const response = apiResponse.created(
|
||||||
|
"Credential Type Created Successfully!",
|
||||||
|
credentialType.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential_type.create"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential-type/:id */
|
||||||
|
export default createRoute(
|
||||||
|
"delete",
|
||||||
|
["/:id"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
await credentialTypes.delete(c.req.param("id"));
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Type Deleted Successfully!",
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential_type.delete"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential-type/:identifier */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/:identifier"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credentialType = await credentialTypes.fetch(
|
||||||
|
c.req.param("identifier"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Type Fetched Successfully!",
|
||||||
|
credentialType.toJson({ includeCredentialCount: true }),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential_type.fetch"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential-type */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const allCredentialTypes = await credentialTypes.fetchAll();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Types Fetched Successfully!",
|
||||||
|
allCredentialTypes.map((ct) =>
|
||||||
|
ct.toJson({ includeCredentialCount: true }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential_type.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential-type/:id/credentials */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/:id/credentials"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credentialType = await credentialTypes.fetch(c.req.param("id"));
|
||||||
|
const credentials = await credentialType.fetchCredentials();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credentials Fetched Successfully!",
|
||||||
|
credentials.map((cred) => cred.toJson()),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({
|
||||||
|
permissions: ["credential_type.fetch", "credential.fetch.many"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { default as fetch } from "./fetch";
|
||||||
|
import { default as fetchAll } from "./fetchAll";
|
||||||
|
import { default as create } from "./create";
|
||||||
|
import { default as update } from "./update";
|
||||||
|
import { default as deleteCredentialType } from "./delete";
|
||||||
|
import { default as fetchCredentials } from "./fetchCredentials";
|
||||||
|
|
||||||
|
export {
|
||||||
|
fetch,
|
||||||
|
fetchAll,
|
||||||
|
create,
|
||||||
|
update,
|
||||||
|
deleteCredentialType as delete,
|
||||||
|
fetchCredentials,
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentialTypes } from "../../managers/credentialTypes";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/* /v1/credential-type/:id */
|
||||||
|
export default createRoute(
|
||||||
|
"patch",
|
||||||
|
["/:id"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
const credentialType = await credentialTypes.fetch(c.req.param("id"));
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
permissionScope: z.string().optional(),
|
||||||
|
icon: z.string().optional(),
|
||||||
|
fields: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
required: z.boolean(),
|
||||||
|
secure: z.boolean(),
|
||||||
|
valueType: z.enum(["plain_text", "password"]),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
await credentialType.update(data as any);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Type Updated Successfully!",
|
||||||
|
credentialType.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential_type.update"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/* /v1/credential/create */
|
||||||
|
export default createRoute(
|
||||||
|
"post",
|
||||||
|
["/credentials"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
name: z.string().min(1, "Name is required"),
|
||||||
|
typeId: z.string().min(1, "Type ID is required"),
|
||||||
|
companyId: z.string().min(1, "Company ID is required"),
|
||||||
|
fields: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
fieldId: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
const credential = await credentials.create(data);
|
||||||
|
|
||||||
|
const response = apiResponse.created(
|
||||||
|
"Credential Created Successfully!",
|
||||||
|
credential.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential.create"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential/:id */
|
||||||
|
export default createRoute(
|
||||||
|
"delete",
|
||||||
|
["/credentials/:id"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
await credentials.delete(c.req.param("id"));
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Deleted Successfully!",
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential.delete"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential/:id */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/credentials/:id"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Fetched Successfully!",
|
||||||
|
credential.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential.fetch"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential/company/:companyId */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/credentials/company/:companyId"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const companyCredentials = await credentials.fetchByCompany(
|
||||||
|
c.req.param("companyId"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Company Credentials Fetched Successfully!",
|
||||||
|
companyCredentials.map((cred) => cred.toJson()),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential.fetch.many"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential/:id/fields */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/credentials/:id/fields"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
const fields = await credential.fetchAllFieldValues();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Fields Fetched Successfully!",
|
||||||
|
fields,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({
|
||||||
|
permissions: ["credential.fetch", "credential.fields.fetch"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { default as fetch } from "./fetch";
|
||||||
|
import { default as fetchByCompany } from "./fetchByCompany";
|
||||||
|
import { default as create } from "./create";
|
||||||
|
import { default as update } from "./update";
|
||||||
|
import { default as updateFields } from "./updateFields";
|
||||||
|
import { default as fetchFields } from "./fetchFields";
|
||||||
|
import { default as readSecureValues } from "./readSecureValues";
|
||||||
|
import { default as deleteCredential } from "./delete";
|
||||||
|
|
||||||
|
export {
|
||||||
|
fetch,
|
||||||
|
fetchByCompany,
|
||||||
|
create,
|
||||||
|
update,
|
||||||
|
updateFields,
|
||||||
|
fetchFields,
|
||||||
|
readSecureValues,
|
||||||
|
deleteCredential as delete,
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* /v1/credential/:id/secure-values */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/credentials/:id/secure-values"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
const secureValues = await credential.readAllSecureValues();
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Secure Values Fetched Successfully!",
|
||||||
|
secureValues,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({
|
||||||
|
permissions: ["credential.fetch", "credential.secure_values.read"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/* /v1/credential/:id */
|
||||||
|
export default createRoute(
|
||||||
|
"patch",
|
||||||
|
["/credentials/:id"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
await credential.update(data);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Updated Successfully!",
|
||||||
|
credential.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["credential.update"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { Hono } from "hono/tiny";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { credentials } from "../../managers/credentials";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/* /v1/credential/:id/fields */
|
||||||
|
export default createRoute(
|
||||||
|
"put",
|
||||||
|
["/credentials/:id/fields"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
fields: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
fieldId: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
await credential.validateAndUpdateFields(data.fields);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Credential Fields Updated Successfully!",
|
||||||
|
credential.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({
|
||||||
|
permissions: ["credential.update", "credential.fields.update"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { Hono } from "hono";
|
||||||
|
import * as credentialRoutes from "../credentials";
|
||||||
|
|
||||||
|
const credentialRouter = new Hono();
|
||||||
|
Object.values(credentialRoutes).map((r) => credentialRouter.route("/", r));
|
||||||
|
|
||||||
|
export default credentialRouter;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Hono } from "hono";
|
||||||
|
import * as credentialTypeRoutes from "../credential-types";
|
||||||
|
|
||||||
|
const credentialTypeRouter = new Hono();
|
||||||
|
Object.values(credentialTypeRoutes).map((r) =>
|
||||||
|
credentialTypeRouter.route("/", r),
|
||||||
|
);
|
||||||
|
|
||||||
|
export default credentialTypeRouter;
|
||||||
@@ -50,6 +50,8 @@ v1.route("/teapot", teapot);
|
|||||||
v1.route("/auth", require("./routers/authRouter").default);
|
v1.route("/auth", require("./routers/authRouter").default);
|
||||||
v1.route("/user", require("./routers/user").default);
|
v1.route("/user", require("./routers/user").default);
|
||||||
v1.route("/company", require("./routers/companyRouter").default);
|
v1.route("/company", require("./routers/companyRouter").default);
|
||||||
|
v1.route("/credential", require("./routers/credentialRouter").default);
|
||||||
|
v1.route("/credential-type", require("./routers/credentialTypeRouter").default);
|
||||||
app.route("/v1", v1);
|
app.route("/v1", v1);
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
+9
-11
@@ -23,18 +23,16 @@ export const sessionDuration = 30 * 24 * 60 * 60000;
|
|||||||
export const accessTokenDuration = "10min";
|
export const accessTokenDuration = "10min";
|
||||||
export const refreshTokenDuration = "30d";
|
export const refreshTokenDuration = "30d";
|
||||||
|
|
||||||
export const accessTokenPrivateKey = readFileSync(
|
export const accessTokenPrivateKey =
|
||||||
`${import.meta.dir}/../.accessToken.key`,
|
readFileSync(`.accessToken.key`).toString();
|
||||||
|
export const refreshTokenPrivateKey =
|
||||||
|
readFileSync(`.refreshToken.key`).toString();
|
||||||
|
export const permissionsPrivateKey = readFileSync(`.permissions.key`);
|
||||||
|
export const secureValuesPrivateKey =
|
||||||
|
readFileSync(`.secureValues.key`).toString();
|
||||||
|
export const secureValuesPublicKey = readFileSync(
|
||||||
|
`public-keys/.secureValues.pub`,
|
||||||
).toString();
|
).toString();
|
||||||
export const refreshTokenPrivateKey = readFileSync(
|
|
||||||
`${import.meta.dir}/../.refreshToken.key`,
|
|
||||||
).toString();
|
|
||||||
export const permissionsPrivateKey = readFileSync(
|
|
||||||
`${import.meta.dir}/../.permissions.key`,
|
|
||||||
);
|
|
||||||
export const apiKeyTokenPrivateKey = readFileSync(
|
|
||||||
`${import.meta.dir}/../.apiKeyToken.key`,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Microsoft Auth Constants
|
// Microsoft Auth Constants
|
||||||
const msalConfig: msal.Configuration = {
|
const msalConfig: msal.Configuration = {
|
||||||
|
|||||||
@@ -0,0 +1,322 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import {
|
||||||
|
Credential,
|
||||||
|
CredentialType,
|
||||||
|
Company,
|
||||||
|
SecureValue,
|
||||||
|
} from "../../generated/prisma/client";
|
||||||
|
import { prisma } from "../constants";
|
||||||
|
import { fieldValidator } from "../modules/credentials/fieldValidator";
|
||||||
|
import {
|
||||||
|
CredentialField,
|
||||||
|
CredentialTypeField,
|
||||||
|
} from "../modules/credentials/credentialTypeDefs";
|
||||||
|
import { generateSecureValue } from "../modules/credentials/generateSecureValue";
|
||||||
|
import { readSecureValue } from "../modules/credentials/readSecureValue";
|
||||||
|
import GenericError from "../Errors/GenericError";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credential Controller
|
||||||
|
*
|
||||||
|
* This class manages credential data, including field validation,
|
||||||
|
* secure value storage/retrieval, and credential updates.
|
||||||
|
*/
|
||||||
|
export class CredentialController {
|
||||||
|
public readonly id: string;
|
||||||
|
public name: string;
|
||||||
|
public readonly typeId: string;
|
||||||
|
public readonly companyId: string;
|
||||||
|
public fields: any;
|
||||||
|
|
||||||
|
private _type: CredentialType;
|
||||||
|
private _company: Company;
|
||||||
|
private _secureValues: SecureValue[];
|
||||||
|
|
||||||
|
public readonly createdAt: Date;
|
||||||
|
public updatedAt: Date;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
credentialData: Credential & {
|
||||||
|
type: CredentialType;
|
||||||
|
company: Company;
|
||||||
|
securevalues: SecureValue[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
this.id = credentialData.id;
|
||||||
|
this.name = credentialData.name;
|
||||||
|
this.typeId = credentialData.typeId;
|
||||||
|
this.companyId = credentialData.companyId;
|
||||||
|
this.fields = credentialData.fields;
|
||||||
|
this._type = credentialData.type;
|
||||||
|
this._company = credentialData.company;
|
||||||
|
this._secureValues = credentialData.securevalues;
|
||||||
|
this.createdAt = credentialData.createdAt;
|
||||||
|
this.updatedAt = credentialData.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Internal Values
|
||||||
|
*
|
||||||
|
* Internal method to update all internal values when we query the database.
|
||||||
|
* This keeps everything up-to-date even when we pass around the credential controller.
|
||||||
|
*
|
||||||
|
* @param credentialData - Credential object from Prisma
|
||||||
|
*/
|
||||||
|
private _updateInternalValues(credentialData: Credential) {
|
||||||
|
this.name = credentialData.name;
|
||||||
|
this.fields = credentialData.fields;
|
||||||
|
this.updatedAt = credentialData.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and Update Fields
|
||||||
|
*
|
||||||
|
* This method validates the submitted fields against the credential type's
|
||||||
|
* acceptable fields, then updates the credential in the database.
|
||||||
|
* Secure fields are encrypted and stored in the SecureValue table.
|
||||||
|
*
|
||||||
|
* @param fields - The fields to validate and update
|
||||||
|
* @returns {Promise<CredentialController>} - The updated credential controller
|
||||||
|
*/
|
||||||
|
async validateAndUpdateFields(
|
||||||
|
fields: CredentialField[],
|
||||||
|
): Promise<CredentialController> {
|
||||||
|
// Get acceptable fields from the credential type
|
||||||
|
const acceptableFields = this._type.fields as any as CredentialTypeField[];
|
||||||
|
// Validate the fields
|
||||||
|
const validatedFields = await fieldValidator(fields, acceptableFields);
|
||||||
|
|
||||||
|
// Separate secure and non-secure fields
|
||||||
|
const secureFields = validatedFields.filter((f) => f.secure);
|
||||||
|
const nonSecureFields = validatedFields.filter((f) => !f.secure);
|
||||||
|
|
||||||
|
// Process secure fields - encrypt and store in SecureValue table
|
||||||
|
await Promise.all(
|
||||||
|
secureFields.map(async (field) => {
|
||||||
|
const { encrypted, hash } = generateSecureValue(field.value);
|
||||||
|
|
||||||
|
// Check if a secure value already exists for this field
|
||||||
|
const existingSecureValue = await prisma.secureValue.findFirst({
|
||||||
|
where: {
|
||||||
|
credentialId: this.id,
|
||||||
|
name: field.fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingSecureValue) {
|
||||||
|
// Update existing secure value
|
||||||
|
await prisma.secureValue.update({
|
||||||
|
where: { id: existingSecureValue.id },
|
||||||
|
data: {
|
||||||
|
content: encrypted,
|
||||||
|
hash,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Create new secure value
|
||||||
|
await prisma.secureValue.create({
|
||||||
|
data: {
|
||||||
|
name: field.fieldId,
|
||||||
|
content: encrypted,
|
||||||
|
hash,
|
||||||
|
credentialId: this.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build fields object for non-secure fields
|
||||||
|
const fieldsObject: Record<string, any> = {};
|
||||||
|
nonSecureFields.forEach((field) => {
|
||||||
|
fieldsObject[field.fieldId] = field.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the credential with non-secure fields
|
||||||
|
const updatedCredential = await prisma.credential.update({
|
||||||
|
where: { id: this.id },
|
||||||
|
data: {
|
||||||
|
fields: fieldsObject,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateInternalValues(updatedCredential);
|
||||||
|
|
||||||
|
// Refresh secure values
|
||||||
|
const secureValues = await prisma.secureValue.findMany({
|
||||||
|
where: { credentialId: this.id },
|
||||||
|
});
|
||||||
|
this._secureValues = secureValues;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch All Field Values
|
||||||
|
*
|
||||||
|
* Returns all field values (both secure and non-secure) for this credential.
|
||||||
|
* Secure field values are NOT decrypted - use `readSecureFieldValue` for that.
|
||||||
|
*
|
||||||
|
* @returns {Promise<CredentialField[]>} - Array of all fields with their encrypted values
|
||||||
|
*/
|
||||||
|
async fetchAllFieldValues(): Promise<CredentialField[]> {
|
||||||
|
const fields: CredentialField[] = [];
|
||||||
|
|
||||||
|
// Add non-secure fields from the fields JSON
|
||||||
|
const nonSecureFields = this.fields as Record<string, any>;
|
||||||
|
Object.entries(nonSecureFields || {}).forEach(([fieldId, value]) => {
|
||||||
|
fields.push({
|
||||||
|
id: `${this.id}-${fieldId}`, // Generate a consistent ID
|
||||||
|
fieldId,
|
||||||
|
value: value as string,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add secure fields from SecureValue table (encrypted)
|
||||||
|
this._secureValues.forEach((secureValue) => {
|
||||||
|
fields.push({
|
||||||
|
id: secureValue.id,
|
||||||
|
fieldId: secureValue.name,
|
||||||
|
value: secureValue.content, // Encrypted value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Secure Field Value
|
||||||
|
*
|
||||||
|
* Decrypts and returns the value of a specific secure field.
|
||||||
|
*
|
||||||
|
* @param fieldId - The field ID to read
|
||||||
|
* @returns {Promise<string>} - The decrypted field value
|
||||||
|
*/
|
||||||
|
async readSecureFieldValue(fieldId: string): Promise<string> {
|
||||||
|
const secureValue = this._secureValues.find((sv) => sv.name === fieldId);
|
||||||
|
|
||||||
|
if (!secureValue) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: `Secure field not found: ${fieldId}`,
|
||||||
|
name: "SecureFieldNotFound",
|
||||||
|
cause: `No secure value exists for field '${fieldId}' in credential '${this.id}'`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt the value
|
||||||
|
const decryptedValue = readSecureValue(
|
||||||
|
secureValue.content,
|
||||||
|
secureValue.hash,
|
||||||
|
);
|
||||||
|
|
||||||
|
return decryptedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read All Secure Values
|
||||||
|
*
|
||||||
|
* Decrypts and returns all secure field values for this credential.
|
||||||
|
*
|
||||||
|
* @returns {Promise<Record<string, string>>} - Object mapping field IDs to decrypted values
|
||||||
|
*/
|
||||||
|
async readAllSecureValues(): Promise<Record<string, string>> {
|
||||||
|
const secureValues: Record<string, string> = {};
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
this._secureValues.map(async (secureValue) => {
|
||||||
|
const decryptedValue = readSecureValue(
|
||||||
|
secureValue.content,
|
||||||
|
secureValue.hash,
|
||||||
|
);
|
||||||
|
secureValues[secureValue.name] = decryptedValue;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return secureValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Credential
|
||||||
|
*
|
||||||
|
* Update the credential name or other basic properties.
|
||||||
|
*
|
||||||
|
* @param data - Partial credential data to update
|
||||||
|
* @returns {Promise<CredentialController>} - The updated credential controller
|
||||||
|
*/
|
||||||
|
async update(
|
||||||
|
data: Partial<Pick<Credential, "name">>,
|
||||||
|
): Promise<CredentialController> {
|
||||||
|
const pData = z
|
||||||
|
.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
|
.parse(data);
|
||||||
|
|
||||||
|
const updatedCredential = await prisma.credential.update({
|
||||||
|
where: { id: this.id },
|
||||||
|
data: pData,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateInternalValues(updatedCredential);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Credential Type
|
||||||
|
*
|
||||||
|
* Returns the credential type information.
|
||||||
|
*
|
||||||
|
* @returns {CredentialType} - The credential type
|
||||||
|
*/
|
||||||
|
getType(): CredentialType {
|
||||||
|
return this._type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Company
|
||||||
|
*
|
||||||
|
* Returns the company this credential belongs to.
|
||||||
|
*
|
||||||
|
* @returns {Company} - The company
|
||||||
|
*/
|
||||||
|
getCompany(): Company {
|
||||||
|
return this._company;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To JSON
|
||||||
|
*
|
||||||
|
* Create an object that can be safely returned to the user.
|
||||||
|
* Secure values are not included by default.
|
||||||
|
*
|
||||||
|
* @param opts - Options to change the output
|
||||||
|
* @returns - An object that is JSON friendly
|
||||||
|
*/
|
||||||
|
toJson(opts?: { includeSecureValues?: boolean }) {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
typeId: this.typeId,
|
||||||
|
companyId: this.companyId,
|
||||||
|
fields: this.fields,
|
||||||
|
type: {
|
||||||
|
id: this._type.id,
|
||||||
|
name: this._type.name,
|
||||||
|
fields: this._type.fields,
|
||||||
|
permissionScope: this._type.permissionScope,
|
||||||
|
},
|
||||||
|
company: {
|
||||||
|
id: this._company.id,
|
||||||
|
name: this._company.name,
|
||||||
|
},
|
||||||
|
secureFieldIds: opts?.includeSecureValues
|
||||||
|
? this._secureValues.map((sv) => sv.name)
|
||||||
|
: undefined,
|
||||||
|
createdAt: this.createdAt,
|
||||||
|
updatedAt: this.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import { CredentialType, Credential } from "../../generated/prisma/client";
|
||||||
|
import { prisma } from "../constants";
|
||||||
|
import { CredentialTypeField } from "../modules/credentials/credentialTypeDefs";
|
||||||
|
import { CredentialController } from "./CredentialController";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credential Type Controller
|
||||||
|
*
|
||||||
|
* This class manages credential type data, including field definitions,
|
||||||
|
* permission scopes, and associated credentials.
|
||||||
|
*/
|
||||||
|
export class CredentialTypeController {
|
||||||
|
public readonly id: string;
|
||||||
|
public name: string;
|
||||||
|
public permissionScope: string;
|
||||||
|
public icon: string | null;
|
||||||
|
public fields: CredentialTypeField[];
|
||||||
|
|
||||||
|
private _credentials: Credential[];
|
||||||
|
|
||||||
|
public readonly createdAt: Date;
|
||||||
|
public updatedAt: Date;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
credentialTypeData: CredentialType & {
|
||||||
|
credentials: Credential[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
this.id = credentialTypeData.id;
|
||||||
|
this.name = credentialTypeData.name;
|
||||||
|
this.permissionScope = credentialTypeData.permissionScope;
|
||||||
|
this.icon = credentialTypeData.icon;
|
||||||
|
this.fields = credentialTypeData.fields! as any as CredentialTypeField[];
|
||||||
|
this._credentials = credentialTypeData.credentials;
|
||||||
|
this.createdAt = credentialTypeData.createdAt;
|
||||||
|
this.updatedAt = credentialTypeData.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Internal Values
|
||||||
|
*
|
||||||
|
* Internal method to update all internal values when we query the database.
|
||||||
|
* This keeps everything up-to-date even when we pass around the credential type controller.
|
||||||
|
*
|
||||||
|
* @param credentialTypeData - CredentialType object from Prisma
|
||||||
|
*/
|
||||||
|
private _updateInternalValues(credentialTypeData: CredentialType) {
|
||||||
|
this.name = credentialTypeData.name;
|
||||||
|
this.permissionScope = credentialTypeData.permissionScope;
|
||||||
|
this.icon = credentialTypeData.icon;
|
||||||
|
this.fields = credentialTypeData.fields! as any as CredentialTypeField[];
|
||||||
|
this.updatedAt = credentialTypeData.updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Credential Type
|
||||||
|
*
|
||||||
|
* Update the credential type's name, permission scope, icon, or fields.
|
||||||
|
*
|
||||||
|
* @param data - Partial credential type data to update
|
||||||
|
* @returns {Promise<CredentialTypeController>} - The updated credential type controller
|
||||||
|
*/
|
||||||
|
async update(
|
||||||
|
data: Partial<
|
||||||
|
Pick<CredentialType, "name" | "permissionScope" | "icon"> & {
|
||||||
|
fields: CredentialTypeField[];
|
||||||
|
}
|
||||||
|
>,
|
||||||
|
): Promise<CredentialTypeController> {
|
||||||
|
const pData = z
|
||||||
|
.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
permissionScope: z.string().optional(),
|
||||||
|
icon: z.string().optional(),
|
||||||
|
fields: z.array(z.any()).optional(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
|
.parse(data);
|
||||||
|
|
||||||
|
const updatedCredentialType = await prisma.credentialType.update({
|
||||||
|
where: { id: this.id },
|
||||||
|
data: pData,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateInternalValues(updatedCredentialType);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Field Definition
|
||||||
|
*
|
||||||
|
* Get the definition for a specific field by its ID.
|
||||||
|
*
|
||||||
|
* @param fieldId - The field ID to look up
|
||||||
|
* @returns {CredentialTypeField | undefined} - The field definition or undefined
|
||||||
|
*/
|
||||||
|
getFieldDefinition(fieldId: string): CredentialTypeField | undefined {
|
||||||
|
return this.fields.find((f) => f.id === fieldId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Required Fields
|
||||||
|
*
|
||||||
|
* Returns all fields that are marked as required.
|
||||||
|
*
|
||||||
|
* @returns {CredentialTypeField[]} - Array of required fields
|
||||||
|
*/
|
||||||
|
getRequiredFields(): CredentialTypeField[] {
|
||||||
|
return this.fields.filter((f) => f.required);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Secure Fields
|
||||||
|
*
|
||||||
|
* Returns all fields that should be stored securely (encrypted).
|
||||||
|
*
|
||||||
|
* @returns {CredentialTypeField[]} - Array of secure fields
|
||||||
|
*/
|
||||||
|
getSecureFields(): CredentialTypeField[] {
|
||||||
|
return this.fields.filter((f) => f.secure);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Credentials
|
||||||
|
*
|
||||||
|
* Fetch all credentials that use this credential type.
|
||||||
|
*
|
||||||
|
* @returns {Promise<CredentialController[]>} - Array of credential controllers
|
||||||
|
*/
|
||||||
|
async fetchCredentials(): Promise<CredentialController[]> {
|
||||||
|
const credentials = await prisma.credential.findMany({
|
||||||
|
where: { typeId: this.id },
|
||||||
|
include: {
|
||||||
|
type: true,
|
||||||
|
company: true,
|
||||||
|
securevalues: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return credentials.map((cred) => new CredentialController(cred));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count Credentials
|
||||||
|
*
|
||||||
|
* Count how many credentials use this credential type.
|
||||||
|
*
|
||||||
|
* @returns {number} - Number of credentials using this type
|
||||||
|
*/
|
||||||
|
countCredentials(): number {
|
||||||
|
return this._credentials.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To JSON
|
||||||
|
*
|
||||||
|
* Create an object that can be safely returned to the user.
|
||||||
|
*
|
||||||
|
* @param opts - Options to change the output
|
||||||
|
* @returns - An object that is JSON friendly
|
||||||
|
*/
|
||||||
|
toJson(opts?: { includeCredentialCount?: boolean }) {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
permissionScope: this.permissionScope,
|
||||||
|
icon: this.icon,
|
||||||
|
fields: this.fields,
|
||||||
|
credentialCount: opts?.includeCredentialCount
|
||||||
|
? this._credentials.length
|
||||||
|
: undefined,
|
||||||
|
createdAt: this.createdAt,
|
||||||
|
updatedAt: this.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
import { prisma } from "../constants";
|
||||||
|
import { CredentialTypeController } from "../controllers/CredentialTypeController";
|
||||||
|
import { CredentialTypeField } from "../modules/credentials/credentialTypeDefs";
|
||||||
|
import GenericError from "../Errors/GenericError";
|
||||||
|
|
||||||
|
export const credentialTypes = {
|
||||||
|
/**
|
||||||
|
* Fetch Credential Type
|
||||||
|
*
|
||||||
|
* Fetch a credential type by its ID or name and return a CredentialTypeController instance.
|
||||||
|
*
|
||||||
|
* @param identifier - The credential type ID or name to fetch
|
||||||
|
* @returns {Promise<CredentialTypeController>} - The credential type controller
|
||||||
|
*/
|
||||||
|
async fetch(identifier: string): Promise<CredentialTypeController> {
|
||||||
|
const credentialType = await prisma.credentialType.findFirst({
|
||||||
|
where: {
|
||||||
|
OR: [{ id: identifier }, { name: identifier }],
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
credentials: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!credentialType) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: "Credential type not found",
|
||||||
|
name: "CredentialTypeNotFound",
|
||||||
|
cause: `No credential type exists with identifier '${identifier}'`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CredentialTypeController(credentialType);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch All Credential Types
|
||||||
|
*
|
||||||
|
* Fetch all credential types in the system.
|
||||||
|
*
|
||||||
|
* @returns {Promise<CredentialTypeController[]>} - Array of credential type controllers
|
||||||
|
*/
|
||||||
|
async fetchAll(): Promise<CredentialTypeController[]> {
|
||||||
|
const credentialTypesList = await prisma.credentialType.findMany({
|
||||||
|
include: {
|
||||||
|
credentials: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return credentialTypesList.map((ct) => new CredentialTypeController(ct));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Credential Type
|
||||||
|
*
|
||||||
|
* Create a new credential type with its field definitions.
|
||||||
|
*
|
||||||
|
* @param data - The credential type data to create
|
||||||
|
* @returns {Promise<CredentialTypeController>} - The created credential type controller
|
||||||
|
*/
|
||||||
|
async create(data: {
|
||||||
|
name: string;
|
||||||
|
permissionScope: string;
|
||||||
|
fields: CredentialTypeField[];
|
||||||
|
icon?: string;
|
||||||
|
}): Promise<CredentialTypeController> {
|
||||||
|
// Check if a credential type with this name already exists
|
||||||
|
const existing = await prisma.credentialType.findFirst({
|
||||||
|
where: { name: data.name },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: "Credential type name already exists",
|
||||||
|
name: "CredentialTypeAlreadyExists",
|
||||||
|
cause: `A credential type with name '${data.name}' already exists`,
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const credentialType = await prisma.credentialType.create({
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
permissionScope: data.permissionScope,
|
||||||
|
fields: data.fields as any,
|
||||||
|
icon: data.icon,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
credentials: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return new CredentialTypeController(credentialType);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Credential Type
|
||||||
|
*
|
||||||
|
* Delete a credential type by its ID.
|
||||||
|
* This will cascade delete all credentials of this type.
|
||||||
|
*
|
||||||
|
* @param id - The credential type ID to delete
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async delete(id: string): Promise<void> {
|
||||||
|
await prisma.credentialType.delete({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
import { prisma } from "../constants";
|
||||||
|
import { CredentialController } from "../controllers/CredentialController";
|
||||||
|
import { fieldValidator } from "../modules/credentials/fieldValidator";
|
||||||
|
import {
|
||||||
|
CredentialField,
|
||||||
|
CredentialTypeField,
|
||||||
|
} from "../modules/credentials/credentialTypeDefs";
|
||||||
|
import { generateSecureValue } from "../modules/credentials/generateSecureValue";
|
||||||
|
import GenericError from "../Errors/GenericError";
|
||||||
|
|
||||||
|
export const credentials = {
|
||||||
|
/**
|
||||||
|
* Fetch Credential
|
||||||
|
*
|
||||||
|
* Fetch a credential by its ID and return a CredentialController instance.
|
||||||
|
*
|
||||||
|
* @param id - The credential ID to fetch
|
||||||
|
* @returns {Promise<CredentialController>} - The credential controller
|
||||||
|
*/
|
||||||
|
async fetch(id: string): Promise<CredentialController> {
|
||||||
|
const credential = await prisma.credential.findFirst({
|
||||||
|
where: { id },
|
||||||
|
include: {
|
||||||
|
type: true,
|
||||||
|
company: true,
|
||||||
|
securevalues: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!credential) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: "Credential not found",
|
||||||
|
name: "CredentialNotFound",
|
||||||
|
cause: `No credential exists with ID '${id}'`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CredentialController(credential);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Credentials by Company
|
||||||
|
*
|
||||||
|
* Fetch all credentials associated with a specific company.
|
||||||
|
*
|
||||||
|
* @param companyId - The company ID to fetch credentials for
|
||||||
|
* @returns {Promise<CredentialController[]>} - Array of credential controllers
|
||||||
|
*/
|
||||||
|
async fetchByCompany(companyId: string): Promise<CredentialController[]> {
|
||||||
|
const credentialsList = await prisma.credential.findMany({
|
||||||
|
where: { companyId },
|
||||||
|
include: {
|
||||||
|
type: true,
|
||||||
|
company: true,
|
||||||
|
securevalues: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return credentialsList.map((cred) => new CredentialController(cred));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Credential
|
||||||
|
*
|
||||||
|
* Create a new credential with validated fields.
|
||||||
|
* This method processes all incoming field values, validating them against
|
||||||
|
* the credential type, encrypting secure fields, and inserting everything
|
||||||
|
* into the database atomically.
|
||||||
|
*
|
||||||
|
* @param data - The credential data to create
|
||||||
|
* @returns {Promise<CredentialController>} - The created credential controller
|
||||||
|
*/
|
||||||
|
async create(data: {
|
||||||
|
name: string;
|
||||||
|
typeId: string;
|
||||||
|
companyId: string;
|
||||||
|
fields: CredentialField[];
|
||||||
|
}): Promise<CredentialController> {
|
||||||
|
// Fetch the credential type to get acceptable fields
|
||||||
|
const credentialType = await prisma.credentialType.findFirst({
|
||||||
|
where: { id: data.typeId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!credentialType) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: "Credential type not found",
|
||||||
|
name: "CredentialTypeNotFound",
|
||||||
|
cause: `No credential type exists with ID '${data.typeId}'`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the fields against acceptable fields
|
||||||
|
const acceptableFields = JSON.parse(credentialType.fields! as string).map(
|
||||||
|
(f: { id: string; name: string; secure: boolean }) => ({
|
||||||
|
id: f.id,
|
||||||
|
name: f.name,
|
||||||
|
secure: f.secure,
|
||||||
|
}),
|
||||||
|
) as CredentialTypeField[];
|
||||||
|
const validatedFields = await fieldValidator(data.fields, acceptableFields);
|
||||||
|
|
||||||
|
// Separate secure and non-secure fields
|
||||||
|
const secureFields = validatedFields.filter((f) => f.secure);
|
||||||
|
const nonSecureFields = validatedFields.filter((f) => !f.secure);
|
||||||
|
|
||||||
|
// Build fields object for non-secure fields
|
||||||
|
const fieldsObject: Record<string, any> = {};
|
||||||
|
nonSecureFields.forEach((field) => {
|
||||||
|
fieldsObject[field.fieldId] = field.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Encrypt secure field values
|
||||||
|
const secureValueData = secureFields.map((field) => {
|
||||||
|
const { encrypted, hash } = generateSecureValue(field.value);
|
||||||
|
return {
|
||||||
|
name: field.fieldId,
|
||||||
|
content: encrypted,
|
||||||
|
hash,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create credential and all secure values in a transaction
|
||||||
|
const credential = await prisma.credential.create({
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
typeId: data.typeId,
|
||||||
|
companyId: data.companyId,
|
||||||
|
fields: fieldsObject,
|
||||||
|
securevalues: {
|
||||||
|
create: secureValueData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
type: true,
|
||||||
|
company: true,
|
||||||
|
securevalues: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return new CredentialController(credential);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Credential
|
||||||
|
*
|
||||||
|
* Delete a credential by its ID.
|
||||||
|
*
|
||||||
|
* @param id - The credential ID to delete
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async delete(id: string): Promise<void> {
|
||||||
|
await prisma.credential.delete({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
export enum ValueType {
|
||||||
|
PLAIN_TEXT = "plain_text",
|
||||||
|
PASSWORD = "password",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CredentialTypeField {
|
||||||
|
id: string; // I.e. "clientId", "clientSecret", etc.
|
||||||
|
name: string; // I.e. "Client ID", "Client Secret", etc.
|
||||||
|
required: boolean;
|
||||||
|
secure: boolean; // Whether this field should be stored encrypted in the database
|
||||||
|
valueType: ValueType; // For future extensibility, currently all fields are strings
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CredentialField {
|
||||||
|
id: string; // CUID
|
||||||
|
fieldId: string; // I.e. "clientId", "clientSecret", etc.
|
||||||
|
value: string; // Encrypted value stored in the database
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { Collection } from "@discordjs/collection";
|
||||||
|
import { CredentialField, CredentialTypeField } from "./credentialTypeDefs";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field Validator
|
||||||
|
*
|
||||||
|
* This method will take a record of the fields being submitted and compare them against a record of the acceptable fields
|
||||||
|
* for a credential type. If any of the submitted fields do not match an acceptable field, an error will be thrown.
|
||||||
|
*
|
||||||
|
* If all the credentials pass, it will return a processed version of the submitted fields including fields that need to be
|
||||||
|
* stored securely (encrypted) and fields that do not.
|
||||||
|
*
|
||||||
|
* @param fields - The fields in object form that are being submitted.
|
||||||
|
* @param acceptableFields - The acceptable field to be compared against.
|
||||||
|
*/
|
||||||
|
export const fieldValidator = async (
|
||||||
|
fields: CredentialField[],
|
||||||
|
acceptableFields: CredentialTypeField[],
|
||||||
|
): Promise<
|
||||||
|
{
|
||||||
|
id: string;
|
||||||
|
fieldId: string;
|
||||||
|
value: string;
|
||||||
|
secure: boolean;
|
||||||
|
}[]
|
||||||
|
> => {
|
||||||
|
const afCollection = new Collection(acceptableFields.map((f) => [f.id, f]));
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
fields.map(async (field) => {
|
||||||
|
const matchingField = afCollection.get(field.fieldId);
|
||||||
|
if (!matchingField) {
|
||||||
|
throw new GenericError({
|
||||||
|
message: `Invalid field ID: ${field.fieldId}`,
|
||||||
|
name: "InvalidCredentialField",
|
||||||
|
cause: `No acceptable field with ID '${field.fieldId}' found.`,
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return fields.map((field) => {
|
||||||
|
const matchingField = afCollection.get(field.fieldId)!;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: field.id,
|
||||||
|
fieldId: field.fieldId,
|
||||||
|
value: field.value,
|
||||||
|
secure: matchingField.secure,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import Password from "../tools/Password";
|
||||||
|
import crypto from "crypto";
|
||||||
|
import { secureValuesPublicKey } from "../../constants";
|
||||||
|
|
||||||
|
export const generateSecureValue = (content: string) => {
|
||||||
|
// Generate a hash of the content
|
||||||
|
const hash = Password.hash(content);
|
||||||
|
|
||||||
|
// Encrypt the content using the .secureValues.pub public key
|
||||||
|
const encrypted = crypto.publicEncrypt(
|
||||||
|
{
|
||||||
|
key: secureValuesPublicKey,
|
||||||
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
|
oaepHash: "sha256",
|
||||||
|
},
|
||||||
|
Buffer.from(content, "utf-8"),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return the encrypted content and the hash for storage
|
||||||
|
return {
|
||||||
|
encrypted: encrypted.toString("base64"),
|
||||||
|
hash,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import Password from "../tools/Password";
|
||||||
|
import crypto from "crypto";
|
||||||
|
import { secureValuesPrivateKey } from "../../constants";
|
||||||
|
|
||||||
|
export const readSecureValue = (
|
||||||
|
encryptedContent: string,
|
||||||
|
hash?: string,
|
||||||
|
): string => {
|
||||||
|
// Decrypt the content using the .secureValues.key private key
|
||||||
|
const decrypted = crypto.privateDecrypt(
|
||||||
|
{
|
||||||
|
key: secureValuesPrivateKey,
|
||||||
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
|
oaepHash: "sha256",
|
||||||
|
},
|
||||||
|
Buffer.from(encryptedContent, "base64"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = decrypted.toString("utf-8");
|
||||||
|
|
||||||
|
// Optionally validate the hash if provided
|
||||||
|
if (hash) {
|
||||||
|
const isValid = Password.validate(content, hash);
|
||||||
|
if (!isValid) {
|
||||||
|
throw new Error("Secure value hash validation failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
};
|
||||||
@@ -10,7 +10,10 @@ export default class Password {
|
|||||||
|
|
||||||
public static hash(password: string, options?: HashPasswordOptions): string {
|
public static hash(password: string, options?: HashPasswordOptions): string {
|
||||||
const salt =
|
const salt =
|
||||||
options?.overrideSalt ?? Password.generateSalt(options?.saltOpts);
|
options?.overrideSalt ??
|
||||||
|
(options?.saltOpts?.length
|
||||||
|
? Password.generateSalt(options?.saltOpts)
|
||||||
|
: "");
|
||||||
const hash = blake2sHex(`$BLAKE2s$${password}$${salt}`);
|
const hash = blake2sHex(`$BLAKE2s$${password}$${salt}`);
|
||||||
return `BLAKE2s$${hash}$${salt}`;
|
return `BLAKE2s$${hash}$${salt}`;
|
||||||
}
|
}
|
||||||
@@ -19,7 +22,7 @@ export default class Password {
|
|||||||
const [algo, oldHash, salt] = hashed.split(/\$/g);
|
const [algo, oldHash, salt] = hashed.split(/\$/g);
|
||||||
return crypto.timingSafeEqual(
|
return crypto.timingSafeEqual(
|
||||||
Buffer.from(hashed),
|
Buffer.from(hashed),
|
||||||
Buffer.from(Password.hash(newPass, { overrideSalt: salt }))
|
Buffer.from(Password.hash(newPass, { overrideSalt: salt })),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-13
@@ -7,31 +7,50 @@ This script will go through and genrate all the keys necessary for running the C
|
|||||||
This process might take several minutes.
|
This process might take several minutes.
|
||||||
-----------------`);
|
-----------------`);
|
||||||
|
|
||||||
await Promise.all(
|
const keyFiles = [
|
||||||
[
|
|
||||||
".accessToken.key",
|
".accessToken.key",
|
||||||
".refreshToken.key",
|
".refreshToken.key",
|
||||||
".permissions.key",
|
".permissions.key",
|
||||||
".apiKeyToken.key",
|
".secureValues.key",
|
||||||
].map(async (v) => {
|
];
|
||||||
if (
|
|
||||||
await Bun.file(v)
|
const publicDir = "public-keys";
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
keyFiles.map(async (v) => {
|
||||||
|
const privExists = await Bun.file(v)
|
||||||
.exists()
|
.exists()
|
||||||
.then((bool) => {
|
.then((bool) => {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
console.log(`'${v}' already exists`);
|
console.log(`'${v}' already exists`);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
})
|
}
|
||||||
) {
|
return false;
|
||||||
console.log(`Generating '${v}'...`);
|
});
|
||||||
const keys = keypair({ bits: 4096 });
|
|
||||||
|
|
||||||
|
const pubPath = `${publicDir}/${v.replace(/\.key$/, ".pub")}`;
|
||||||
|
const pubExists = await Bun.file(pubPath)
|
||||||
|
.exists()
|
||||||
|
.then((bool) => {
|
||||||
|
if (bool) {
|
||||||
|
console.log(`'${pubPath}' already exists`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!privExists || !pubExists) {
|
||||||
|
console.log(`Generating '${v}' and '${pubPath}'...`);
|
||||||
|
const keys = keypair({ bits: 4096 });
|
||||||
|
if (!privExists) {
|
||||||
await Bun.write(v, keys.private);
|
await Bun.write(v, keys.private);
|
||||||
}
|
}
|
||||||
|
if (!pubExists) {
|
||||||
|
await Bun.write(pubPath, keys.public);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("\nGenerated All Keys Successfully!");
|
console.log("\nGenerated All Keys Successfully!");
|
||||||
|
|||||||
Reference in New Issue
Block a user