a lot of things
This commit is contained in:
+449
-11
@@ -199,6 +199,273 @@ Check if the currently authenticated user has specific permissions. Accepts an a
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Other User Routes
|
||||||
|
|
||||||
|
### Get All Users
|
||||||
|
|
||||||
|
**GET** `/user/users`
|
||||||
|
|
||||||
|
Fetch a list of all users.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.read.other`, `user.list.other`
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Users Fetched Successfully!",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "ckx...",
|
||||||
|
"name": "John Doe",
|
||||||
|
"email": "john.doe@example.com",
|
||||||
|
"login": "john.doe",
|
||||||
|
"image": "https://...",
|
||||||
|
"roles": ["admin"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Get User by ID
|
||||||
|
|
||||||
|
**GET** `/user/users/:identifier`
|
||||||
|
|
||||||
|
Fetch a specific user by their ID.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.read.other`
|
||||||
|
|
||||||
|
**Path Parameters:**
|
||||||
|
|
||||||
|
- `identifier` - The user's ID
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "User Fetched Successfully!",
|
||||||
|
"data": {
|
||||||
|
"id": "ckx...",
|
||||||
|
"name": "John Doe",
|
||||||
|
"email": "john.doe@example.com",
|
||||||
|
"login": "john.doe",
|
||||||
|
"image": "https://...",
|
||||||
|
"roles": ["admin"]
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Response (404):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 404,
|
||||||
|
"message": "User with identifier 'ckx...' was not found.",
|
||||||
|
"error": "UserNotFound",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Update User by ID
|
||||||
|
|
||||||
|
**PATCH** `/user/users/:identifier`
|
||||||
|
|
||||||
|
Update a specific user's information. Supports updating profile fields, roles, and direct permissions.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.write.other`
|
||||||
|
|
||||||
|
**Conditional Permissions:**
|
||||||
|
|
||||||
|
- If `roles` is included in the body: `user.roles.other` is also required
|
||||||
|
- If `permissions` is included in the body: `user.permissions.other` is also required
|
||||||
|
|
||||||
|
**Path Parameters:**
|
||||||
|
|
||||||
|
- `identifier` - The user's ID
|
||||||
|
|
||||||
|
**Request Body:**
|
||||||
|
|
||||||
|
All fields are optional. Include only the fields you want to update.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Jane Doe",
|
||||||
|
"image": "https://example.com/avatar.jpg",
|
||||||
|
"roles": ["admin", "moderator"],
|
||||||
|
"permissions": ["credential.fetch", "company.fetch"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
| ------------- | ---------- | -------------------------------------------------------------- |
|
||||||
|
| `name` | `string` | The user's display name |
|
||||||
|
| `image` | `string` | URL to the user's avatar image |
|
||||||
|
| `roles` | `string[]` | Array of role ids or monikers to assign (replaces all roles) |
|
||||||
|
| `permissions` | `string[]` | Array of permission nodes to assign (replaces all permissions) |
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "User Updated Successfully!",
|
||||||
|
"data": {
|
||||||
|
"id": "ckx...",
|
||||||
|
"name": "Jane Doe",
|
||||||
|
"email": "jane.doe@example.com",
|
||||||
|
"login": "jane.doe",
|
||||||
|
"image": "https://example.com/avatar.jpg",
|
||||||
|
"roles": ["admin", "moderator"]
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Response (403 - Missing role permission):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 403,
|
||||||
|
"message": "You do not have permission to modify roles on another user.",
|
||||||
|
"error": "InsufficientPermission",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Delete User by ID
|
||||||
|
|
||||||
|
**DELETE** `/user/users/:identifier`
|
||||||
|
|
||||||
|
Delete a specific user.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.delete.other`
|
||||||
|
|
||||||
|
**Path Parameters:**
|
||||||
|
|
||||||
|
- `identifier` - The user's ID
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "User Deleted Successfully!",
|
||||||
|
"data": {
|
||||||
|
"id": "ckx...",
|
||||||
|
"name": "John Doe",
|
||||||
|
"email": "john.doe@example.com",
|
||||||
|
"login": "john.doe",
|
||||||
|
"image": "https://...",
|
||||||
|
"roles": ["admin"]
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Get User Roles
|
||||||
|
|
||||||
|
**GET** `/user/users/:identifier/roles`
|
||||||
|
|
||||||
|
Fetch all roles assigned to a specific user.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.read.other`, `role.read`
|
||||||
|
|
||||||
|
**Path Parameters:**
|
||||||
|
|
||||||
|
- `identifier` - The user's ID
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "User Roles Fetched Successfully!",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "uuid...",
|
||||||
|
"title": "Administrator",
|
||||||
|
"moniker": "admin",
|
||||||
|
"permissions": ["*"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Check User Permissions (Other User)
|
||||||
|
|
||||||
|
**POST** `/user/users/:identifier/check-permission`
|
||||||
|
|
||||||
|
Check if a specific user has certain permissions.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `user.read.other`
|
||||||
|
|
||||||
|
**Path Parameters:**
|
||||||
|
|
||||||
|
- `identifier` - The user's ID
|
||||||
|
|
||||||
|
**Request Body:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"permissions": ["user.read", "company.fetch", "credential.write"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Permission check completed.",
|
||||||
|
"data": {
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"permission": "user.read",
|
||||||
|
"hasPermission": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"permission": "company.fetch",
|
||||||
|
"hasPermission": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"permission": "credential.write",
|
||||||
|
"hasPermission": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Company Routes
|
## Company Routes
|
||||||
|
|
||||||
### Get All Companies
|
### Get All Companies
|
||||||
@@ -342,6 +609,34 @@ Fetch configurations for a specific company from ConnectWise.
|
|||||||
|
|
||||||
## Credential Routes
|
## Credential Routes
|
||||||
|
|
||||||
|
### Get Value Types
|
||||||
|
|
||||||
|
**GET** `/credential/valuetypes`
|
||||||
|
|
||||||
|
Returns all available field value types for credential type fields.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Value Types Fetched Successfully!",
|
||||||
|
"data": [
|
||||||
|
"plain_text",
|
||||||
|
"license_key",
|
||||||
|
"ip_address",
|
||||||
|
"generic_secret",
|
||||||
|
"bitlocker_key",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Get Credential by ID
|
### Get Credential by ID
|
||||||
|
|
||||||
**GET** `/credential/credentials/:id`
|
**GET** `/credential/credentials/:id`
|
||||||
@@ -365,11 +660,27 @@ Fetch a single credential by its ID.
|
|||||||
"data": {
|
"data": {
|
||||||
"id": "ckx...",
|
"id": "ckx...",
|
||||||
"name": "AWS Credentials",
|
"name": "AWS Credentials",
|
||||||
|
"notes": null,
|
||||||
"typeId": "cky...",
|
"typeId": "cky...",
|
||||||
"companyId": "ckz...",
|
"companyId": "ckz...",
|
||||||
"fields": {
|
"fields": [
|
||||||
"accountId": "123456789"
|
{
|
||||||
},
|
"id": "accessKeyId",
|
||||||
|
"name": "Access Key ID",
|
||||||
|
"secure": false,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "plain_text",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "secretAccessKey",
|
||||||
|
"name": "Secret Access Key",
|
||||||
|
"secure": true,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "password",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"type": {
|
"type": {
|
||||||
"id": "cky...",
|
"id": "cky...",
|
||||||
"name": "AWS",
|
"name": "AWS",
|
||||||
@@ -413,9 +724,27 @@ Fetch all credentials associated with a specific company.
|
|||||||
{
|
{
|
||||||
"id": "ckx...",
|
"id": "ckx...",
|
||||||
"name": "AWS Credentials",
|
"name": "AWS Credentials",
|
||||||
|
"notes": null,
|
||||||
"typeId": "cky...",
|
"typeId": "cky...",
|
||||||
"companyId": "ckz...",
|
"companyId": "ckz...",
|
||||||
"fields": {...},
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "accessKeyId",
|
||||||
|
"name": "Access Key ID",
|
||||||
|
"secure": false,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "plain_text",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "secretAccessKey",
|
||||||
|
"name": "Secret Access Key",
|
||||||
|
"secure": true,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "password",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"type": {...},
|
"type": {...},
|
||||||
"company": {...}
|
"company": {...}
|
||||||
}
|
}
|
||||||
@@ -441,6 +770,7 @@ Create a new credential with validated and encrypted fields.
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Production AWS Credentials",
|
"name": "Production AWS Credentials",
|
||||||
|
"notes": "Used for production S3 access",
|
||||||
"typeId": "cky...",
|
"typeId": "cky...",
|
||||||
"companyId": "ckz...",
|
"companyId": "ckz...",
|
||||||
"fields": [
|
"fields": [
|
||||||
@@ -469,7 +799,26 @@ Create a new credential with validated and encrypted fields.
|
|||||||
"name": "Production AWS Credentials",
|
"name": "Production AWS Credentials",
|
||||||
"typeId": "cky...",
|
"typeId": "cky...",
|
||||||
"companyId": "ckz...",
|
"companyId": "ckz...",
|
||||||
"fields": {...}
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "accessKeyId",
|
||||||
|
"name": "Access Key ID",
|
||||||
|
"secure": false,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "plain_text",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "secretAccessKey",
|
||||||
|
"name": "Secret Access Key",
|
||||||
|
"secure": true,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "password",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": {...},
|
||||||
|
"company": {...}
|
||||||
},
|
},
|
||||||
"successful": true
|
"successful": true
|
||||||
}
|
}
|
||||||
@@ -481,7 +830,7 @@ Create a new credential with validated and encrypted fields.
|
|||||||
|
|
||||||
**PATCH** `/credential/credentials/:id`
|
**PATCH** `/credential/credentials/:id`
|
||||||
|
|
||||||
Update a credential's basic properties (name).
|
Update a credential's basic properties (name, notes) and/or field values. Secure fields are automatically encrypted.
|
||||||
|
|
||||||
**Authentication Required:** Yes
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
@@ -493,9 +842,22 @@ Update a credential's basic properties (name).
|
|||||||
|
|
||||||
**Request Body:**
|
**Request Body:**
|
||||||
|
|
||||||
|
All properties are optional. Include only the properties you want to update.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Updated Credential Name"
|
"name": "Updated Credential Name",
|
||||||
|
"notes": "Updated notes for this credential",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldId": "accessKeyId",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldId": "secretAccessKey",
|
||||||
|
"value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -508,7 +870,21 @@ Update a credential's basic properties (name).
|
|||||||
"data": {
|
"data": {
|
||||||
"id": "ckx...",
|
"id": "ckx...",
|
||||||
"name": "Updated Credential Name",
|
"name": "Updated Credential Name",
|
||||||
...
|
"notes": "Updated notes for this credential",
|
||||||
|
"typeId": "cky...",
|
||||||
|
"companyId": "ckz...",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "accessKeyId",
|
||||||
|
"name": "Access Key ID",
|
||||||
|
"secure": false,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "plain_text",
|
||||||
|
"value": "AKIAIOSFODNN7EXAMPLE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": {...},
|
||||||
|
"company": {...}
|
||||||
},
|
},
|
||||||
"successful": true
|
"successful": true
|
||||||
}
|
}
|
||||||
@@ -536,12 +912,10 @@ Validate and update credential field values. Secure fields are automatically enc
|
|||||||
{
|
{
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"id": "ckx1...",
|
|
||||||
"fieldId": "accessKeyId",
|
"fieldId": "accessKeyId",
|
||||||
"value": "AKIAIOSFODNN7NEWVALUE"
|
"value": "AKIAIOSFODNN7NEWVALUE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ckx2...",
|
|
||||||
"fieldId": "secretAccessKey",
|
"fieldId": "secretAccessKey",
|
||||||
"value": "newSecretKeyValue123"
|
"value": "newSecretKeyValue123"
|
||||||
}
|
}
|
||||||
@@ -558,7 +932,29 @@ Validate and update credential field values. Secure fields are automatically enc
|
|||||||
"data": {
|
"data": {
|
||||||
"id": "ckx...",
|
"id": "ckx...",
|
||||||
"name": "Production AWS Credentials",
|
"name": "Production AWS Credentials",
|
||||||
"fields": {...}
|
"notes": null,
|
||||||
|
"typeId": "cky...",
|
||||||
|
"companyId": "ckz...",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"id": "accessKeyId",
|
||||||
|
"name": "Access Key ID",
|
||||||
|
"secure": false,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "plain_text",
|
||||||
|
"value": "AKIAIOSFODNN7NEWVALUE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "secretAccessKey",
|
||||||
|
"name": "Secret Access Key",
|
||||||
|
"secure": true,
|
||||||
|
"required": true,
|
||||||
|
"valueType": "password",
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": {...},
|
||||||
|
"company": {...}
|
||||||
},
|
},
|
||||||
"successful": true
|
"successful": true
|
||||||
}
|
}
|
||||||
@@ -634,6 +1030,48 @@ Decrypt and return all secure field values for a credential.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Read Single Secure Value
|
||||||
|
|
||||||
|
**GET** `/credential/credentials/:id/secure-values/:fieldId`
|
||||||
|
|
||||||
|
Decrypt and return a single secure field value for a credential.
|
||||||
|
|
||||||
|
**Authentication Required:** Yes
|
||||||
|
|
||||||
|
**Required Permissions:** `credential.fetch`, `credential.secure_values.read`
|
||||||
|
|
||||||
|
**URL Parameters:**
|
||||||
|
|
||||||
|
- `id` - Credential ID
|
||||||
|
- `fieldId` - The field ID of the secure value to read
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 200,
|
||||||
|
"message": "Secure Value Fetched Successfully!",
|
||||||
|
"data": {
|
||||||
|
"fieldId": "secretAccessKey",
|
||||||
|
"value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||||
|
},
|
||||||
|
"successful": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Error Response (404):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": 404,
|
||||||
|
"message": "Secure field not found: unknownField",
|
||||||
|
"error": "SecureFieldNotFound",
|
||||||
|
"successful": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Delete Credential
|
### Delete Credential
|
||||||
|
|
||||||
**DELETE** `/credential/credentials/:id`
|
**DELETE** `/credential/credentials/:id`
|
||||||
|
|||||||
+20
-14
@@ -32,16 +32,16 @@ The permission validator supports special tokens for flexible permission managem
|
|||||||
|
|
||||||
### Credential Permissions
|
### Credential Permissions
|
||||||
|
|
||||||
| Permission Node | Description | Used In |
|
| Permission Node | Description | Used In |
|
||||||
| ------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
|
| ------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `credential.create` | Create a new credential | [src/api/credentials/create.ts](src/api/credentials/create.ts) |
|
| `credential.create` | Create a new credential | [src/api/credentials/create.ts](src/api/credentials/create.ts) |
|
||||||
| `credential.fetch` | Fetch a single credential | [src/api/credentials/fetch.ts](src/api/credentials/fetch.ts) |
|
| `credential.fetch` | Fetch a single credential | [src/api/credentials/fetch.ts](src/api/credentials/fetch.ts) |
|
||||||
| `credential.fetch.many` | Fetch multiple credentials | [src/api/credentials/fetchByCompany.ts](src/api/credentials/fetchByCompany.ts) |
|
| `credential.fetch.many` | Fetch multiple credentials | [src/api/credentials/fetchByCompany.ts](src/api/credentials/fetchByCompany.ts) |
|
||||||
| `credential.update` | Update a credential | [src/api/credentials/update.ts](src/api/credentials/update.ts) |
|
| `credential.update` | Update a credential | [src/api/credentials/update.ts](src/api/credentials/update.ts) |
|
||||||
| `credential.delete` | Delete a credential | [src/api/credentials/delete.ts](src/api/credentials/delete.ts) |
|
| `credential.delete` | Delete a credential | [src/api/credentials/delete.ts](src/api/credentials/delete.ts) |
|
||||||
| `credential.fields.fetch` | Fetch credential fields (requires `credential.fetch` as well) | [src/api/credentials/fetchFields.ts](src/api/credentials/fetchFields.ts) |
|
| `credential.fields.fetch` | Fetch credential fields (requires `credential.fetch` as well) | [src/api/credentials/fetchFields.ts](src/api/credentials/fetchFields.ts) |
|
||||||
| `credential.fields.update` | Update credential fields (requires `credential.update` as well) | [src/api/credentials/updateFields.ts](src/api/credentials/updateFields.ts) |
|
| `credential.fields.update` | Update credential fields (requires `credential.update` as well) | [src/api/credentials/updateFields.ts](src/api/credentials/updateFields.ts) |
|
||||||
| `credential.secure_values.read` | Read secure values of a credential (requires `credential.fetch` as well) | [src/api/credentials/readSecureValues.ts](src/api/credentials/readSecureValues.ts) |
|
| `credential.secure_values.read` | Read secure values of a credential (requires `credential.fetch` as well) | [src/api/credentials/readSecureValues.ts](src/api/credentials/readSecureValues.ts), [src/api/credentials/readSecureValue.ts](src/api/credentials/readSecureValue.ts) |
|
||||||
|
|
||||||
### Credential Type Permissions
|
### Credential Type Permissions
|
||||||
|
|
||||||
@@ -66,10 +66,16 @@ The permission validator supports special tokens for flexible permission managem
|
|||||||
|
|
||||||
### User Permissions
|
### User Permissions
|
||||||
|
|
||||||
| Permission Node | Description | Used In |
|
| Permission Node | Description | Used In | Dependencies |
|
||||||
| --------------- | ----------------------- | -------------------------------------------------------- |
|
| ------------------------ | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||||
| `user.read` | Read user information | [src/api/user/@me/fetch.ts](src/api/user/@me/fetch.ts) |
|
| `user.read` | Read user information | [src/api/user/@me/fetch.ts](src/api/user/@me/fetch.ts) | |
|
||||||
| `user.write` | Update user information | [src/api/user/@me/update.ts](src/api/user/@me/update.ts) |
|
| `user.write` | Update user information | [src/api/user/@me/update.ts](src/api/user/@me/update.ts) | |
|
||||||
|
| `user.read.other` | Read other users' information | [src/api/user/fetch.ts](src/api/user/fetch.ts), [src/api/user/fetchRoles.ts](src/api/user/fetchRoles.ts), [src/api/user/checkPermission.ts](src/api/user/checkPermission.ts) | |
|
||||||
|
| `user.list.other` | List all users | [src/api/user/fetchAll.ts](src/api/user/fetchAll.ts) | `user.read.other` |
|
||||||
|
| `user.write.other` | Update other users' information | [src/api/user/update.ts](src/api/user/update.ts) | |
|
||||||
|
| `user.roles.other` | Modify roles assigned to other users | [src/api/user/update.ts](src/api/user/update.ts) | `user.write.other` |
|
||||||
|
| `user.permissions.other` | Modify direct permissions assigned to other users | [src/api/user/update.ts](src/api/user/update.ts) | `user.write.other` |
|
||||||
|
| `user.delete.other` | Delete other users | [src/api/user/delete.ts](src/api/user/delete.ts) | |
|
||||||
|
|
||||||
### Permission Routes
|
### Permission Routes
|
||||||
|
|
||||||
|
|||||||
@@ -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 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",
|
"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 notes 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\":\"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\":{}}")
|
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\":\"notes\",\"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')
|
||||||
|
|||||||
@@ -1050,6 +1050,7 @@ export type SecureValueScalarFieldEnum = (typeof SecureValueScalarFieldEnum)[key
|
|||||||
export const CredentialScalarFieldEnum = {
|
export const CredentialScalarFieldEnum = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
|
notes: 'notes',
|
||||||
typeId: 'typeId',
|
typeId: 'typeId',
|
||||||
fields: 'fields',
|
fields: 'fields',
|
||||||
companyId: 'companyId',
|
companyId: 'companyId',
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ export type SecureValueScalarFieldEnum = (typeof SecureValueScalarFieldEnum)[key
|
|||||||
export const CredentialScalarFieldEnum = {
|
export const CredentialScalarFieldEnum = {
|
||||||
id: 'id',
|
id: 'id',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
|
notes: 'notes',
|
||||||
typeId: 'typeId',
|
typeId: 'typeId',
|
||||||
fields: 'fields',
|
fields: 'fields',
|
||||||
companyId: 'companyId',
|
companyId: 'companyId',
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export type AggregateCredential = {
|
|||||||
export type CredentialMinAggregateOutputType = {
|
export type CredentialMinAggregateOutputType = {
|
||||||
id: string | null
|
id: string | null
|
||||||
name: string | null
|
name: string | null
|
||||||
|
notes: string | null
|
||||||
typeId: string | null
|
typeId: string | null
|
||||||
companyId: string | null
|
companyId: string | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
@@ -36,6 +37,7 @@ export type CredentialMinAggregateOutputType = {
|
|||||||
export type CredentialMaxAggregateOutputType = {
|
export type CredentialMaxAggregateOutputType = {
|
||||||
id: string | null
|
id: string | null
|
||||||
name: string | null
|
name: string | null
|
||||||
|
notes: string | null
|
||||||
typeId: string | null
|
typeId: string | null
|
||||||
companyId: string | null
|
companyId: string | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
@@ -45,6 +47,7 @@ export type CredentialMaxAggregateOutputType = {
|
|||||||
export type CredentialCountAggregateOutputType = {
|
export type CredentialCountAggregateOutputType = {
|
||||||
id: number
|
id: number
|
||||||
name: number
|
name: number
|
||||||
|
notes: number
|
||||||
typeId: number
|
typeId: number
|
||||||
fields: number
|
fields: number
|
||||||
companyId: number
|
companyId: number
|
||||||
@@ -57,6 +60,7 @@ export type CredentialCountAggregateOutputType = {
|
|||||||
export type CredentialMinAggregateInputType = {
|
export type CredentialMinAggregateInputType = {
|
||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
|
notes?: true
|
||||||
typeId?: true
|
typeId?: true
|
||||||
companyId?: true
|
companyId?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
@@ -66,6 +70,7 @@ export type CredentialMinAggregateInputType = {
|
|||||||
export type CredentialMaxAggregateInputType = {
|
export type CredentialMaxAggregateInputType = {
|
||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
|
notes?: true
|
||||||
typeId?: true
|
typeId?: true
|
||||||
companyId?: true
|
companyId?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
@@ -75,6 +80,7 @@ export type CredentialMaxAggregateInputType = {
|
|||||||
export type CredentialCountAggregateInputType = {
|
export type CredentialCountAggregateInputType = {
|
||||||
id?: true
|
id?: true
|
||||||
name?: true
|
name?: true
|
||||||
|
notes?: true
|
||||||
typeId?: true
|
typeId?: true
|
||||||
fields?: true
|
fields?: true
|
||||||
companyId?: true
|
companyId?: true
|
||||||
@@ -158,6 +164,7 @@ export type CredentialGroupByArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
|||||||
export type CredentialGroupByOutputType = {
|
export type CredentialGroupByOutputType = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
|
notes: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: runtime.JsonValue
|
fields: runtime.JsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
@@ -189,6 +196,7 @@ export type CredentialWhereInput = {
|
|||||||
NOT?: Prisma.CredentialWhereInput | Prisma.CredentialWhereInput[]
|
NOT?: Prisma.CredentialWhereInput | Prisma.CredentialWhereInput[]
|
||||||
id?: Prisma.StringFilter<"Credential"> | string
|
id?: Prisma.StringFilter<"Credential"> | string
|
||||||
name?: Prisma.StringFilter<"Credential"> | string
|
name?: Prisma.StringFilter<"Credential"> | string
|
||||||
|
notes?: Prisma.StringNullableFilter<"Credential"> | string | null
|
||||||
typeId?: Prisma.StringFilter<"Credential"> | string
|
typeId?: Prisma.StringFilter<"Credential"> | string
|
||||||
fields?: Prisma.JsonFilter<"Credential">
|
fields?: Prisma.JsonFilter<"Credential">
|
||||||
companyId?: Prisma.StringFilter<"Credential"> | string
|
companyId?: Prisma.StringFilter<"Credential"> | string
|
||||||
@@ -202,6 +210,7 @@ export type CredentialWhereInput = {
|
|||||||
export type CredentialOrderByWithRelationInput = {
|
export type CredentialOrderByWithRelationInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
|
notes?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
typeId?: Prisma.SortOrder
|
typeId?: Prisma.SortOrder
|
||||||
fields?: Prisma.SortOrder
|
fields?: Prisma.SortOrder
|
||||||
companyId?: Prisma.SortOrder
|
companyId?: Prisma.SortOrder
|
||||||
@@ -218,6 +227,7 @@ export type CredentialWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
OR?: Prisma.CredentialWhereInput[]
|
OR?: Prisma.CredentialWhereInput[]
|
||||||
NOT?: Prisma.CredentialWhereInput | Prisma.CredentialWhereInput[]
|
NOT?: Prisma.CredentialWhereInput | Prisma.CredentialWhereInput[]
|
||||||
name?: Prisma.StringFilter<"Credential"> | string
|
name?: Prisma.StringFilter<"Credential"> | string
|
||||||
|
notes?: Prisma.StringNullableFilter<"Credential"> | string | null
|
||||||
typeId?: Prisma.StringFilter<"Credential"> | string
|
typeId?: Prisma.StringFilter<"Credential"> | string
|
||||||
fields?: Prisma.JsonFilter<"Credential">
|
fields?: Prisma.JsonFilter<"Credential">
|
||||||
companyId?: Prisma.StringFilter<"Credential"> | string
|
companyId?: Prisma.StringFilter<"Credential"> | string
|
||||||
@@ -231,6 +241,7 @@ export type CredentialWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
export type CredentialOrderByWithAggregationInput = {
|
export type CredentialOrderByWithAggregationInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
|
notes?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
typeId?: Prisma.SortOrder
|
typeId?: Prisma.SortOrder
|
||||||
fields?: Prisma.SortOrder
|
fields?: Prisma.SortOrder
|
||||||
companyId?: Prisma.SortOrder
|
companyId?: Prisma.SortOrder
|
||||||
@@ -247,6 +258,7 @@ export type CredentialScalarWhereWithAggregatesInput = {
|
|||||||
NOT?: Prisma.CredentialScalarWhereWithAggregatesInput | Prisma.CredentialScalarWhereWithAggregatesInput[]
|
NOT?: Prisma.CredentialScalarWhereWithAggregatesInput | Prisma.CredentialScalarWhereWithAggregatesInput[]
|
||||||
id?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
id?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
||||||
name?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
name?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
||||||
|
notes?: Prisma.StringNullableWithAggregatesFilter<"Credential"> | string | null
|
||||||
typeId?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
typeId?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
||||||
fields?: Prisma.JsonWithAggregatesFilter<"Credential">
|
fields?: Prisma.JsonWithAggregatesFilter<"Credential">
|
||||||
companyId?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
companyId?: Prisma.StringWithAggregatesFilter<"Credential"> | string
|
||||||
@@ -257,6 +269,7 @@ export type CredentialScalarWhereWithAggregatesInput = {
|
|||||||
export type CredentialCreateInput = {
|
export type CredentialCreateInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
@@ -268,6 +281,7 @@ export type CredentialCreateInput = {
|
|||||||
export type CredentialUncheckedCreateInput = {
|
export type CredentialUncheckedCreateInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
@@ -279,6 +293,7 @@ export type CredentialUncheckedCreateInput = {
|
|||||||
export type CredentialUpdateInput = {
|
export type CredentialUpdateInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -290,6 +305,7 @@ export type CredentialUpdateInput = {
|
|||||||
export type CredentialUncheckedUpdateInput = {
|
export type CredentialUncheckedUpdateInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -301,6 +317,7 @@ export type CredentialUncheckedUpdateInput = {
|
|||||||
export type CredentialCreateManyInput = {
|
export type CredentialCreateManyInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
@@ -311,6 +328,7 @@ export type CredentialCreateManyInput = {
|
|||||||
export type CredentialUpdateManyMutationInput = {
|
export type CredentialUpdateManyMutationInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -319,6 +337,7 @@ export type CredentialUpdateManyMutationInput = {
|
|||||||
export type CredentialUncheckedUpdateManyInput = {
|
export type CredentialUncheckedUpdateManyInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -344,6 +363,7 @@ export type CredentialScalarRelationFilter = {
|
|||||||
export type CredentialCountOrderByAggregateInput = {
|
export type CredentialCountOrderByAggregateInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
|
notes?: Prisma.SortOrder
|
||||||
typeId?: Prisma.SortOrder
|
typeId?: Prisma.SortOrder
|
||||||
fields?: Prisma.SortOrder
|
fields?: Prisma.SortOrder
|
||||||
companyId?: Prisma.SortOrder
|
companyId?: Prisma.SortOrder
|
||||||
@@ -354,6 +374,7 @@ export type CredentialCountOrderByAggregateInput = {
|
|||||||
export type CredentialMaxOrderByAggregateInput = {
|
export type CredentialMaxOrderByAggregateInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
|
notes?: Prisma.SortOrder
|
||||||
typeId?: Prisma.SortOrder
|
typeId?: Prisma.SortOrder
|
||||||
companyId?: Prisma.SortOrder
|
companyId?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
@@ -363,6 +384,7 @@ export type CredentialMaxOrderByAggregateInput = {
|
|||||||
export type CredentialMinOrderByAggregateInput = {
|
export type CredentialMinOrderByAggregateInput = {
|
||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
name?: Prisma.SortOrder
|
name?: Prisma.SortOrder
|
||||||
|
notes?: Prisma.SortOrder
|
||||||
typeId?: Prisma.SortOrder
|
typeId?: Prisma.SortOrder
|
||||||
companyId?: Prisma.SortOrder
|
companyId?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
@@ -470,6 +492,7 @@ export type CredentialUpdateOneRequiredWithoutSecurevaluesNestedInput = {
|
|||||||
export type CredentialCreateWithoutCompanyInput = {
|
export type CredentialCreateWithoutCompanyInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
@@ -480,6 +503,7 @@ export type CredentialCreateWithoutCompanyInput = {
|
|||||||
export type CredentialUncheckedCreateWithoutCompanyInput = {
|
export type CredentialUncheckedCreateWithoutCompanyInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
@@ -519,6 +543,7 @@ export type CredentialScalarWhereInput = {
|
|||||||
NOT?: Prisma.CredentialScalarWhereInput | Prisma.CredentialScalarWhereInput[]
|
NOT?: Prisma.CredentialScalarWhereInput | Prisma.CredentialScalarWhereInput[]
|
||||||
id?: Prisma.StringFilter<"Credential"> | string
|
id?: Prisma.StringFilter<"Credential"> | string
|
||||||
name?: Prisma.StringFilter<"Credential"> | string
|
name?: Prisma.StringFilter<"Credential"> | string
|
||||||
|
notes?: Prisma.StringNullableFilter<"Credential"> | string | null
|
||||||
typeId?: Prisma.StringFilter<"Credential"> | string
|
typeId?: Prisma.StringFilter<"Credential"> | string
|
||||||
fields?: Prisma.JsonFilter<"Credential">
|
fields?: Prisma.JsonFilter<"Credential">
|
||||||
companyId?: Prisma.StringFilter<"Credential"> | string
|
companyId?: Prisma.StringFilter<"Credential"> | string
|
||||||
@@ -529,6 +554,7 @@ export type CredentialScalarWhereInput = {
|
|||||||
export type CredentialCreateWithoutTypeInput = {
|
export type CredentialCreateWithoutTypeInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
@@ -539,6 +565,7 @@ export type CredentialCreateWithoutTypeInput = {
|
|||||||
export type CredentialUncheckedCreateWithoutTypeInput = {
|
export type CredentialUncheckedCreateWithoutTypeInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
@@ -575,6 +602,7 @@ export type CredentialUpdateManyWithWhereWithoutTypeInput = {
|
|||||||
export type CredentialCreateWithoutSecurevaluesInput = {
|
export type CredentialCreateWithoutSecurevaluesInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
@@ -585,6 +613,7 @@ export type CredentialCreateWithoutSecurevaluesInput = {
|
|||||||
export type CredentialUncheckedCreateWithoutSecurevaluesInput = {
|
export type CredentialUncheckedCreateWithoutSecurevaluesInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
@@ -611,6 +640,7 @@ export type CredentialUpdateToOneWithWhereWithoutSecurevaluesInput = {
|
|||||||
export type CredentialUpdateWithoutSecurevaluesInput = {
|
export type CredentialUpdateWithoutSecurevaluesInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -621,6 +651,7 @@ export type CredentialUpdateWithoutSecurevaluesInput = {
|
|||||||
export type CredentialUncheckedUpdateWithoutSecurevaluesInput = {
|
export type CredentialUncheckedUpdateWithoutSecurevaluesInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -631,6 +662,7 @@ export type CredentialUncheckedUpdateWithoutSecurevaluesInput = {
|
|||||||
export type CredentialCreateManyCompanyInput = {
|
export type CredentialCreateManyCompanyInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
@@ -640,6 +672,7 @@ export type CredentialCreateManyCompanyInput = {
|
|||||||
export type CredentialUpdateWithoutCompanyInput = {
|
export type CredentialUpdateWithoutCompanyInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -650,6 +683,7 @@ export type CredentialUpdateWithoutCompanyInput = {
|
|||||||
export type CredentialUncheckedUpdateWithoutCompanyInput = {
|
export type CredentialUncheckedUpdateWithoutCompanyInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -660,6 +694,7 @@ export type CredentialUncheckedUpdateWithoutCompanyInput = {
|
|||||||
export type CredentialUncheckedUpdateManyWithoutCompanyInput = {
|
export type CredentialUncheckedUpdateManyWithoutCompanyInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
typeId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -669,6 +704,7 @@ export type CredentialUncheckedUpdateManyWithoutCompanyInput = {
|
|||||||
export type CredentialCreateManyTypeInput = {
|
export type CredentialCreateManyTypeInput = {
|
||||||
id?: string
|
id?: string
|
||||||
name: string
|
name: string
|
||||||
|
notes?: string | null
|
||||||
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
@@ -678,6 +714,7 @@ export type CredentialCreateManyTypeInput = {
|
|||||||
export type CredentialUpdateWithoutTypeInput = {
|
export type CredentialUpdateWithoutTypeInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -688,6 +725,7 @@ export type CredentialUpdateWithoutTypeInput = {
|
|||||||
export type CredentialUncheckedUpdateWithoutTypeInput = {
|
export type CredentialUncheckedUpdateWithoutTypeInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -698,6 +736,7 @@ export type CredentialUncheckedUpdateWithoutTypeInput = {
|
|||||||
export type CredentialUncheckedUpdateManyWithoutTypeInput = {
|
export type CredentialUncheckedUpdateManyWithoutTypeInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
name?: Prisma.StringFieldUpdateOperationsInput | string
|
name?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
fields?: Prisma.JsonNullValueInput | runtime.InputJsonValue
|
||||||
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
companyId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
@@ -738,6 +777,7 @@ export type CredentialCountOutputTypeCountSecurevaluesArgs<ExtArgs extends runti
|
|||||||
export type CredentialSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type CredentialSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
|
notes?: boolean
|
||||||
typeId?: boolean
|
typeId?: boolean
|
||||||
fields?: boolean
|
fields?: boolean
|
||||||
companyId?: boolean
|
companyId?: boolean
|
||||||
@@ -752,6 +792,7 @@ export type CredentialSelect<ExtArgs extends runtime.Types.Extensions.InternalAr
|
|||||||
export type CredentialSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type CredentialSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
|
notes?: boolean
|
||||||
typeId?: boolean
|
typeId?: boolean
|
||||||
fields?: boolean
|
fields?: boolean
|
||||||
companyId?: boolean
|
companyId?: boolean
|
||||||
@@ -764,6 +805,7 @@ export type CredentialSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Ex
|
|||||||
export type CredentialSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
export type CredentialSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
|
notes?: boolean
|
||||||
typeId?: boolean
|
typeId?: boolean
|
||||||
fields?: boolean
|
fields?: boolean
|
||||||
companyId?: boolean
|
companyId?: boolean
|
||||||
@@ -776,6 +818,7 @@ export type CredentialSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Ex
|
|||||||
export type CredentialSelectScalar = {
|
export type CredentialSelectScalar = {
|
||||||
id?: boolean
|
id?: boolean
|
||||||
name?: boolean
|
name?: boolean
|
||||||
|
notes?: boolean
|
||||||
typeId?: boolean
|
typeId?: boolean
|
||||||
fields?: boolean
|
fields?: boolean
|
||||||
companyId?: boolean
|
companyId?: boolean
|
||||||
@@ -783,7 +826,7 @@ export type CredentialSelectScalar = {
|
|||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CredentialOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "typeId" | "fields" | "companyId" | "createdAt" | "updatedAt", ExtArgs["result"]["credential"]>
|
export type CredentialOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "notes" | "typeId" | "fields" | "companyId" | "createdAt" | "updatedAt", ExtArgs["result"]["credential"]>
|
||||||
export type CredentialInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type CredentialInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
type?: boolean | Prisma.CredentialTypeDefaultArgs<ExtArgs>
|
type?: boolean | Prisma.CredentialTypeDefaultArgs<ExtArgs>
|
||||||
company?: boolean | Prisma.CompanyDefaultArgs<ExtArgs>
|
company?: boolean | Prisma.CompanyDefaultArgs<ExtArgs>
|
||||||
@@ -809,6 +852,7 @@ export type $CredentialPayload<ExtArgs extends runtime.Types.Extensions.Internal
|
|||||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
|
notes: string | null
|
||||||
typeId: string
|
typeId: string
|
||||||
fields: runtime.JsonValue
|
fields: runtime.JsonValue
|
||||||
companyId: string
|
companyId: string
|
||||||
@@ -1242,6 +1286,7 @@ export interface Prisma__CredentialClient<T, Null = never, ExtArgs extends runti
|
|||||||
export interface CredentialFieldRefs {
|
export interface CredentialFieldRefs {
|
||||||
readonly id: Prisma.FieldRef<"Credential", 'String'>
|
readonly id: Prisma.FieldRef<"Credential", 'String'>
|
||||||
readonly name: Prisma.FieldRef<"Credential", 'String'>
|
readonly name: Prisma.FieldRef<"Credential", 'String'>
|
||||||
|
readonly notes: Prisma.FieldRef<"Credential", 'String'>
|
||||||
readonly typeId: Prisma.FieldRef<"Credential", 'String'>
|
readonly typeId: Prisma.FieldRef<"Credential", 'String'>
|
||||||
readonly fields: Prisma.FieldRef<"Credential", 'Json'>
|
readonly fields: Prisma.FieldRef<"Credential", 'Json'>
|
||||||
readonly companyId: Prisma.FieldRef<"Credential", 'String'>
|
readonly companyId: Prisma.FieldRef<"Credential", 'String'>
|
||||||
|
|||||||
@@ -97,8 +97,9 @@ model SecureValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Credential {
|
model Credential {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
|
notes String?
|
||||||
|
|
||||||
typeId String
|
typeId String
|
||||||
type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)
|
type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { apiResponse } from "../../modules/api-utils/apiResponse";
|
|||||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
import { authMiddleware } from "../middleware/authorization";
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||||
|
|
||||||
/* /v1/credential-type */
|
/* /v1/credential-type */
|
||||||
export default createRoute(
|
export default createRoute(
|
||||||
@@ -24,13 +25,15 @@ export default createRoute(
|
|||||||
name: z.string(),
|
name: z.string(),
|
||||||
required: z.boolean(),
|
required: z.boolean(),
|
||||||
secure: z.boolean(),
|
secure: z.boolean(),
|
||||||
valueType: z.enum(["plain_text", "password"]),
|
valueType: z.enum(Object.values(ValueType)),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = schema.parse(body);
|
const data = schema.parse(body);
|
||||||
|
|
||||||
|
console.log("Creating Credential Type with data:", data);
|
||||||
|
|
||||||
const credentialType = await credentialTypes.create(data as any);
|
const credentialType = await credentialTypes.create(data as any);
|
||||||
|
|
||||||
const response = apiResponse.created(
|
const response = apiResponse.created(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { apiResponse } from "../../modules/api-utils/apiResponse";
|
|||||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
import { authMiddleware } from "../middleware/authorization";
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||||
|
|
||||||
/* /v1/credential-type/:id */
|
/* /v1/credential-type/:id */
|
||||||
export default createRoute(
|
export default createRoute(
|
||||||
@@ -26,7 +27,7 @@ export default createRoute(
|
|||||||
name: z.string(),
|
name: z.string(),
|
||||||
required: z.boolean(),
|
required: z.boolean(),
|
||||||
secure: z.boolean(),
|
secure: z.boolean(),
|
||||||
valueType: z.enum(["plain_text", "password"]),
|
valueType: z.enum(Object.values(ValueType)),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export default createRoute(
|
|||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
name: z.string().min(1, "Name is required"),
|
name: z.string().min(1, "Name is required"),
|
||||||
|
notes: z.string().optional(),
|
||||||
typeId: z.string().min(1, "Type ID is required"),
|
typeId: z.string().min(1, "Type ID is required"),
|
||||||
companyId: z.string().min(1, "Company ID is required"),
|
companyId: z.string().min(1, "Company ID is required"),
|
||||||
fields: z.array(
|
fields: z.array(
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ import { default as update } from "./update";
|
|||||||
import { default as updateFields } from "./updateFields";
|
import { default as updateFields } from "./updateFields";
|
||||||
import { default as fetchFields } from "./fetchFields";
|
import { default as fetchFields } from "./fetchFields";
|
||||||
import { default as readSecureValues } from "./readSecureValues";
|
import { default as readSecureValues } from "./readSecureValues";
|
||||||
|
import { default as readSecureValue } from "./readSecureValue";
|
||||||
import { default as deleteCredential } from "./delete";
|
import { default as deleteCredential } from "./delete";
|
||||||
|
import { default as valueTypes } from "./valueTypes";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
valueTypes,
|
||||||
fetch,
|
fetch,
|
||||||
fetchByCompany,
|
fetchByCompany,
|
||||||
create,
|
create,
|
||||||
@@ -15,5 +18,6 @@ export {
|
|||||||
updateFields,
|
updateFields,
|
||||||
fetchFields,
|
fetchFields,
|
||||||
readSecureValues,
|
readSecureValues,
|
||||||
|
readSecureValue,
|
||||||
deleteCredential as delete,
|
deleteCredential as delete,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
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";
|
||||||
|
|
||||||
|
/* GET /v1/credential/credentials/:id/secure-values/:fieldId */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/credentials/:id/secure-values/:fieldId"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const credential = await credentials.fetch(c.req.param("id"));
|
||||||
|
const fieldId = c.req.param("fieldId");
|
||||||
|
const value = await credential.readSecureFieldValue(fieldId);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Secure Value Fetched Successfully!",
|
||||||
|
{ fieldId, value },
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({
|
||||||
|
permissions: ["credential.fetch", "credential.secure_values.read"],
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -17,11 +17,29 @@ export default createRoute(
|
|||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
|
notes: z.string().nullable().optional(),
|
||||||
|
fields: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
fieldId: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = schema.parse(body);
|
const data = schema.parse(body);
|
||||||
|
|
||||||
await credential.update(data);
|
if (data.fields) {
|
||||||
|
await credential.validateAndUpdateFields(data.fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.name !== undefined || data.notes !== undefined) {
|
||||||
|
await credential.update({
|
||||||
|
...(data.name !== undefined && { name: data.name }),
|
||||||
|
...(data.notes !== undefined && { notes: data.notes }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const response = apiResponse.successful(
|
const response = apiResponse.successful(
|
||||||
"Credential Updated Successfully!",
|
"Credential Updated Successfully!",
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ export default createRoute(
|
|||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
fields: z.array(
|
fields: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
|
||||||
fieldId: z.string(),
|
fieldId: z.string(),
|
||||||
value: z.string(),
|
value: z.string(),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
|
||||||
|
/* GET /v1/credential/valuetypes */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/valuetypes"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const valueTypes = Object.values(ValueType);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Value Types Fetched Successfully!",
|
||||||
|
valueTypes,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware(),
|
||||||
|
);
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import * as userRoutes from "../user/@me";
|
import * as meRoutes from "../user/@me";
|
||||||
|
import * as userRoutes from "../user";
|
||||||
|
|
||||||
const authRouter = new Hono();
|
const authRouter = new Hono();
|
||||||
|
Object.values(meRoutes).map((r) => authRouter.route("/", r));
|
||||||
Object.values(userRoutes).map((r) => authRouter.route("/", r));
|
Object.values(userRoutes).map((r) => authRouter.route("/", r));
|
||||||
|
|
||||||
export default authRouter;
|
export default authRouter;
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { z } from "zod";
|
||||||
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||||
import { createRoute } from "../../../modules/api-utils/createRoute";
|
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||||
import { authMiddleware } from "../../middleware/authorization";
|
import { authMiddleware } from "../../middleware/authorization";
|
||||||
|
|
||||||
|
const updateSchema = z
|
||||||
|
.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
image: z.string().optional(),
|
||||||
|
})
|
||||||
|
.strict();
|
||||||
|
|
||||||
export default createRoute(
|
export default createRoute(
|
||||||
"patch",
|
"patch",
|
||||||
["/@me"],
|
["/@me"],
|
||||||
async (c) => {
|
async (c) => {
|
||||||
const updatedUser = await c.get("user")?.update(await c.req.json());
|
const body = updateSchema.parse(await c.req.json());
|
||||||
|
const updatedUser = await c.get("user")?.update(body);
|
||||||
const response = apiResponse.successful(
|
const response = apiResponse.successful(
|
||||||
"Successfully updated user.",
|
"Successfully updated user.",
|
||||||
updatedUser?.toJson(),
|
updatedUser?.toJson(),
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
const checkPermissionSchema = z.object({
|
||||||
|
permissions: z
|
||||||
|
.array(z.string().min(1, "Permission node cannot be empty"))
|
||||||
|
.min(1, "At least one permission is required"),
|
||||||
|
});
|
||||||
|
|
||||||
|
/* POST /v1/user/users/:identifier/check-permission */
|
||||||
|
export default createRoute(
|
||||||
|
"post",
|
||||||
|
["/users/:identifier/check-permission"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const identifier = c.req.param("identifier");
|
||||||
|
|
||||||
|
const user = await users.fetchUser({ id: identifier });
|
||||||
|
if (!user)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "UserNotFound",
|
||||||
|
message: `User with identifier '${identifier}' was not found.`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = await c.req.json();
|
||||||
|
const { permissions } = checkPermissionSchema.parse(body);
|
||||||
|
|
||||||
|
const results = await Promise.all(
|
||||||
|
permissions.map(async (permission) => ({
|
||||||
|
permission,
|
||||||
|
hasPermission: await user.hasPermission(permission),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = apiResponse.successful("Permission check completed.", {
|
||||||
|
results,
|
||||||
|
});
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.read.other"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
/* DELETE /v1/user/users/:identifier */
|
||||||
|
export default createRoute(
|
||||||
|
"delete",
|
||||||
|
["/users/:identifier"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const identifier = c.req.param("identifier");
|
||||||
|
|
||||||
|
const user = await users.fetchUser({ id: identifier });
|
||||||
|
if (!user)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "UserNotFound",
|
||||||
|
message: `User with identifier '${identifier}' was not found.`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const userData = user.toJson();
|
||||||
|
await users.deleteUser(user.id);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"User Deleted Successfully!",
|
||||||
|
userData,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.delete.other"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
/* GET /v1/user/users/:identifier */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/users/:identifier"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const identifier = c.req.param("identifier");
|
||||||
|
|
||||||
|
const user = await users.fetchUser({ id: identifier });
|
||||||
|
if (!user)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "UserNotFound",
|
||||||
|
message: `User with identifier '${identifier}' was not found.`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"User Fetched Successfully!",
|
||||||
|
user.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.read.other"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
|
||||||
|
/* GET /v1/user/users */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/users"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const allUsers = await users.fetchAllUsers();
|
||||||
|
const usersArray = allUsers.map((u) => u.toJson());
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"Users Fetched Successfully!",
|
||||||
|
usersArray,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.read.other", "user.list.other"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
/* GET /v1/user/users/:identifier/roles */
|
||||||
|
export default createRoute(
|
||||||
|
"get",
|
||||||
|
["/users/:identifier/roles"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const identifier = c.req.param("identifier");
|
||||||
|
|
||||||
|
const user = await users.fetchUser({ id: identifier });
|
||||||
|
if (!user)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "UserNotFound",
|
||||||
|
message: `User with identifier '${identifier}' was not found.`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const roles = await user.fetchRoles();
|
||||||
|
const rolesArray = roles.map((r) => r.toJson({ viewPermissions: true }));
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"User Roles Fetched Successfully!",
|
||||||
|
rolesArray,
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.read.other", "role.read"] }),
|
||||||
|
);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export { default as fetch } from "./fetch";
|
||||||
|
export { default as fetchAll } from "./fetchAll";
|
||||||
|
export { default as update } from "./update";
|
||||||
|
export { default as deleteUser } from "./delete";
|
||||||
|
export { default as fetchRoles } from "./fetchRoles";
|
||||||
|
export { default as checkPermission } from "./checkPermission";
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||||
|
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||||
|
import { authMiddleware } from "../middleware/authorization";
|
||||||
|
import { users } from "../../managers/users";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
const updateSchema = z
|
||||||
|
.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
image: z.string().optional(),
|
||||||
|
roles: z.array(z.string()).optional(),
|
||||||
|
permissions: z.array(z.string()).optional(),
|
||||||
|
})
|
||||||
|
.strict();
|
||||||
|
|
||||||
|
/* PATCH /v1/user/users/:identifier */
|
||||||
|
export default createRoute(
|
||||||
|
"patch",
|
||||||
|
["/users/:identifier"],
|
||||||
|
|
||||||
|
async (c) => {
|
||||||
|
const identifier = c.req.param("identifier");
|
||||||
|
const requestingUser = c.get("user");
|
||||||
|
|
||||||
|
const user = await users.fetchUser({ id: identifier });
|
||||||
|
if (!user)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "UserNotFound",
|
||||||
|
message: `User with identifier '${identifier}' was not found.`,
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = updateSchema.parse(await c.req.json());
|
||||||
|
|
||||||
|
if (body.roles && !(await requestingUser.hasPermission("user.roles.other")))
|
||||||
|
throw new GenericError({
|
||||||
|
name: "InsufficientPermission",
|
||||||
|
message: "You do not have permission to modify roles on another user.",
|
||||||
|
status: 403,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
body.permissions &&
|
||||||
|
!(await requestingUser.hasPermission("user.permissions.other"))
|
||||||
|
)
|
||||||
|
throw new GenericError({
|
||||||
|
name: "InsufficientPermission",
|
||||||
|
message:
|
||||||
|
"You do not have permission to modify permissions on another user.",
|
||||||
|
status: 403,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { roles: roleIds, permissions, ...profileData } = body;
|
||||||
|
|
||||||
|
if (Object.keys(profileData).length > 0) await user.update(profileData);
|
||||||
|
if (roleIds) await user.setRoles(roleIds);
|
||||||
|
if (permissions) await user.setPermissions(permissions);
|
||||||
|
|
||||||
|
const response = apiResponse.successful(
|
||||||
|
"User Updated Successfully!",
|
||||||
|
user.toJson(),
|
||||||
|
);
|
||||||
|
return c.json(response, response.status as ContentfulStatusCode);
|
||||||
|
},
|
||||||
|
authMiddleware({ permissions: ["user.write.other"] }),
|
||||||
|
);
|
||||||
@@ -80,7 +80,9 @@ export class CompanyController {
|
|||||||
city: this.cw_Data?.city,
|
city: this.cw_Data?.city,
|
||||||
state: this.cw_Data?.state,
|
state: this.cw_Data?.state,
|
||||||
zip: this.cw_Data?.zip,
|
zip: this.cw_Data?.zip,
|
||||||
country: this.cw_Data?.country.name,
|
country: this.cw_Data?.country
|
||||||
|
? this.cw_Data.country.name
|
||||||
|
: "United States",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { fieldValidator } from "../modules/credentials/fieldValidator";
|
|||||||
import {
|
import {
|
||||||
CredentialField,
|
CredentialField,
|
||||||
CredentialTypeField,
|
CredentialTypeField,
|
||||||
|
ValueType,
|
||||||
} from "../modules/credentials/credentialTypeDefs";
|
} from "../modules/credentials/credentialTypeDefs";
|
||||||
import { generateSecureValue } from "../modules/credentials/generateSecureValue";
|
import { generateSecureValue } from "../modules/credentials/generateSecureValue";
|
||||||
import { readSecureValue } from "../modules/credentials/readSecureValue";
|
import { readSecureValue } from "../modules/credentials/readSecureValue";
|
||||||
@@ -24,6 +25,7 @@ import GenericError from "../Errors/GenericError";
|
|||||||
export class CredentialController {
|
export class CredentialController {
|
||||||
public readonly id: string;
|
public readonly id: string;
|
||||||
public name: string;
|
public name: string;
|
||||||
|
public notes: string | null;
|
||||||
public readonly typeId: string;
|
public readonly typeId: string;
|
||||||
public readonly companyId: string;
|
public readonly companyId: string;
|
||||||
public fields: any;
|
public fields: any;
|
||||||
@@ -44,6 +46,7 @@ export class CredentialController {
|
|||||||
) {
|
) {
|
||||||
this.id = credentialData.id;
|
this.id = credentialData.id;
|
||||||
this.name = credentialData.name;
|
this.name = credentialData.name;
|
||||||
|
this.notes = credentialData.notes;
|
||||||
this.typeId = credentialData.typeId;
|
this.typeId = credentialData.typeId;
|
||||||
this.companyId = credentialData.companyId;
|
this.companyId = credentialData.companyId;
|
||||||
this._type = credentialData.type;
|
this._type = credentialData.type;
|
||||||
@@ -52,14 +55,21 @@ export class CredentialController {
|
|||||||
this.fields = (() => {
|
this.fields = (() => {
|
||||||
let fields = credentialData.fields as Record<string, any>;
|
let fields = credentialData.fields as Record<string, any>;
|
||||||
|
|
||||||
this._secureValues.forEach((sv) => (fields[sv.name] = `secure-${sv.id}`));
|
return (this._type.fields! as any).map((f: any) => ({
|
||||||
|
id: f.id,
|
||||||
|
name: f.name,
|
||||||
|
secure: f.secure,
|
||||||
|
required: f.required,
|
||||||
|
valueType: f.valueType as ValueType,
|
||||||
|
value: f.secure
|
||||||
|
? `secure-${this._secureValues.find((sv) => sv.name === f.id)?.id}`
|
||||||
|
: fields[f.id],
|
||||||
|
}));
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
})();
|
})();
|
||||||
this.createdAt = credentialData.createdAt;
|
this.createdAt = credentialData.createdAt;
|
||||||
this.updatedAt = credentialData.updatedAt;
|
this.updatedAt = credentialData.updatedAt;
|
||||||
|
|
||||||
console.log(credentialData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +82,7 @@ export class CredentialController {
|
|||||||
*/
|
*/
|
||||||
private _updateInternalValues(credentialData: Credential) {
|
private _updateInternalValues(credentialData: Credential) {
|
||||||
this.name = credentialData.name;
|
this.name = credentialData.name;
|
||||||
|
this.notes = credentialData.notes;
|
||||||
this.fields = credentialData.fields;
|
this.fields = credentialData.fields;
|
||||||
this.updatedAt = credentialData.updatedAt;
|
this.updatedAt = credentialData.updatedAt;
|
||||||
}
|
}
|
||||||
@@ -174,7 +185,6 @@ export class CredentialController {
|
|||||||
const nonSecureFields = this.fields as Record<string, any>;
|
const nonSecureFields = this.fields as Record<string, any>;
|
||||||
Object.entries(nonSecureFields || {}).forEach(([fieldId, value]) => {
|
Object.entries(nonSecureFields || {}).forEach(([fieldId, value]) => {
|
||||||
fields.push({
|
fields.push({
|
||||||
id: `${this.id}-${fieldId}`, // Generate a consistent ID
|
|
||||||
fieldId,
|
fieldId,
|
||||||
value: value as string,
|
value: value as string,
|
||||||
});
|
});
|
||||||
@@ -183,7 +193,6 @@ export class CredentialController {
|
|||||||
// Add secure fields from SecureValue table (encrypted)
|
// Add secure fields from SecureValue table (encrypted)
|
||||||
this._secureValues.forEach((secureValue) => {
|
this._secureValues.forEach((secureValue) => {
|
||||||
fields.push({
|
fields.push({
|
||||||
id: secureValue.id,
|
|
||||||
fieldId: secureValue.name,
|
fieldId: secureValue.name,
|
||||||
value: secureValue.content, // Encrypted value
|
value: secureValue.content, // Encrypted value
|
||||||
});
|
});
|
||||||
@@ -253,11 +262,12 @@ export class CredentialController {
|
|||||||
* @returns {Promise<CredentialController>} - The updated credential controller
|
* @returns {Promise<CredentialController>} - The updated credential controller
|
||||||
*/
|
*/
|
||||||
async update(
|
async update(
|
||||||
data: Partial<Pick<Credential, "name">>,
|
data: Partial<Pick<Credential, "name" | "notes">>,
|
||||||
): Promise<CredentialController> {
|
): Promise<CredentialController> {
|
||||||
const pData = z
|
const pData = z
|
||||||
.object({
|
.object({
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
|
notes: z.string().nullable().optional(),
|
||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
.parse(data);
|
.parse(data);
|
||||||
@@ -307,6 +317,7 @@ export class CredentialController {
|
|||||||
return {
|
return {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
notes: this.notes,
|
||||||
typeId: this.typeId,
|
typeId: this.typeId,
|
||||||
companyId: this.companyId,
|
companyId: this.companyId,
|
||||||
fields: this.fields,
|
fields: this.fields,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Collection } from "@discordjs/collection";
|
import { Collection } from "@discordjs/collection";
|
||||||
import { z } from "zod";
|
|
||||||
import { Role } from "../../generated/prisma/client";
|
import { Role } from "../../generated/prisma/client";
|
||||||
import { User } from "../../generated/prisma/browser";
|
import { User } from "../../generated/prisma/browser";
|
||||||
import { SessionTokensObject } from "./SessionController";
|
import { SessionTokensObject } from "./SessionController";
|
||||||
@@ -9,6 +8,10 @@ import { prisma } from "../constants";
|
|||||||
import { events } from "../modules/globalEvents";
|
import { events } from "../modules/globalEvents";
|
||||||
import { RoleController } from "./RoleController";
|
import { RoleController } from "./RoleController";
|
||||||
import { roles } from "../managers/roles";
|
import { roles } from "../managers/roles";
|
||||||
|
import { signPermissions } from "../modules/permission-utils/signPermissions";
|
||||||
|
import { DecodedPermissionsBlock } from "../types/PermissionTypes";
|
||||||
|
import jwt from "jsonwebtoken";
|
||||||
|
import { permissionsPrivateKey } from "../constants";
|
||||||
|
|
||||||
export default class UserController {
|
export default class UserController {
|
||||||
public id: string;
|
public id: string;
|
||||||
@@ -18,6 +21,7 @@ export default class UserController {
|
|||||||
public image: string | null;
|
public image: string | null;
|
||||||
|
|
||||||
private _roles: Collection<string, Role>;
|
private _roles: Collection<string, Role>;
|
||||||
|
private _permissions: string | null;
|
||||||
|
|
||||||
public createdAt: Date;
|
public createdAt: Date;
|
||||||
public updatedAt: Date;
|
public updatedAt: Date;
|
||||||
@@ -29,6 +33,7 @@ export default class UserController {
|
|||||||
this.image = userdata.image;
|
this.image = userdata.image;
|
||||||
this.updatedAt = userdata.updatedAt;
|
this.updatedAt = userdata.updatedAt;
|
||||||
this.createdAt = userdata.createdAt;
|
this.createdAt = userdata.createdAt;
|
||||||
|
this._permissions = userdata.permissions ?? null;
|
||||||
|
|
||||||
this._roles = (() => {
|
this._roles = (() => {
|
||||||
let collection = new Collection<string, Role>();
|
let collection = new Collection<string, Role>();
|
||||||
@@ -77,22 +82,13 @@ export default class UserController {
|
|||||||
* @param data - A partial of the user data
|
* @param data - A partial of the user data
|
||||||
* @returns {Promise<UserController>} - The updated user controller
|
* @returns {Promise<UserController>} - The updated user controller
|
||||||
*/
|
*/
|
||||||
public async update(data: Partial<User>) {
|
public async update(data: Partial<Pick<User, "name" | "image">>) {
|
||||||
// Parsed Data With Schema
|
|
||||||
const pData = z
|
|
||||||
.object({
|
|
||||||
name: z.string().optional(),
|
|
||||||
image: z.string().optional(),
|
|
||||||
})
|
|
||||||
.strict()
|
|
||||||
.parse(data);
|
|
||||||
|
|
||||||
if (Object.keys(data).length == 0)
|
if (Object.keys(data).length == 0)
|
||||||
throw new BodyError("Body cannot be empty.");
|
throw new BodyError("Body cannot be empty.");
|
||||||
|
|
||||||
const updatedUser = await prisma.user.update({
|
const updatedUser = await prisma.user.update({
|
||||||
where: { id: this.id },
|
where: { id: this.id },
|
||||||
data: pData,
|
data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._updateInternalValues(updatedUser);
|
this._updateInternalValues(updatedUser);
|
||||||
@@ -101,6 +97,87 @@ export default class UserController {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Roles
|
||||||
|
*
|
||||||
|
* Replace the user's roles with the provided array of role identifiers (id or moniker).
|
||||||
|
* Validates that each role exists before assigning.
|
||||||
|
*
|
||||||
|
* @param roleIdentifiers - Array of role ids or monikers to assign
|
||||||
|
* @returns {Promise<UserController>} - The updated user controller
|
||||||
|
*/
|
||||||
|
public async setRoles(roleIdentifiers: string[]): Promise<UserController> {
|
||||||
|
const resolvedRoles = await Promise.all(
|
||||||
|
roleIdentifiers.map((identifier) => roles.fetch(identifier)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedUser = await prisma.user.update({
|
||||||
|
where: { id: this.id },
|
||||||
|
data: {
|
||||||
|
roles: {
|
||||||
|
set: resolvedRoles.map((r) => ({ id: r.id })),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
include: { roles: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateInternalValues(updatedUser);
|
||||||
|
this._roles = new Collection<string, Role>();
|
||||||
|
updatedUser.roles.map((v: any) => this._roles.set(v.id, v));
|
||||||
|
|
||||||
|
for (const role of resolvedRoles) {
|
||||||
|
events.emit("user:role:assigned", { user: this, role });
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Permissions
|
||||||
|
*
|
||||||
|
* Replace the user's direct permissions with the provided array of permission strings.
|
||||||
|
* Signs the permissions with the user issuer before storing.
|
||||||
|
*
|
||||||
|
* @param permissions - Array of permission node strings to assign
|
||||||
|
* @returns {Promise<UserController>} - The updated user controller
|
||||||
|
*/
|
||||||
|
public async setPermissions(permissions: string[]): Promise<UserController> {
|
||||||
|
const signed = signPermissions({
|
||||||
|
issuer: "user",
|
||||||
|
subject: this.id,
|
||||||
|
permissions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedUser = await prisma.user.update({
|
||||||
|
where: { id: this.id },
|
||||||
|
data: { permissions: signed },
|
||||||
|
});
|
||||||
|
|
||||||
|
this._updateInternalValues(updatedUser);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Permissions
|
||||||
|
*
|
||||||
|
* Verifies and decodes the user's direct permissions JWT and returns the array of
|
||||||
|
* permission node strings. Returns an empty array if the user has no direct permissions.
|
||||||
|
*
|
||||||
|
* @returns {string[]} The user's direct permission nodes
|
||||||
|
*/
|
||||||
|
public readPermissions(): string[] {
|
||||||
|
if (!this._permissions) return [];
|
||||||
|
|
||||||
|
const decoded = jwt.verify(this._permissions, permissionsPrivateKey, {
|
||||||
|
algorithms: ["RS256"],
|
||||||
|
issuer: "user",
|
||||||
|
subject: this.id,
|
||||||
|
}) as DecodedPermissionsBlock;
|
||||||
|
|
||||||
|
return decoded.permissions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch Roles
|
* Fetch Roles
|
||||||
*
|
*
|
||||||
@@ -185,9 +262,12 @@ export default class UserController {
|
|||||||
: this._roles.size > 0
|
: this._roles.size > 0
|
||||||
? this._roles.map((v) => v.moniker)
|
? this._roles.map((v) => v.moniker)
|
||||||
: undefined,
|
: undefined,
|
||||||
|
permissions: opts?.safeReturn ? undefined : this.readPermissions(),
|
||||||
login: opts?.safeReturn ? undefined : this.login,
|
login: opts?.safeReturn ? undefined : this.login,
|
||||||
email: opts?.safeReturn ? undefined : this.email,
|
email: opts?.safeReturn ? undefined : this.email,
|
||||||
image: this.image,
|
image: this.image,
|
||||||
|
createdAt: this.createdAt,
|
||||||
|
updatedAt: this.updatedAt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ export const credentialTypes = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(data.fields);
|
||||||
|
|
||||||
const credentialType = await prisma.credentialType.create({
|
const credentialType = await prisma.credentialType.create({
|
||||||
data: {
|
data: {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
@@ -91,6 +93,8 @@ export const credentialTypes = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(credentialType.fields);
|
||||||
|
|
||||||
return new CredentialTypeController(credentialType);
|
return new CredentialTypeController(credentialType);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ export const credentials = {
|
|||||||
*/
|
*/
|
||||||
async create(data: {
|
async create(data: {
|
||||||
name: string;
|
name: string;
|
||||||
|
notes?: string;
|
||||||
typeId: string;
|
typeId: string;
|
||||||
companyId: string;
|
companyId: string;
|
||||||
fields: {
|
fields: {
|
||||||
@@ -131,6 +132,7 @@ export const credentials = {
|
|||||||
const credential = await prisma.credential.create({
|
const credential = await prisma.credential.create({
|
||||||
data: {
|
data: {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
|
notes: data.notes,
|
||||||
typeId: data.typeId,
|
typeId: data.typeId,
|
||||||
companyId: data.companyId,
|
companyId: data.companyId,
|
||||||
fields: fieldsObject,
|
fields: fieldsObject,
|
||||||
|
|||||||
+27
-4
@@ -106,8 +106,31 @@ export const users = {
|
|||||||
|
|
||||||
return controller;
|
return controller;
|
||||||
},
|
},
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @TODO Figure out default permissions
|
* Fetch all users
|
||||||
*/
|
*
|
||||||
|
* Returns an array of UserController instances for every user in the database.
|
||||||
|
*
|
||||||
|
* @returns {Promise<UserController[]>} Array of user controllers
|
||||||
|
*/
|
||||||
|
async fetchAllUsers(): Promise<UserController[]> {
|
||||||
|
const allUsers = await prisma.user.findMany({
|
||||||
|
include: { roles: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
return allUsers.map((u) => new UserController(u));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a user
|
||||||
|
*
|
||||||
|
* Removes a user record from the database by their id.
|
||||||
|
*
|
||||||
|
* @param userId - The id of the user to delete
|
||||||
|
*/
|
||||||
|
async deleteUser(userId: string): Promise<void> {
|
||||||
|
await prisma.user.delete({ where: { id: userId } });
|
||||||
|
events.emit("user:deleted", { id: userId });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
export enum ValueType {
|
export enum ValueType {
|
||||||
PLAIN_TEXT = "plain_text",
|
PLAIN_TEXT = "plain_text",
|
||||||
|
LICENSE_KEY = "license_key",
|
||||||
|
IP_ADDRESS = "ip_address",
|
||||||
|
GENERIC_SECRET = "generic_secret",
|
||||||
|
BITLOCKER_KEY = "bitlocker_key",
|
||||||
PASSWORD = "password",
|
PASSWORD = "password",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +16,6 @@ export interface CredentialTypeField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CredentialField {
|
export interface CredentialField {
|
||||||
id: string; // CUID
|
|
||||||
fieldId: string; // I.e. "clientId", "clientSecret", etc.
|
fieldId: string; // I.e. "clientId", "clientSecret", etc.
|
||||||
value: string; // Encrypted value stored in the database
|
value: string; // Encrypted value stored in the database
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export const fieldValidator = async (
|
|||||||
acceptableFields: CredentialTypeField[],
|
acceptableFields: CredentialTypeField[],
|
||||||
): Promise<
|
): Promise<
|
||||||
{
|
{
|
||||||
id: string;
|
|
||||||
fieldId: string;
|
fieldId: string;
|
||||||
value: string;
|
value: string;
|
||||||
secure: boolean;
|
secure: boolean;
|
||||||
@@ -47,7 +46,6 @@ export const fieldValidator = async (
|
|||||||
const matchingField = afCollection.get(field.fieldId)!;
|
const matchingField = afCollection.get(field.fieldId)!;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: field.id,
|
|
||||||
fieldId: field.fieldId,
|
fieldId: field.fieldId,
|
||||||
value: field.value,
|
value: field.value,
|
||||||
secure: matchingField.secure,
|
secure: matchingField.secure,
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ export const generateSecureValue = (content: string) => {
|
|||||||
// Generate a hash of the content
|
// Generate a hash of the content
|
||||||
const hash = Password.hash(content);
|
const hash = Password.hash(content);
|
||||||
|
|
||||||
|
// Parse the PKCS#1 PEM key into a proper KeyObject
|
||||||
|
const publicKey = crypto.createPublicKey(secureValuesPublicKey);
|
||||||
|
|
||||||
// Encrypt the content using the .secureValues.pub public key
|
// Encrypt the content using the .secureValues.pub public key
|
||||||
const encrypted = crypto.publicEncrypt(
|
const encrypted = crypto.publicEncrypt(
|
||||||
{
|
{
|
||||||
key: secureValuesPublicKey,
|
key: publicKey,
|
||||||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
oaepHash: "sha256",
|
oaepHash: "sha256",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,20 +1,36 @@
|
|||||||
import Password from "../tools/Password";
|
import Password from "../tools/Password";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { secureValuesPrivateKey } from "../../constants";
|
import { secureValuesPrivateKey } from "../../constants";
|
||||||
|
import GenericError from "../../Errors/GenericError";
|
||||||
|
|
||||||
|
const privateKey = crypto.createPrivateKey(secureValuesPrivateKey);
|
||||||
|
|
||||||
export const readSecureValue = (
|
export const readSecureValue = (
|
||||||
encryptedContent: string,
|
encryptedContent: string,
|
||||||
hash?: string,
|
hash?: string,
|
||||||
): string => {
|
): string => {
|
||||||
// Decrypt the content using the .secureValues.key private key
|
let decrypted: Buffer;
|
||||||
const decrypted = crypto.privateDecrypt(
|
|
||||||
{
|
try {
|
||||||
key: secureValuesPrivateKey,
|
// Decrypt the content using the .secureValues.key private key
|
||||||
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
decrypted = crypto.privateDecrypt(
|
||||||
oaepHash: "sha256",
|
{
|
||||||
},
|
key: privateKey,
|
||||||
Buffer.from(encryptedContent, "base64"),
|
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
||||||
);
|
oaepHash: "sha256",
|
||||||
|
},
|
||||||
|
Buffer.from(encryptedContent, "base64"),
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
throw new GenericError({
|
||||||
|
name: "SecureValueDecryptionError",
|
||||||
|
message:
|
||||||
|
"Unable to decrypt secure value. The value was encrypted with a different key and must be re-entered.",
|
||||||
|
cause:
|
||||||
|
"RSA key mismatch — the current private key does not match the public key used to encrypt this value.",
|
||||||
|
status: 422,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const content = decrypted.toString("utf-8");
|
const content = decrypted.toString("utf-8");
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ interface EventTypes {
|
|||||||
user: UserController;
|
user: UserController;
|
||||||
updatedValues: Partial<User>;
|
updatedValues: Partial<User>;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
"user:deleted": (data: { id: string }) => void;
|
||||||
"user:authenticated": (data: {
|
"user:authenticated": (data: {
|
||||||
user: UserController;
|
user: UserController;
|
||||||
tokens: SessionTokensObject;
|
tokens: SessionTokensObject;
|
||||||
|
|||||||
@@ -114,7 +114,10 @@ export const PERMISSION_NODES = {
|
|||||||
{
|
{
|
||||||
node: "credential.secure_values.read",
|
node: "credential.secure_values.read",
|
||||||
description: "Read secure values of a credential",
|
description: "Read secure values of a credential",
|
||||||
usedIn: ["src/api/credentials/readSecureValues.ts"],
|
usedIn: [
|
||||||
|
"src/api/credentials/readSecureValues.ts",
|
||||||
|
"src/api/credentials/readSecureValue.ts",
|
||||||
|
],
|
||||||
dependencies: ["credential.fetch"],
|
dependencies: ["credential.fetch"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -231,6 +234,43 @@ export const PERMISSION_NODES = {
|
|||||||
description: "Update user information",
|
description: "Update user information",
|
||||||
usedIn: ["src/api/user/@me/update.ts"],
|
usedIn: ["src/api/user/@me/update.ts"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
node: "user.read.other",
|
||||||
|
description: "Read other users' information",
|
||||||
|
usedIn: [
|
||||||
|
"src/api/user/fetch.ts",
|
||||||
|
"src/api/user/fetchRoles.ts",
|
||||||
|
"src/api/user/checkPermission.ts",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: "user.list.other",
|
||||||
|
description: "List all users",
|
||||||
|
usedIn: ["src/api/user/fetchAll.ts"],
|
||||||
|
dependencies: ["user.read.other"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: "user.write.other",
|
||||||
|
description: "Update other users' information",
|
||||||
|
usedIn: ["src/api/user/update.ts"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: "user.roles.other",
|
||||||
|
description: "Modify roles assigned to other users",
|
||||||
|
usedIn: ["src/api/user/update.ts"],
|
||||||
|
dependencies: ["user.write.other"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: "user.permissions.other",
|
||||||
|
description: "Modify direct permissions assigned to other users",
|
||||||
|
usedIn: ["src/api/user/update.ts"],
|
||||||
|
dependencies: ["user.write.other"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: "user.delete.other",
|
||||||
|
description: "Delete other users",
|
||||||
|
usedIn: ["src/api/user/delete.ts"],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,11 @@ await Promise.all(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!privExists || !pubExists) {
|
if (!privExists || !pubExists) {
|
||||||
|
// Always regenerate both files together to ensure the key pair matches
|
||||||
console.log(`Generating '${v}' and '${pubPath}'...`);
|
console.log(`Generating '${v}' and '${pubPath}'...`);
|
||||||
const keys = keypair({ bits: 4096 });
|
const keys = keypair({ bits: 4096 });
|
||||||
if (!privExists) {
|
await Bun.write(v, keys.private);
|
||||||
await Bun.write(v, keys.private);
|
await Bun.write(pubPath, keys.public);
|
||||||
}
|
|
||||||
if (!pubExists) {
|
|
||||||
await Bun.write(pubPath, keys.public);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user