diff --git a/backend/schema/common.json b/backend/schema/common.json index 343f125e5..00b06e005 100644 --- a/backend/schema/common.json +++ b/backend/schema/common.json @@ -7,7 +7,8 @@ "description": "Unique identifier", "readOnly": true, "type": "integer", - "minimum": 1 + "minimum": 1, + "example": 11 }, "expand": { "anyOf": [ @@ -38,35 +39,42 @@ "created_on": { "description": "Date and time of creation", "readOnly": true, - "type": "string" + "type": "string", + "example": "2025-10-28T04:17:54.000Z" }, "modified_on": { "description": "Date and time of last update", "readOnly": true, - "type": "string" + "type": "string", + "example": "2025-10-28T04:17:54.000Z" }, "user_id": { "description": "User ID", "type": "integer", - "minimum": 1 + "minimum": 1, + "example": 2 }, "certificate_id": { "description": "Certificate ID", "anyOf": [ { "type": "integer", - "minimum": 0 + "minimum": 0, + "example": 5 }, { "type": "string", - "pattern": "^new$" + "pattern": "^new$", + "example": "new" } - ] + ], + "example": 5 }, "access_list_id": { "description": "Access List ID", "type": "integer", - "minimum": 0 + "minimum": 0, + "example": 3 }, "domain_names": { "description": "Domain Names separated by a comma", @@ -77,44 +85,157 @@ "items": { "type": "string", "pattern": "^[^&| @!#%^();:/\\\\}{=+?<>,~`'\"]+$" - } + }, + "example": ["example.com", "www.example.com"] }, "enabled": { "description": "Is Enabled", - "type": "boolean" + "type": "boolean", + "example": false }, "ssl_forced": { "description": "Is SSL Forced", - "type": "boolean" + "type": "boolean", + "example": true }, "hsts_enabled": { "description": "Is HSTS Enabled", - "type": "boolean" + "type": "boolean", + "example": true }, "hsts_subdomains": { "description": "Is HSTS applicable to all subdomains", - "type": "boolean" + "type": "boolean", + "example": true }, "ssl_provider": { "type": "string", - "pattern": "^(letsencrypt|other)$" + "pattern": "^(letsencrypt|other)$", + "example": "letsencrypt" }, "http2_support": { "description": "HTTP2 Protocol Support", - "type": "boolean" + "type": "boolean", + "example": true }, "block_exploits": { "description": "Should we block common exploits", - "type": "boolean" + "type": "boolean", + "example": false }, "caching_enabled": { "description": "Should we cache assets", - "type": "boolean" + "type": "boolean", + "example": true }, "email": { "description": "Email address", "type": "string", - "pattern": "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" + "pattern": "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$", + "example": "me@example.com" + }, + "directive": { + "type": "string", + "enum": ["allow", "deny"], + "example": "allow" + }, + "address": { + "oneOf": [ + { + "type": "string", + "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$" + }, + { + "type": "string", + "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" + }, + { + "type": "string", + "pattern": "^all$" + } + ], + "example": "192.168.0.11" + }, + "access_items": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "username": { + "type": "string", + "minLength": 1 + }, + "password": { + "type": "string" + } + }, + "example": { + "username": "admin", + "password": "pass" + } + }, + "example": [ + { + "username": "admin", + "password": "pass" + } + ] + }, + "access_clients": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "address": { + "$ref": "#/properties/address" + }, + "directive": { + "$ref": "#/properties/directive" + } + }, + "example": { + "directive": "allow", + "address": "192.168.0.0/24" + } + }, + "example": [ + { + "directive": "allow", + "address": "192.168.0.0/24" + } + ] + }, + "certificate_files": { + "description": "Certificate Files", + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["certificate", "certificate_key"], + "properties": { + "certificate": { + "type": "string", + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" + }, + "certificate_key": { + "type": "string", + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" + }, + "intermediate_certificate": { + "type": "string", + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" + } + } + }, + "example": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----", + "certificate_key": "-----BEGIN PRIVATE\nMIID...-----END CERTIFICATE-----" + } + } + } } } } diff --git a/backend/schema/components/access-list-object.json b/backend/schema/components/access-list-object.json index cd0218d72..d80eb06d8 100644 --- a/backend/schema/components/access-list-object.json +++ b/backend/schema/components/access-list-object.json @@ -1,8 +1,7 @@ { "type": "object", "description": "Access List object", - "required": ["id", "created_on", "modified_on", "owner_user_id", "name", "directive", "address", "satisfy_any", "pass_auth", "meta"], - "additionalProperties": false, + "required": ["id", "created_on", "modified_on", "owner_user_id", "name", "meta", "satisfy_any", "pass_auth", "proxy_host_count"], "properties": { "id": { "$ref": "../common.json#/properties/id" @@ -18,36 +17,25 @@ }, "name": { "type": "string", - "minLength": 1 - }, - "directive": { - "type": "string", - "enum": ["allow", "deny"] - }, - "address": { - "oneOf": [ - { - "type": "string", - "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$" - }, - { - "type": "string", - "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" - }, - { - "type": "string", - "pattern": "^all$" - } - ] - }, - "satisfy_any": { - "type": "boolean" - }, - "pass_auth": { - "type": "boolean" + "minLength": 1, + "example": "My Access List" }, "meta": { - "type": "object" + "type": "object", + "example": {} + }, + "satisfy_any": { + "type": "boolean", + "example": true + }, + "pass_auth": { + "type": "boolean", + "example": false + }, + "proxy_host_count": { + "type": "integer", + "minimum": 0, + "example": 3 } } } diff --git a/backend/schema/components/audit-log-object.json b/backend/schema/components/audit-log-object.json index 4ed25e5cf..307cac822 100644 --- a/backend/schema/components/audit-log-object.json +++ b/backend/schema/components/audit-log-object.json @@ -26,16 +26,19 @@ "$ref": "../common.json#/properties/user_id" }, "object_type": { - "type": "string" + "type": "string", + "example": "certificate" }, "object_id": { "$ref": "../common.json#/properties/id" }, "action": { - "type": "string" + "type": "string", + "example": "created" }, "meta": { - "type": "object" + "type": "object", + "example": {} }, "user": { "$ref": "./user-object.json" diff --git a/backend/schema/components/certificate-object.json b/backend/schema/components/certificate-object.json index ef3553d9b..793483c75 100644 --- a/backend/schema/components/certificate-object.json +++ b/backend/schema/components/certificate-object.json @@ -21,7 +21,8 @@ }, "nice_name": { "type": "string", - "description": "Nice Name for the custom certificate" + "description": "Nice Name for the custom certificate", + "example": "My Custom Cert" }, "domain_names": { "description": "Domain Names separated by a comma", @@ -31,12 +32,14 @@ "items": { "type": "string", "pattern": "^[^&| @!#%^();:/\\\\}{=+?<>,~`'\"]+$" - } + }, + "example": ["example.com", "www.example.com"] }, "expires_on": { "description": "Date and time of expiration", "readOnly": true, - "type": "string" + "type": "string", + "example": "2025-10-28T04:17:54.000Z" }, "owner": { "$ref": "./user-object.json" @@ -59,9 +62,6 @@ "dns_provider": { "type": "string" }, - "dns_provider_credentials": { - "type": "string" - }, "letsencrypt_certificate": { "type": "object" }, @@ -69,6 +69,9 @@ "type": "integer", "minimum": 0 } + }, + "example": { + "dns_challenge": false } } } diff --git a/backend/schema/components/dead-host-object.json b/backend/schema/components/dead-host-object.json index 792c2f81e..b876ebf0a 100644 --- a/backend/schema/components/dead-host-object.json +++ b/backend/schema/components/dead-host-object.json @@ -35,13 +35,30 @@ "$ref": "../common.json#/properties/http2_support" }, "advanced_config": { - "type": "string" + "type": "string", + "example": "" }, "enabled": { "$ref": "../common.json#/properties/enabled" }, "meta": { - "type": "object" + "type": "object", + "example": {} + }, + "certificate": { + "oneOf": [ + { + "type": "null", + "example": null + }, + { + "$ref": "./certificate-object.json" + } + ], + "example": null + }, + "owner": { + "$ref": "./user-object.json" } } } diff --git a/backend/schema/components/error-object.json b/backend/schema/components/error-object.json index c2540cf1f..6f350a088 100644 --- a/backend/schema/components/error-object.json +++ b/backend/schema/components/error-object.json @@ -5,10 +5,12 @@ "required": ["code", "message"], "properties": { "code": { - "type": "integer" + "type": "integer", + "example": 400 }, "message": { - "type": "string" + "type": "string", + "example": "Bad Request" } } } diff --git a/backend/schema/components/health-object.json b/backend/schema/components/health-object.json index f63980946..592ead2ca 100644 --- a/backend/schema/components/health-object.json +++ b/backend/schema/components/health-object.json @@ -27,15 +27,18 @@ "properties": { "major": { "type": "integer", - "minimum": 0 + "minimum": 0, + "example": 2 }, "minor": { "type": "integer", - "minimum": 0 + "minimum": 0, + "example": 10 }, "revision": { "type": "integer", - "minimum": 0 + "minimum": 0, + "example": 1 } } } diff --git a/backend/schema/components/permission-object.json b/backend/schema/components/permission-object.json index b852a014d..cae9d26c0 100644 --- a/backend/schema/components/permission-object.json +++ b/backend/schema/components/permission-object.json @@ -5,37 +5,44 @@ "visibility": { "type": "string", "description": "Visibility Type", - "enum": ["all", "user"] + "enum": ["all", "user"], + "example": "all" }, "access_lists": { "type": "string", "description": "Access Lists Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "view" }, "dead_hosts": { "type": "string", "description": "404 Hosts Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "manage" }, "proxy_hosts": { "type": "string", "description": "Proxy Hosts Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "hidden" }, "redirection_hosts": { "type": "string", "description": "Redirection Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "view" }, "streams": { "type": "string", "description": "Streams Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "manage" }, "certificates": { "type": "string", "description": "Certificates Permissions", - "enum": ["hidden", "view", "manage"] + "enum": ["hidden", "view", "manage"], + "example": "hidden" } } } diff --git a/backend/schema/components/proxy-host-object.json b/backend/schema/components/proxy-host-object.json index e9dcacb5e..464b188e8 100644 --- a/backend/schema/components/proxy-host-object.json +++ b/backend/schema/components/proxy-host-object.json @@ -24,7 +24,6 @@ "hsts_enabled", "hsts_subdomains" ], - "additionalProperties": false, "properties": { "id": { "$ref": "../common.json#/properties/id" @@ -44,12 +43,14 @@ "forward_host": { "type": "string", "minLength": 1, - "maxLength": 255 + "maxLength": 255, + "example": "127.0.0.1" }, "forward_port": { "type": "integer", "minimum": 1, - "maximum": 65535 + "maximum": 65535, + "example": 8080 }, "access_list_id": { "$ref": "../common.json#/properties/access_list_id" @@ -67,22 +68,28 @@ "$ref": "../common.json#/properties/block_exploits" }, "advanced_config": { - "type": "string" + "type": "string", + "example": "" }, "meta": { - "type": "object" + "type": "object", + "example": { + "nginx_online": true, + "nginx_err": null + } }, "allow_websocket_upgrade": { "description": "Allow Websocket Upgrade for all paths", - "example": true, - "type": "boolean" + "type": "boolean", + "example": true }, "http2_support": { "$ref": "../common.json#/properties/http2_support" }, "forward_scheme": { "type": "string", - "enum": ["http", "https"] + "enum": ["http", "https"], + "example": "http" }, "enabled": { "$ref": "../common.json#/properties/enabled" @@ -118,7 +125,15 @@ "type": "string" } } - } + }, + "example": [ + { + "path": "/app", + "forward_scheme": "http", + "forward_host": "example.com", + "forward_port": 80 + } + ] }, "hsts_enabled": { "$ref": "../common.json#/properties/hsts_enabled" @@ -129,12 +144,14 @@ "certificate": { "oneOf": [ { - "type": "null" + "type": "null", + "example": null }, { "$ref": "./certificate-object.json" } - ] + ], + "example": null }, "owner": { "$ref": "./user-object.json" @@ -142,12 +159,14 @@ "access_list": { "oneOf": [ { - "type": "null" + "type": "null", + "example": null }, { "$ref": "./access-list-object.json" } - ] + ], + "example": null } } } diff --git a/backend/schema/components/redirection-host-object.json b/backend/schema/components/redirection-host-object.json index e7a495fd3..58169720b 100644 --- a/backend/schema/components/redirection-host-object.json +++ b/backend/schema/components/redirection-host-object.json @@ -1,7 +1,26 @@ { "type": "object", "description": "Redirection Host object", - "required": ["id", "created_on", "modified_on", "owner_user_id", "domain_names", "forward_http_code", "forward_scheme", "forward_domain_name", "preserve_path", "certificate_id", "ssl_forced", "hsts_enabled", "hsts_subdomains", "http2_support", "block_exploits", "advanced_config", "enabled", "meta"], + "required": [ + "id", + "created_on", + "modified_on", + "owner_user_id", + "domain_names", + "forward_http_code", + "forward_scheme", + "forward_domain_name", + "preserve_path", + "certificate_id", + "ssl_forced", + "hsts_enabled", + "hsts_subdomains", + "http2_support", + "block_exploits", + "advanced_config", + "enabled", + "meta" + ], "additionalProperties": false, "properties": { "id": { @@ -21,25 +40,30 @@ }, "forward_http_code": { "description": "Redirect HTTP Status Code", - "example": 302, "type": "integer", "minimum": 300, - "maximum": 308 + "maximum": 308, + "example": 302 }, "forward_scheme": { "type": "string", - "enum": ["auto", "http", "https"] + "enum": [ + "auto", + "http", + "https" + ], + "example": "http" }, "forward_domain_name": { "description": "Domain Name", - "example": "jc21.com", "type": "string", - "pattern": "^(?:[^.*]+\\.?)+[^.]$" + "pattern": "^(?:[^.*]+\\.?)+[^.]$", + "example": "jc21.com" }, "preserve_path": { "description": "Should the path be preserved", - "example": true, - "type": "boolean" + "type": "boolean", + "example": true }, "certificate_id": { "$ref": "../common.json#/properties/certificate_id" @@ -60,13 +84,33 @@ "$ref": "../common.json#/properties/block_exploits" }, "advanced_config": { - "type": "string" + "type": "string", + "example": "" }, "enabled": { "$ref": "../common.json#/properties/enabled" }, "meta": { - "type": "object" + "type": "object", + "example": { + "nginx_online": true, + "nginx_err": null + } + }, + "certificate": { + "oneOf": [ + { + "type": "null", + "example": null + }, + { + "$ref": "./certificate-object.json" + } + ], + "example": null + }, + "owner": { + "$ref": "./user-object.json" } } } diff --git a/backend/schema/components/security-schemes.json b/backend/schema/components/security-schemes.json index 82407be3f..4ae57bd79 100644 --- a/backend/schema/components/security-schemes.json +++ b/backend/schema/components/security-schemes.json @@ -1,6 +1,8 @@ { - "BearerAuth": { + "bearerAuth": { "type": "http", - "scheme": "bearer" + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "JWT Bearer Token authentication" } } diff --git a/backend/schema/components/stream-object.json b/backend/schema/components/stream-object.json index d4ba0a276..602073cec 100644 --- a/backend/schema/components/stream-object.json +++ b/backend/schema/components/stream-object.json @@ -1,7 +1,19 @@ { "type": "object", "description": "Stream object", - "required": ["id", "created_on", "modified_on", "owner_user_id", "incoming_port", "forwarding_host", "forwarding_port", "tcp_forwarding", "udp_forwarding", "enabled", "meta"], + "required": [ + "id", + "created_on", + "modified_on", + "owner_user_id", + "incoming_port", + "forwarding_host", + "forwarding_port", + "tcp_forwarding", + "udp_forwarding", + "enabled", + "meta" + ], "additionalProperties": false, "properties": { "id": { @@ -19,15 +31,16 @@ "incoming_port": { "type": "integer", "minimum": 1, - "maximum": 65535 + "maximum": 65535, + "example": 9090 }, "forwarding_host": { "anyOf": [ { "description": "Domain Name", - "example": "jc21.com", "type": "string", - "pattern": "^(?:[^.*]+\\.?)+[^.]$" + "pattern": "^(?:[^.*]+\\.?)+[^.]$", + "example": "example.com" }, { "type": "string", @@ -37,18 +50,22 @@ "type": "string", "format": "ipv6" } - ] + ], + "example": "example.com" }, "forwarding_port": { "type": "integer", "minimum": 1, - "maximum": 65535 + "maximum": 65535, + "example": 80 }, "tcp_forwarding": { - "type": "boolean" + "type": "boolean", + "example": true }, "udp_forwarding": { - "type": "boolean" + "type": "boolean", + "example": false }, "enabled": { "$ref": "../common.json#/properties/enabled" @@ -57,10 +74,8 @@ "$ref": "../common.json#/properties/certificate_id" }, "meta": { - "type": "object" - }, - "owner": { - "$ref": "./user-object.json" + "type": "object", + "example": {} }, "certificate": { "oneOf": [ @@ -70,7 +85,11 @@ { "$ref": "./certificate-object.json" } - ] + ], + "example": null + }, + "owner": { + "$ref": "./user-object.json" } } } diff --git a/backend/schema/components/user-object.json b/backend/schema/components/user-object.json index eec02a861..7acd0a429 100644 --- a/backend/schema/components/user-object.json +++ b/backend/schema/components/user-object.json @@ -77,37 +77,37 @@ "proxy_hosts": { "type": "string", "description": "Proxy Hosts access level", - "example": "all", + "example": "manage", "pattern": "^(manage|view|hidden)$" }, "redirection_hosts": { "type": "string", "description": "Redirection Hosts access level", - "example": "all", + "example": "manage", "pattern": "^(manage|view|hidden)$" }, "dead_hosts": { "type": "string", "description": "Dead Hosts access level", - "example": "all", + "example": "manage", "pattern": "^(manage|view|hidden)$" }, "streams": { "type": "string", "description": "Streams access level", - "example": "all", + "example": "manage", "pattern": "^(manage|view|hidden)$" }, "access_lists": { "type": "string", "description": "Access Lists access level", - "example": "all", + "example": "hidden", "pattern": "^(manage|view|hidden)$" }, "certificates": { "type": "string", "description": "Certificates access level", - "example": "all", + "example": "view", "pattern": "^(manage|view|hidden)$" } } diff --git a/backend/schema/paths/audit-log/get.json b/backend/schema/paths/audit-log/get.json index ecda9cefb..62c09ce16 100644 --- a/backend/schema/paths/audit-log/get.json +++ b/backend/schema/paths/audit-log/get.json @@ -1,10 +1,10 @@ { "operationId": "getAuditLogs", "summary": "Get Audit Logs", - "tags": ["Audit Log"], + "tags": ["audit-log"], "security": [ { - "BearerAuth": ["audit-log"] + "bearerAuth": ["admin"] } ], "responses": { diff --git a/backend/schema/paths/audit-log/id/get.json b/backend/schema/paths/audit-log/id/get.json index 74f597232..38ff1c762 100644 --- a/backend/schema/paths/audit-log/id/get.json +++ b/backend/schema/paths/audit-log/id/get.json @@ -1,13 +1,11 @@ { "operationId": "getAuditLog", "summary": "Get Audit Log Event", - "tags": [ - "Audit Log" - ], + "tags": ["audit-log"], "security": [ { - "BearerAuth": [ - "audit-log" + "bearerAuth": [ + "admin" ] } ], @@ -15,6 +13,7 @@ { "in": "path", "name": "id", + "description": "Audit Log Event ID", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/get.json b/backend/schema/paths/get.json index 9ca1b8d3f..9f6ba2a98 100644 --- a/backend/schema/paths/get.json +++ b/backend/schema/paths/get.json @@ -1,7 +1,7 @@ { "operationId": "health", "summary": "Returns the API health status", - "tags": ["Public"], + "tags": ["public"], "responses": { "200": { "description": "200 response", diff --git a/backend/schema/paths/nginx/access-lists/get.json b/backend/schema/paths/nginx/access-lists/get.json index a8b9adc69..ada40f5bf 100644 --- a/backend/schema/paths/nginx/access-lists/get.json +++ b/backend/schema/paths/nginx/access-lists/get.json @@ -1,10 +1,12 @@ { "operationId": "getAccessLists", "summary": "Get all access lists", - "tags": ["Access Lists"], + "tags": ["access-lists"], "security": [ { - "BearerAuth": ["access_lists"] + "bearerAuth": [ + "access_lists.view" + ] } ], "parameters": [ @@ -14,7 +16,12 @@ "description": "Expansions", "schema": { "type": "string", - "enum": ["owner", "items", "clients", "proxy_hosts"] + "enum": [ + "owner", + "items", + "clients", + "proxy_hosts" + ] } } ], @@ -23,22 +30,16 @@ "description": "200 response", "content": { "application/json": { - "examples": { - "default": { - "value": [ - { - "id": 1, - "created_on": "2024-10-08T22:15:40.000Z", - "modified_on": "2024-10-08T22:15:40.000Z", - "owner_user_id": 1, - "name": "test1234", - "meta": {}, - "satisfy_any": true, - "pass_auth": false, - "proxy_host_count": 0 - } - ] - } + "example": { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "owner_user_id": 1, + "name": "test1234", + "meta": {}, + "satisfy_any": true, + "pass_auth": false, + "proxy_host_count": 0 }, "schema": { "$ref": "../../../components/access-list-object.json" diff --git a/backend/schema/paths/nginx/access-lists/listID/delete.json b/backend/schema/paths/nginx/access-lists/listID/delete.json index 073585c8b..182a883a1 100644 --- a/backend/schema/paths/nginx/access-lists/listID/delete.json +++ b/backend/schema/paths/nginx/access-lists/listID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteAccessList", "summary": "Delete a Access List", - "tags": ["Access Lists"], + "tags": ["access-lists"], "security": [ { - "BearerAuth": ["access_lists"] + "bearerAuth": ["access_lists.manage"] } ], "parameters": [ { "in": "path", "name": "listID", + "description": "Access List ID", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/access-lists/listID/get.json b/backend/schema/paths/nginx/access-lists/listID/get.json index e67023f89..9705826f2 100644 --- a/backend/schema/paths/nginx/access-lists/listID/get.json +++ b/backend/schema/paths/nginx/access-lists/listID/get.json @@ -1,49 +1,54 @@ { - "operationId": "getAccessList", - "summary": "Get a access List", - "tags": ["Access Lists"], - "security": [ - { - "BearerAuth": ["access_lists"] - } - ], - "parameters": [ - { - "in": "path", - "name": "listID", - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "example": 1 - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": 1, - "created_on": "2020-01-30T09:36:08.000Z", - "modified_on": "2020-01-30T09:41:04.000Z", - "is_disabled": false, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"] - } - } - }, - "schema": { - "$ref": "../../../../components/access-list-object.json" - } - } - } - } - } + "operationId": "getAccessList", + "summary": "Get a access List", + "tags": [ + "access-lists" + ], + "security": [ + { + "bearerAuth": [ + "access_lists.view" + ] + } + ], + "parameters": [ + { + "in": "path", + "name": "listID", + "description": "Access List ID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2025-10-28T04:06:55.000Z", + "modified_on": "2025-10-29T22:48:20.000Z", + "owner_user_id": 1, + "name": "My Access List", + "meta": {}, + "satisfy_any": false, + "pass_auth": false, + "proxy_host_count": 1 + } + } + }, + "schema": { + "$ref": "../../../../components/access-list-object.json" + } + } + } + } + } } diff --git a/backend/schema/paths/nginx/access-lists/listID/put.json b/backend/schema/paths/nginx/access-lists/listID/put.json index 7f887dad6..61e804401 100644 --- a/backend/schema/paths/nginx/access-lists/listID/put.json +++ b/backend/schema/paths/nginx/access-lists/listID/put.json @@ -1,16 +1,17 @@ { "operationId": "updateAccessList", "summary": "Update a Access List", - "tags": ["Access Lists"], + "tags": ["access-lists"], "security": [ { - "BearerAuth": ["access_lists"] + "bearerAuth": ["access_lists.manage"] } ], "parameters": [ { "in": "path", "name": "listID", + "description": "Access List ID", "schema": { "type": "integer", "minimum": 1 @@ -39,50 +40,29 @@ "$ref": "../../../../components/access-list-object.json#/properties/pass_auth" }, "items": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string" - } - } - } + "$ref": "../../../../common.json#/properties/access_items" }, "clients": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "address": { - "oneOf": [ - { - "type": "string", - "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$" - }, - { - "type": "string", - "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" - }, - { - "type": "string", - "pattern": "^all$" - } - ] - }, - "directive": { - "$ref": "../../../../components/access-list-object.json#/properties/directive" - } - } - } + "$ref": "../../../../common.json#/properties/access_clients" } } + }, + "example": { + "name": "My Access List", + "satisfy_any": true, + "pass_auth": false, + "items": [ + { + "username": "admin2", + "password": "pass2" + } + ], + "clients": [ + { + "directive": "allow", + "address": "192.168.0.0/24" + } + ] } } } @@ -108,7 +88,6 @@ "id": 1, "created_on": "2024-10-07T22:43:55.000Z", "modified_on": "2024-10-08T12:52:54.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", diff --git a/backend/schema/paths/nginx/access-lists/post.json b/backend/schema/paths/nginx/access-lists/post.json index 4c5a4edd2..38b7003a1 100644 --- a/backend/schema/paths/nginx/access-lists/post.json +++ b/backend/schema/paths/nginx/access-lists/post.json @@ -1,10 +1,12 @@ { "operationId": "createAccessList", "summary": "Create a Access List", - "tags": ["Access Lists"], + "tags": ["access-lists"], "security": [ { - "BearerAuth": ["access_lists"] + "bearerAuth": [ + "access_lists.manage" + ] } ], "requestBody": { @@ -15,7 +17,9 @@ "schema": { "type": "object", "additionalProperties": false, - "required": ["name"], + "required": [ + "name" + ], "properties": { "name": { "$ref": "../../../components/access-list-object.json#/properties/name" @@ -27,54 +31,29 @@ "$ref": "../../../components/access-list-object.json#/properties/pass_auth" }, "items": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 1 - } - } - } + "$ref": "../../../common.json#/properties/access_items" }, "clients": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "address": { - "oneOf": [ - { - "type": "string", - "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$" - }, - { - "type": "string", - "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" - }, - { - "type": "string", - "pattern": "^all$" - } - ] - }, - "directive": { - "$ref": "../../../components/access-list-object.json#/properties/directive" - } - } - } - }, - "meta": { - "$ref": "../../../components/access-list-object.json#/properties/meta" + "$ref": "../../../common.json#/properties/access_clients" } } + }, + "example": { + "name": "My Access List", + "satisfy_any": true, + "pass_auth": false, + "items": [ + { + "username": "admin", + "password": "pass" + } + ], + "clients": [ + { + "directive": "allow", + "address": "192.168.0.0/24" + } + ] } } } @@ -100,13 +79,14 @@ "id": 1, "created_on": "2024-10-07T22:43:55.000Z", "modified_on": "2024-10-08T12:52:54.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", "nickname": "some guy", "avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm", - "roles": ["admin"] + "roles": [ + "admin" + ] }, "items": [ { diff --git a/backend/schema/paths/nginx/certificates/certID/delete.json b/backend/schema/paths/nginx/certificates/certID/delete.json index 0d40bcb8c..a99f619d6 100644 --- a/backend/schema/paths/nginx/certificates/certID/delete.json +++ b/backend/schema/paths/nginx/certificates/certID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteCertificate", "summary": "Delete a Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "parameters": [ { "in": "path", "name": "certID", + "description": "Certificate ID", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/certificates/certID/download/get.json b/backend/schema/paths/nginx/certificates/certID/download/get.json index 4b858cae7..7c18d019d 100644 --- a/backend/schema/paths/nginx/certificates/certID/download/get.json +++ b/backend/schema/paths/nginx/certificates/certID/download/get.json @@ -1,16 +1,17 @@ { "operationId": "downloadCertificate", "summary": "Downloads a Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "parameters": [ { "in": "path", "name": "certID", + "description": "Certificate ID", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/certificates/certID/get.json b/backend/schema/paths/nginx/certificates/certID/get.json index bc2895737..46afbf875 100644 --- a/backend/schema/paths/nginx/certificates/certID/get.json +++ b/backend/schema/paths/nginx/certificates/certID/get.json @@ -1,16 +1,17 @@ { "operationId": "getCertificate", "summary": "Get a Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.view"] } ], "parameters": [ { "in": "path", "name": "certID", + "description": "Certificate ID", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/certificates/certID/renew/post.json b/backend/schema/paths/nginx/certificates/certID/renew/post.json index b2c1dcd61..4466d38d3 100644 --- a/backend/schema/paths/nginx/certificates/certID/renew/post.json +++ b/backend/schema/paths/nginx/certificates/certID/renew/post.json @@ -1,16 +1,17 @@ { "operationId": "renewCertificate", "summary": "Renews a Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "parameters": [ { "in": "path", "name": "certID", + "description": "Certificate ID", "schema": { "type": "integer", "minimum": 1 @@ -32,7 +33,6 @@ "id": 4, "created_on": "2024-10-09T05:31:58.000Z", "owner_user_id": 1, - "is_deleted": false, "provider": "letsencrypt", "nice_name": "My Test Cert", "domain_names": ["test.jc21.supernerd.pro"], diff --git a/backend/schema/paths/nginx/certificates/certID/upload/post.json b/backend/schema/paths/nginx/certificates/certID/upload/post.json index f38b8102a..2b1ba3e61 100644 --- a/backend/schema/paths/nginx/certificates/certID/upload/post.json +++ b/backend/schema/paths/nginx/certificates/certID/upload/post.json @@ -1,16 +1,17 @@ { "operationId": "uploadCertificate", "summary": "Uploads a custom Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "parameters": [ { "in": "path", "name": "certID", + "description": "Certificate ID", "schema": { "type": "integer", "minimum": 1 @@ -20,28 +21,7 @@ } ], "requestBody": { - "description": "Certificate Files", - "required": true, - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "additionalProperties": false, - "required": ["certificate", "certificate_key"], - "properties": { - "certificate": { - "type": "string" - }, - "certificate_key": { - "type": "string" - }, - "intermediate_certificate": { - "type": "string" - } - } - } - } - } + "$ref": "../../../../../common.json#/properties/certificate_files" }, "responses": { "200": { @@ -63,15 +43,18 @@ "properties": { "certificate": { "type": "string", - "minLength": 1 + "minLength": 1, + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" }, "certificate_key": { "type": "string", - "minLength": 1 + "minLength": 1, + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" }, "intermediate_certificate": { "type": "string", - "minLength": 1 + "minLength": 1, + "example": "-----BEGIN CERTIFICATE-----\nMIID...-----END CERTIFICATE-----" } } } diff --git a/backend/schema/paths/nginx/certificates/dns-providers/get.json b/backend/schema/paths/nginx/certificates/dns-providers/get.json index ec0646272..3efb1a069 100644 --- a/backend/schema/paths/nginx/certificates/dns-providers/get.json +++ b/backend/schema/paths/nginx/certificates/dns-providers/get.json @@ -1,14 +1,10 @@ { "operationId": "getDNSProviders", "summary": "Get DNS Providers for Certificates", - "tags": [ - "Certificates" - ], + "tags": ["certificates"], "security": [ { - "BearerAuth": [ - "certificates" - ] + "bearerAuth": ["certificates.view"] } ], "responses": { diff --git a/backend/schema/paths/nginx/certificates/get.json b/backend/schema/paths/nginx/certificates/get.json index bd45e62a1..5884c9729 100644 --- a/backend/schema/paths/nginx/certificates/get.json +++ b/backend/schema/paths/nginx/certificates/get.json @@ -1,10 +1,10 @@ { "operationId": "getCertificates", "summary": "Get all certificates", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.view"] } ], "parameters": [ diff --git a/backend/schema/paths/nginx/certificates/post.json b/backend/schema/paths/nginx/certificates/post.json index f2bb2fa2d..15406c8b3 100644 --- a/backend/schema/paths/nginx/certificates/post.json +++ b/backend/schema/paths/nginx/certificates/post.json @@ -1,10 +1,10 @@ { "operationId": "createCertificate", "summary": "Create a Certificate", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "requestBody": { @@ -30,6 +30,13 @@ "$ref": "../../../components/certificate-object.json#/properties/meta" } } + }, + "example": { + "provider": "letsencrypt", + "domain_names": ["test.example.com"], + "meta": { + "dns_challenge": false + } } } } @@ -47,7 +54,6 @@ "id": 5, "created_on": "2024-10-09 05:28:35", "owner_user_id": 1, - "is_deleted": false, "provider": "letsencrypt", "nice_name": "test.example.com", "domain_names": ["test.example.com"], diff --git a/backend/schema/paths/nginx/certificates/test-http/post.json b/backend/schema/paths/nginx/certificates/test-http/post.json index f4f82e3fc..4d738d018 100644 --- a/backend/schema/paths/nginx/certificates/test-http/post.json +++ b/backend/schema/paths/nginx/certificates/test-http/post.json @@ -1,10 +1,10 @@ { "operationId": "testHttpReach", "summary": "Test HTTP Reachability", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.view"] } ], "requestBody": { diff --git a/backend/schema/paths/nginx/certificates/validate/post.json b/backend/schema/paths/nginx/certificates/validate/post.json index 21eb325ef..9fa2bd126 100644 --- a/backend/schema/paths/nginx/certificates/validate/post.json +++ b/backend/schema/paths/nginx/certificates/validate/post.json @@ -1,35 +1,14 @@ { "operationId": "validateCertificates", "summary": "Validates given Custom Certificates", - "tags": ["Certificates"], + "tags": ["certificates"], "security": [ { - "BearerAuth": ["certificates"] + "bearerAuth": ["certificates.manage"] } ], "requestBody": { - "description": "Certificate Files", - "required": true, - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "additionalProperties": false, - "required": ["certificate", "certificate_key"], - "properties": { - "certificate": { - "type": "string" - }, - "certificate_key": { - "type": "string" - }, - "intermediate_certificate": { - "type": "string" - } - } - } - } - } + "$ref": "../../../../common.json#/properties/certificate_files" }, "responses": { "200": { @@ -62,10 +41,12 @@ "required": ["cn", "issuer", "dates"], "properties": { "cn": { - "type": "string" + "type": "string", + "example": "example.com" }, "issuer": { - "type": "string" + "type": "string", + "example": "C = US, O = Let's Encrypt, CN = E5" }, "dates": { "type": "object", @@ -78,12 +59,17 @@ "to": { "type": "integer" } + }, + "example": { + "from": 1728448218, + "to": 1736224217 } } } }, "certificate_key": { - "type": "boolean" + "type": "boolean", + "example": true } } } diff --git a/backend/schema/paths/nginx/dead-hosts/get.json b/backend/schema/paths/nginx/dead-hosts/get.json index 8a11a3f66..feb04ff22 100644 --- a/backend/schema/paths/nginx/dead-hosts/get.json +++ b/backend/schema/paths/nginx/dead-hosts/get.json @@ -1,10 +1,10 @@ { "operationId": "getDeadHosts", "summary": "Get all 404 hosts", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.view"] } ], "parameters": [ diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/delete.json b/backend/schema/paths/nginx/dead-hosts/hostID/delete.json index f3aa81a5b..eed0ebc01 100644 --- a/backend/schema/paths/nginx/dead-hosts/hostID/delete.json +++ b/backend/schema/paths/nginx/dead-hosts/hostID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteDeadHost", "summary": "Delete a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the 404 Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json index 2cdcecf4b..2a4d08aeb 100644 --- a/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json +++ b/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json @@ -1,16 +1,17 @@ { "operationId": "disableDeadHost", "summary": "Disable a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the 404 Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json index ca3ce9fae..512c2a0af 100644 --- a/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json +++ b/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json @@ -1,16 +1,17 @@ { "operationId": "enableDeadHost", "summary": "Enable a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the 404 Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/get.json b/backend/schema/paths/nginx/dead-hosts/hostID/get.json index 47e2f8b12..a3c24edc3 100644 --- a/backend/schema/paths/nginx/dead-hosts/hostID/get.json +++ b/backend/schema/paths/nginx/dead-hosts/hostID/get.json @@ -1,16 +1,17 @@ { "operationId": "getDeadHost", "summary": "Get a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.view"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the 404 Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/put.json b/backend/schema/paths/nginx/dead-hosts/hostID/put.json index f9505ed48..e07217c45 100644 --- a/backend/schema/paths/nginx/dead-hosts/hostID/put.json +++ b/backend/schema/paths/nginx/dead-hosts/hostID/put.json @@ -1,16 +1,17 @@ { "operationId": "updateDeadHost", "summary": "Update a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": ["dead_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the 404 Host", "schema": { "type": "integer", "minimum": 1 @@ -86,7 +87,6 @@ "id": 1, "created_on": "2024-10-09T00:59:56.000Z", "modified_on": "2024-10-09T00:59:56.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", diff --git a/backend/schema/paths/nginx/dead-hosts/post.json b/backend/schema/paths/nginx/dead-hosts/post.json index c8bbb6932..1ec38720c 100644 --- a/backend/schema/paths/nginx/dead-hosts/post.json +++ b/backend/schema/paths/nginx/dead-hosts/post.json @@ -1,10 +1,12 @@ { "operationId": "create404Host", "summary": "Create a 404 Host", - "tags": ["404 Hosts"], + "tags": ["404-hosts"], "security": [ { - "BearerAuth": ["dead_hosts"] + "bearerAuth": [ + "dead_hosts.manage" + ] } ], "requestBody": { @@ -15,7 +17,9 @@ "schema": { "type": "object", "additionalProperties": false, - "required": ["domain_names"], + "required": [ + "domain_names" + ], "properties": { "domain_names": { "$ref": "../../../components/dead-host-object.json#/properties/domain_names" @@ -42,6 +46,18 @@ "$ref": "../../../components/dead-host-object.json#/properties/meta" } } + }, + "example": { + "domain_names": [ + "test.example.com" + ], + "certificate_id": 0, + "ssl_forced": false, + "advanced_config": "", + "http2_support": false, + "hsts_enabled": false, + "hsts_subdomains": false, + "meta": {} } } } @@ -58,7 +74,9 @@ "created_on": "2024-10-09T01:38:52.000Z", "modified_on": "2024-10-09T01:38:52.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], + "domain_names": [ + "test.example.com" + ], "certificate_id": 0, "ssl_forced": false, "advanced_config": "", @@ -72,13 +90,14 @@ "id": 1, "created_on": "2024-10-09T00:59:56.000Z", "modified_on": "2024-10-09T00:59:56.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", "nickname": "Admin", "avatar": "", - "roles": ["admin"] + "roles": [ + "admin" + ] } } } diff --git a/backend/schema/paths/nginx/proxy-hosts/get.json b/backend/schema/paths/nginx/proxy-hosts/get.json index 1d9f63351..7f8cb148a 100644 --- a/backend/schema/paths/nginx/proxy-hosts/get.json +++ b/backend/schema/paths/nginx/proxy-hosts/get.json @@ -1,10 +1,12 @@ { "operationId": "getProxyHosts", "summary": "Get all proxy hosts", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": [ + "proxy_hosts.view" + ] } ], "parameters": [ @@ -14,7 +16,11 @@ "description": "Expansions", "schema": { "type": "string", - "enum": ["access_list", "owner", "certificate"] + "enum": [ + "access_list", + "owner", + "certificate" + ] } } ], @@ -28,14 +34,16 @@ "value": [ { "id": 1, - "created_on": "2024-10-08T23:23:03.000Z", - "modified_on": "2024-10-08T23:23:04.000Z", + "created_on": "2025-10-28T01:10:26.000Z", + "modified_on": "2025-10-28T04:07:16.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], + "domain_names": [ + "test.jc21com" + ], "forward_host": "127.0.0.1", - "forward_port": 8989, - "access_list_id": 0, - "certificate_id": 0, + "forward_port": 8081, + "access_list_id": 1, + "certificate_id": 1, "ssl_forced": false, "caching_enabled": false, "block_exploits": false, @@ -48,7 +56,7 @@ "http2_support": false, "forward_scheme": "http", "enabled": true, - "locations": null, + "locations": [], "hsts_enabled": false, "hsts_subdomains": false } diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json b/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json index 991ef0e9e..da67944d5 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteProxyHost", "summary": "Delete a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": ["proxy_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Proxy Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json index 54ff8a663..14c2689c0 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json @@ -1,16 +1,17 @@ { "operationId": "disableProxyHost", "summary": "Disable a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": ["proxy_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Proxy Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json index 9f052de05..fe504b781 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json @@ -1,16 +1,17 @@ { "operationId": "enableProxyHost", "summary": "Enable a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": ["proxy_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Proxy Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/get.json b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json index 5e10a9cfd..351451c4f 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/get.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json @@ -1,16 +1,19 @@ { "operationId": "getProxyHost", "summary": "Get a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": [ + "proxy_hosts.view" + ] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Proxy Host", "schema": { "type": "integer", "minimum": 1 @@ -27,13 +30,15 @@ "examples": { "default": { "value": { - "id": 1, - "created_on": "2024-10-08T23:23:03.000Z", - "modified_on": "2024-10-08T23:26:38.000Z", + "id": 3, + "created_on": "2025-10-30T01:12:05.000Z", + "modified_on": "2025-10-30T01:12:05.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], - "forward_host": "192.168.0.10", - "forward_port": 8989, + "domain_names": [ + "test.example.com" + ], + "forward_host": "127.0.0.1", + "forward_port": 8080, "access_list_id": 0, "certificate_id": 0, "ssl_forced": false, @@ -48,9 +53,22 @@ "http2_support": false, "forward_scheme": "http", "enabled": true, - "locations": null, + "locations": [], "hsts_enabled": false, - "hsts_subdomains": false + "hsts_subdomains": false, + "owner": { + "id": 1, + "created_on": "2025-10-28T00:50:24.000Z", + "modified_on": "2025-10-28T00:50:24.000Z", + "is_disabled": false, + "email": "jc@jc21.com", + "name": "jamiec", + "nickname": "jamiec", + "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", + "roles": [ + "admin" + ] + } } } }, diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json index 5cab6e752..7ae60e1af 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json @@ -1,16 +1,19 @@ { "operationId": "updateProxyHost", "summary": "Update a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": [ + "proxy_hosts.manage" + ] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Proxy Host", "schema": { "type": "integer", "minimum": 1 @@ -93,13 +96,15 @@ "examples": { "default": { "value": { - "id": 1, - "created_on": "2024-10-08T23:23:03.000Z", - "modified_on": "2024-10-08T23:26:37.000Z", + "id": 3, + "created_on": "2025-10-30T01:12:05.000Z", + "modified_on": "2025-10-30T01:17:06.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], - "forward_host": "192.168.0.10", - "forward_port": 8989, + "domain_names": [ + "test.example.com" + ], + "forward_host": "127.0.0.1", + "forward_port": 8080, "access_list_id": 0, "certificate_id": 0, "ssl_forced": false, @@ -114,19 +119,21 @@ "http2_support": false, "forward_scheme": "http", "enabled": true, + "locations": [], "hsts_enabled": false, "hsts_subdomains": false, "owner": { "id": 1, - "created_on": "2024-10-07T22:43:55.000Z", - "modified_on": "2024-10-08T12:52:54.000Z", - "is_deleted": false, + "created_on": "2025-10-28T00:50:24.000Z", + "modified_on": "2025-10-28T00:50:24.000Z", "is_disabled": false, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "some guy", - "avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm", - "roles": ["admin"] + "email": "jc@jc21.com", + "name": "jamiec", + "nickname": "jamiec", + "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", + "roles": [ + "admin" + ] }, "certificate": null, "access_list": null diff --git a/backend/schema/paths/nginx/proxy-hosts/post.json b/backend/schema/paths/nginx/proxy-hosts/post.json index 85455fb6b..77d772e94 100644 --- a/backend/schema/paths/nginx/proxy-hosts/post.json +++ b/backend/schema/paths/nginx/proxy-hosts/post.json @@ -1,10 +1,12 @@ { "operationId": "createProxyHost", "summary": "Create a Proxy Host", - "tags": ["Proxy Hosts"], + "tags": ["proxy-hosts"], "security": [ { - "BearerAuth": ["proxy_hosts"] + "bearerAuth": [ + "proxy_hosts.manage" + ] } ], "requestBody": { @@ -15,7 +17,12 @@ "schema": { "type": "object", "additionalProperties": false, - "required": ["domain_names", "forward_scheme", "forward_host", "forward_port"], + "required": [ + "domain_names", + "forward_scheme", + "forward_host", + "forward_port" + ], "properties": { "domain_names": { "$ref": "../../../components/proxy-host-object.json#/properties/domain_names" @@ -69,6 +76,14 @@ "$ref": "../../../components/proxy-host-object.json#/properties/locations" } } + }, + "example": { + "domain_names": [ + "test.example.com" + ], + "forward_scheme": "http", + "forward_host": "127.0.0.1", + "forward_port": 8080 } } } @@ -81,13 +96,15 @@ "examples": { "default": { "value": { - "id": 1, - "created_on": "2024-10-08T23:23:03.000Z", - "modified_on": "2024-10-08T23:23:03.000Z", + "id": 3, + "created_on": "2025-10-30T01:12:05.000Z", + "modified_on": "2025-10-30T01:12:05.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], + "domain_names": [ + "test.example.com" + ], "forward_host": "127.0.0.1", - "forward_port": 8989, + "forward_port": 8080, "access_list_id": 0, "certificate_id": 0, "ssl_forced": false, @@ -99,20 +116,22 @@ "http2_support": false, "forward_scheme": "http", "enabled": true, + "locations": [], "hsts_enabled": false, "hsts_subdomains": false, "certificate": null, "owner": { "id": 1, - "created_on": "2024-10-07T22:43:55.000Z", - "modified_on": "2024-10-08T12:52:54.000Z", - "is_deleted": false, + "created_on": "2025-10-28T00:50:24.000Z", + "modified_on": "2025-10-28T00:50:24.000Z", "is_disabled": false, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "some guy", - "avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm", - "roles": ["admin"] + "email": "jc@jc21.com", + "name": "jamiec", + "nickname": "jamiec", + "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", + "roles": [ + "admin" + ] }, "access_list": null } diff --git a/backend/schema/paths/nginx/redirection-hosts/get.json b/backend/schema/paths/nginx/redirection-hosts/get.json index 0b35e0fc4..dfeb60497 100644 --- a/backend/schema/paths/nginx/redirection-hosts/get.json +++ b/backend/schema/paths/nginx/redirection-hosts/get.json @@ -1,10 +1,10 @@ { "operationId": "getRedirectionHosts", "summary": "Get all Redirection hosts", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.view"] } ], "parameters": [ diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json b/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json index 7330f3623..0b3232e81 100644 --- a/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteRedirectionHost", "summary": "Delete a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Redirection Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json index 8433220d5..f44af11fd 100644 --- a/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json @@ -1,16 +1,17 @@ { "operationId": "disableRedirectionHost", "summary": "Disable a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Redirection Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json index bef53436b..07bf44dd3 100644 --- a/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json @@ -1,16 +1,17 @@ { "operationId": "enableRedirectionHost", "summary": "Enable a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Redirection Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/get.json b/backend/schema/paths/nginx/redirection-hosts/hostID/get.json index d780f874b..577b5144a 100644 --- a/backend/schema/paths/nginx/redirection-hosts/hostID/get.json +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/get.json @@ -1,16 +1,17 @@ { "operationId": "getRedirectionHost", "summary": "Get a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.view"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Redirection Host", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/put.json b/backend/schema/paths/nginx/redirection-hosts/hostID/put.json index fd97cbfa8..454a38805 100644 --- a/backend/schema/paths/nginx/redirection-hosts/hostID/put.json +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/put.json @@ -1,16 +1,17 @@ { "operationId": "updateRedirectionHost", "summary": "Update a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": ["redirection_hosts.manage"] } ], "parameters": [ { "in": "path", "name": "hostID", + "description": "The ID of the Redirection Host", "schema": { "type": "integer", "minimum": 1 @@ -106,7 +107,6 @@ "id": 1, "created_on": "2024-10-09T00:59:56.000Z", "modified_on": "2024-10-09T00:59:56.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", diff --git a/backend/schema/paths/nginx/redirection-hosts/post.json b/backend/schema/paths/nginx/redirection-hosts/post.json index 5bfde2c38..6aa533010 100644 --- a/backend/schema/paths/nginx/redirection-hosts/post.json +++ b/backend/schema/paths/nginx/redirection-hosts/post.json @@ -1,10 +1,12 @@ { "operationId": "createRedirectionHost", "summary": "Create a Redirection Host", - "tags": ["Redirection Hosts"], + "tags": ["redirection-hosts"], "security": [ { - "BearerAuth": ["redirection_hosts"] + "bearerAuth": [ + "redirection_hosts.manage" + ] } ], "requestBody": { @@ -15,7 +17,12 @@ "schema": { "type": "object", "additionalProperties": false, - "required": ["domain_names", "forward_scheme", "forward_http_code", "forward_domain_name"], + "required": [ + "domain_names", + "forward_scheme", + "forward_http_code", + "forward_domain_name" + ], "properties": { "domain_names": { "$ref": "../../../components/redirection-host-object.json#/properties/domain_names" @@ -57,6 +64,23 @@ "$ref": "../../../components/redirection-host-object.json#/properties/meta" } } + }, + "example": { + "domain_names": [ + "test.example.com" + ], + "forward_domain_name": "example.com", + "forward_scheme": "auto", + "forward_http_code": 301, + "preserve_path": false, + "block_exploits": false, + "certificate_id": 0, + "ssl_forced": false, + "http2_support": false, + "hsts_enabled": false, + "hsts_subdomains": false, + "advanced_config": "", + "meta": {} } } } @@ -69,12 +93,14 @@ "examples": { "default": { "value": { - "id": 1, - "created_on": "2024-10-09T01:13:12.000Z", - "modified_on": "2024-10-09T01:13:12.000Z", + "id": 2, + "created_on": "2025-10-30T01:27:04.000Z", + "modified_on": "2025-10-30T01:27:04.000Z", "owner_user_id": 1, - "domain_names": ["test.example.com"], - "forward_domain_name": "something-else.com", + "domain_names": [ + "test.example.com" + ], + "forward_domain_name": "example.com", "preserve_path": false, "certificate_id": 0, "ssl_forced": false, @@ -85,20 +111,21 @@ "enabled": true, "hsts_enabled": false, "hsts_subdomains": false, - "forward_scheme": "http", + "forward_scheme": "auto", "forward_http_code": 301, "certificate": null, "owner": { "id": 1, - "created_on": "2024-10-09T00:59:56.000Z", - "modified_on": "2024-10-09T00:59:56.000Z", - "is_deleted": false, + "created_on": "2025-10-28T00:50:24.000Z", + "modified_on": "2025-10-28T00:50:24.000Z", "is_disabled": false, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "Admin", - "avatar": "", - "roles": ["admin"] + "email": "jc@jc21.com", + "name": "jamiec", + "nickname": "jamiec", + "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", + "roles": [ + "admin" + ] } } } diff --git a/backend/schema/paths/nginx/streams/get.json b/backend/schema/paths/nginx/streams/get.json index 17969ee4e..6dda8e346 100644 --- a/backend/schema/paths/nginx/streams/get.json +++ b/backend/schema/paths/nginx/streams/get.json @@ -1,10 +1,10 @@ { "operationId": "getStreams", "summary": "Get all streams", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.view"] } ], "parameters": [ diff --git a/backend/schema/paths/nginx/streams/post.json b/backend/schema/paths/nginx/streams/post.json index 0ee6c6eb4..0c986de8f 100644 --- a/backend/schema/paths/nginx/streams/post.json +++ b/backend/schema/paths/nginx/streams/post.json @@ -1,10 +1,12 @@ { "operationId": "createStream", "summary": "Create a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": [ + "streams.manage" + ] } ], "requestBody": { @@ -15,7 +17,11 @@ "schema": { "type": "object", "additionalProperties": false, - "required": ["incoming_port", "forwarding_host", "forwarding_port"], + "required": [ + "incoming_port", + "forwarding_host", + "forwarding_port" + ], "properties": { "incoming_port": { "$ref": "../../../components/stream-object.json#/properties/incoming_port" @@ -42,6 +48,15 @@ "$ref": "../../../components/dead-host-object.json#/properties/domain_names" } } + }, + "example": { + "incoming_port": 8888, + "forwarding_host": "127.0.0.1", + "forwarding_port": 8080, + "tcp_forwarding": true, + "udp_forwarding": false, + "certificate_id": 0, + "meta": {} } } } @@ -72,13 +87,14 @@ "id": 1, "created_on": "2024-10-09T02:33:16.000Z", "modified_on": "2024-10-09T02:33:16.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", "nickname": "Admin", "avatar": "", - "roles": ["admin"] + "roles": [ + "admin" + ] }, "certificate_id": 0 } diff --git a/backend/schema/paths/nginx/streams/streamID/delete.json b/backend/schema/paths/nginx/streams/streamID/delete.json index 3a9685258..585cd82d1 100644 --- a/backend/schema/paths/nginx/streams/streamID/delete.json +++ b/backend/schema/paths/nginx/streams/streamID/delete.json @@ -1,16 +1,17 @@ { "operationId": "deleteStream", "summary": "Delete a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.manage"] } ], "parameters": [ { "in": "path", "name": "streamID", + "description": "The ID of the Stream", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/streams/streamID/disable/post.json b/backend/schema/paths/nginx/streams/streamID/disable/post.json index d1c1b1c84..61de85168 100644 --- a/backend/schema/paths/nginx/streams/streamID/disable/post.json +++ b/backend/schema/paths/nginx/streams/streamID/disable/post.json @@ -1,16 +1,17 @@ { "operationId": "disableStream", "summary": "Disable a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.manage"] } ], "parameters": [ { "in": "path", "name": "streamID", + "description": "The ID of the Stream", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/streams/streamID/enable/post.json b/backend/schema/paths/nginx/streams/streamID/enable/post.json index dc914f5f2..d27ce5265 100644 --- a/backend/schema/paths/nginx/streams/streamID/enable/post.json +++ b/backend/schema/paths/nginx/streams/streamID/enable/post.json @@ -1,16 +1,17 @@ { "operationId": "enableStream", "summary": "Enable a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.manage"] } ], "parameters": [ { "in": "path", "name": "streamID", + "description": "The ID of the Stream", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/streams/streamID/get.json b/backend/schema/paths/nginx/streams/streamID/get.json index 801af13a7..22fae8872 100644 --- a/backend/schema/paths/nginx/streams/streamID/get.json +++ b/backend/schema/paths/nginx/streams/streamID/get.json @@ -1,16 +1,17 @@ { "operationId": "getStream", "summary": "Get a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.view"] } ], "parameters": [ { "in": "path", "name": "streamID", + "description": "The ID of the Stream", "schema": { "type": "integer", "minimum": 1 diff --git a/backend/schema/paths/nginx/streams/streamID/put.json b/backend/schema/paths/nginx/streams/streamID/put.json index 14adb1631..21ae71ef7 100644 --- a/backend/schema/paths/nginx/streams/streamID/put.json +++ b/backend/schema/paths/nginx/streams/streamID/put.json @@ -1,16 +1,17 @@ { "operationId": "updateStream", "summary": "Update a Stream", - "tags": ["Streams"], + "tags": ["streams"], "security": [ { - "BearerAuth": ["streams"] + "bearerAuth": ["streams.manage"] } ], "parameters": [ { "in": "path", "name": "streamID", + "description": "The ID of the Stream", "schema": { "type": "integer", "minimum": 1 @@ -81,7 +82,6 @@ "id": 1, "created_on": "2024-10-09T02:33:16.000Z", "modified_on": "2024-10-09T02:33:16.000Z", - "is_deleted": false, "is_disabled": false, "email": "admin@example.com", "name": "Administrator", diff --git a/backend/schema/paths/reports/hosts/get.json b/backend/schema/paths/reports/hosts/get.json index a40ddc723..682a97b88 100644 --- a/backend/schema/paths/reports/hosts/get.json +++ b/backend/schema/paths/reports/hosts/get.json @@ -1,10 +1,10 @@ { "operationId": "reportsHosts", "summary": "Report on Host Statistics", - "tags": ["Reports"], + "tags": ["reports"], "security": [ { - "BearerAuth": ["reports"] + "bearerAuth": [] } ], "responses": { @@ -27,19 +27,23 @@ "properties": { "proxy": { "type": "integer", - "description": "Proxy Hosts Count" + "description": "Proxy Hosts Count", + "example": 20 }, "redirection": { "type": "integer", - "description": "Redirection Hosts Count" + "description": "Redirection Hosts Count", + "example": 2 }, "stream": { "type": "integer", - "description": "Streams Count" + "description": "Streams Count", + "example": 0 }, "dead": { "type": "integer", - "description": "404 Hosts Count" + "description": "404 Hosts Count", + "example": 3 } } } diff --git a/backend/schema/paths/schema/get.json b/backend/schema/paths/schema/get.json index d435b0042..c9e601eab 100644 --- a/backend/schema/paths/schema/get.json +++ b/backend/schema/paths/schema/get.json @@ -1,7 +1,7 @@ { "operationId": "schema", "summary": "Returns this swagger API schema", - "tags": ["Public"], + "tags": ["public"], "responses": { "200": { "description": "200 response" diff --git a/backend/schema/paths/settings/get.json b/backend/schema/paths/settings/get.json index 5d148d8af..a99f7f220 100644 --- a/backend/schema/paths/settings/get.json +++ b/backend/schema/paths/settings/get.json @@ -1,10 +1,10 @@ { "operationId": "getSettings", "summary": "Get all settings", - "tags": ["Settings"], + "tags": ["settings"], "security": [ { - "BearerAuth": ["settings"] + "bearerAuth": ["admin"] } ], "responses": { diff --git a/backend/schema/paths/settings/settingID/get.json b/backend/schema/paths/settings/settingID/get.json index 405b976d2..929f3e5f3 100644 --- a/backend/schema/paths/settings/settingID/get.json +++ b/backend/schema/paths/settings/settingID/get.json @@ -1,10 +1,10 @@ { "operationId": "getSetting", "summary": "Get a setting", - "tags": ["Settings"], + "tags": ["settings"], "security": [ { - "BearerAuth": ["settings"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/paths/settings/settingID/put.json b/backend/schema/paths/settings/settingID/put.json index 4ca624293..050ad4412 100644 --- a/backend/schema/paths/settings/settingID/put.json +++ b/backend/schema/paths/settings/settingID/put.json @@ -1,10 +1,10 @@ { "operationId": "updateSetting", "summary": "Update a setting", - "tags": ["Settings"], + "tags": ["settings"], "security": [ { - "BearerAuth": ["settings"] + "bearerAuth": ["admin"] } ], "parameters": [ @@ -34,7 +34,8 @@ "value": { "type": "string", "minLength": 1, - "enum": ["congratulations", "404", "444", "redirect", "html"] + "enum": ["congratulations", "404", "444", "redirect", "html"], + "example": "html" }, "meta": { "type": "object", @@ -46,9 +47,16 @@ "html": { "type": "string" } + }, + "example": { + "html": "

hello world

" } } } + }, + "example": { + "value": "congratulations", + "meta": {} } } } diff --git a/backend/schema/paths/tokens/get.json b/backend/schema/paths/tokens/get.json index ef842eafe..4e6ae2449 100644 --- a/backend/schema/paths/tokens/get.json +++ b/backend/schema/paths/tokens/get.json @@ -1,10 +1,10 @@ { "operationId": "refreshToken", "summary": "Refresh your access token", - "tags": ["Tokens"], + "tags": ["tokens"], "security": [ { - "BearerAuth": ["tokens"] + "bearerAuth": [] } ], "responses": { diff --git a/backend/schema/paths/tokens/post.json b/backend/schema/paths/tokens/post.json index 99703ff0d..f8a639ad5 100644 --- a/backend/schema/paths/tokens/post.json +++ b/backend/schema/paths/tokens/post.json @@ -1,7 +1,7 @@ { "operationId": "requestToken", "summary": "Request a new access token from credentials", - "tags": ["Tokens"], + "tags": ["tokens"], "requestBody": { "description": "Credentials Payload", "required": true, @@ -12,20 +12,27 @@ "properties": { "identity": { "minLength": 1, - "type": "string" + "type": "string", + "example": "me@example.com" }, "scope": { "minLength": 1, "type": "string", - "enum": ["user"] + "enum": ["user"], + "example": "user" }, "secret": { "minLength": 1, - "type": "string" + "type": "string", + "example": "bigredhorsebanana" } }, "required": ["identity", "secret"], "type": "object" + }, + "example": { + "identity": "me@example.com", + "secret": "bigredhorsebanana" } } } @@ -37,10 +44,8 @@ "examples": { "default": { "value": { - "result": { - "expires": "2025-02-04T20:40:46.340Z", - "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" - } + "expires": "2025-02-04T20:40:46.340Z", + "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" } } }, diff --git a/backend/schema/paths/users/get.json b/backend/schema/paths/users/get.json index 374153011..79c31ba80 100644 --- a/backend/schema/paths/users/get.json +++ b/backend/schema/paths/users/get.json @@ -1,10 +1,10 @@ { "operationId": "getUsers", "summary": "Get all users", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/paths/users/post.json b/backend/schema/paths/users/post.json index c0213fe05..49025e325 100644 --- a/backend/schema/paths/users/post.json +++ b/backend/schema/paths/users/post.json @@ -1,10 +1,10 @@ { "operationId": "createUser", "summary": "Create a User", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "requestBody": { diff --git a/backend/schema/paths/users/userID/auth/put.json b/backend/schema/paths/users/userID/auth/put.json index a72f5617c..3dba45b5a 100644 --- a/backend/schema/paths/users/userID/auth/put.json +++ b/backend/schema/paths/users/userID/auth/put.json @@ -1,10 +1,10 @@ { "operationId": "updateUserAuth", "summary": "Update a User's Authentication", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/paths/users/userID/delete.json b/backend/schema/paths/users/userID/delete.json index 7d4f36151..767edfe89 100644 --- a/backend/schema/paths/users/userID/delete.json +++ b/backend/schema/paths/users/userID/delete.json @@ -1,10 +1,10 @@ { "operationId": "deleteUser", "summary": "Delete a User", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/paths/users/userID/get.json b/backend/schema/paths/users/userID/get.json index cb8ac61b4..2cf5587d9 100644 --- a/backend/schema/paths/users/userID/get.json +++ b/backend/schema/paths/users/userID/get.json @@ -1,10 +1,10 @@ { "operationId": "getUser", "summary": "Get a user", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/paths/users/userID/login/post.json b/backend/schema/paths/users/userID/login/post.json index 6148d182b..46001d2ec 100644 --- a/backend/schema/paths/users/userID/login/post.json +++ b/backend/schema/paths/users/userID/login/post.json @@ -1,10 +1,10 @@ { "operationId": "loginAsUser", "summary": "Login as this user", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ @@ -35,11 +35,11 @@ "created_on": "2020-01-30T10:43:44.000Z", "modified_on": "2020-01-30T10:43:44.000Z", "is_disabled": false, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", + "email": "user2@example.com", + "name": "John Doe", + "nickname": "Jonny", "avatar": "//www.gravatar.com/avatar/3c8d73f45fd8763f827b964c76e6032a?default=mm", - "roles": ["admin"] + "roles": [] } } } @@ -50,16 +50,15 @@ "required": ["expires", "token", "user"], "additionalProperties": false, "properties": { - "expires": { - "description": "Token Expiry Unix Time", - "example": 1566540249, - "minimum": 1, - "type": "number" - }, "token": { "description": "JWT Token", - "example": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4", - "type": "string" + "type": "string", + "example": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" + }, + "expires": { + "description": "Token Expiry Timestamp", + "type": "string", + "example": "2020-01-30T10:43:44.000Z" }, "user": { "$ref": "../../../../components/user-object.json" diff --git a/backend/schema/paths/users/userID/permissions/put.json b/backend/schema/paths/users/userID/permissions/put.json index 2dcd2aed7..764e7466c 100644 --- a/backend/schema/paths/users/userID/permissions/put.json +++ b/backend/schema/paths/users/userID/permissions/put.json @@ -1,10 +1,10 @@ { "operationId": "updateUserPermissions", "summary": "Update a User's Permissions", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ @@ -27,6 +27,15 @@ "application/json": { "schema": { "$ref": "../../../../components/permission-object.json" + }, + "example": { + "visibility": "all", + "access_lists": "view", + "certificates": "hidden", + "dead_hosts": "hidden", + "proxy_hosts": "manage", + "redirection_hosts": "hidden", + "streams": "hidden" } } } diff --git a/backend/schema/paths/users/userID/put.json b/backend/schema/paths/users/userID/put.json index 60a6cd132..eabaa3a0e 100644 --- a/backend/schema/paths/users/userID/put.json +++ b/backend/schema/paths/users/userID/put.json @@ -1,10 +1,10 @@ { "operationId": "updateUser", "summary": "Update a User", - "tags": ["Users"], + "tags": ["users"], "security": [ { - "BearerAuth": ["users"] + "bearerAuth": ["admin"] } ], "parameters": [ diff --git a/backend/schema/swagger.json b/backend/schema/swagger.json index 7feb4ebc8..e7234d4ec 100644 --- a/backend/schema/swagger.json +++ b/backend/schema/swagger.json @@ -2,7 +2,8 @@ "openapi": "3.1.0", "info": { "title": "Nginx Proxy Manager API", - "version": "2.x.x" + "version": "2.x.x", + "description": "This is the official API documentation for Nginx Proxy Manager.\n\nMost endpoints require authentication via Bearer Token (JWT). You can generate a token by logging in via the `POST /tokens` endpoint.\n\nFor more information, visit the [Nginx Proxy Manager Documentation](https://nginxproxymanager.com)." }, "servers": [ { @@ -11,13 +12,59 @@ ], "components": { "securitySchemes": { - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "bearerFormat": "JWT" - } + "$ref": "./components/security-schemes.json" } }, + "tags": [ + { + "name": "public", + "description": "Endpoints that do not require authentication" + }, + { + "name": "audit-log", + "description": "Endpoints related to Audit Logs" + }, + { + "name": "access-lists", + "description": "Endpoints related to Access Lists" + }, + { + "name": "certificates", + "description": "Endpoints related to Certificates" + }, + { + "name": "404-hosts", + "description": "Endpoints related to 404 Hosts" + }, + { + "name": "proxy-hosts", + "description": "Endpoints related to Proxy Hosts" + }, + { + "name": "redirection-hosts", + "description": "Endpoints related to Redirection Hosts" + }, + { + "name": "streams", + "description": "Endpoints related to Streams" + }, + { + "name": "reports", + "description": "Endpoints for viewing reports" + }, + { + "name": "settings", + "description": "Endpoints for managing application settings" + }, + { + "name": "tokens", + "description": "Endpoints for managing authentication tokens" + }, + { + "name": "users", + "description": "Endpoints for managing users" + } + ], "paths": { "/": { "get": { diff --git a/test/cypress/e2e/api/SwaggerSchema.cy.js b/test/cypress/e2e/api/SwaggerSchema.cy.js new file mode 100644 index 000000000..63578e21e --- /dev/null +++ b/test/cypress/e2e/api/SwaggerSchema.cy.js @@ -0,0 +1,21 @@ +/// + +const SWAGGER_SCHEMA_FILENAME = 'results/swagger-schema.json'; + +describe('Swagger Schema Linting', () => { + it('Should be a completely valid schema', () => { + // Save the schema to a file and lint it + cy.request('/api/schema') + .then((response) => { + const fileContent = response.body; + cy.writeFile(SWAGGER_SCHEMA_FILENAME, fileContent); + }) + .then(() => { + cy.exec(`yarn swagger-lint '${SWAGGER_SCHEMA_FILENAME}'`) + .then((result) => { + cy.log("Swagger Vacuum Results:\n", result.stdout); + expect(result.code).to.eq(0); + }); + }); + }); +}); diff --git a/test/package.json b/test/package.json index a3a3cad6d..d1ae44eb3 100644 --- a/test/package.json +++ b/test/package.json @@ -5,6 +5,7 @@ "main": "index.js", "dependencies": { "@jc21/cypress-swagger-validation": "^0.3.2", + "@quobix/vacuum": "^0.19.4", "axios": "^1.7.9", "cypress": "^14.0.1", "cypress-multi-reporters": "^2.0.5", @@ -20,7 +21,8 @@ }, "scripts": { "cypress": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress open --config-file=cypress/config/ci.js", - "cypress:headless": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress run --config-file=cypress/config/ci.js" + "cypress:headless": "HTTP_PROXY=127.0.0.1:8128 HTTPS_PROXY=127.0.0.1:8128 cypress run --config-file=cypress/config/ci.js", + "swagger-lint": "vacuum lint -b -q -d -a -n=warn" }, "author": "", "license": "ISC" diff --git a/test/vacuum-rules.yaml b/test/vacuum-rules.yaml new file mode 100644 index 000000000..fc129b727 --- /dev/null +++ b/test/vacuum-rules.yaml @@ -0,0 +1,971 @@ +description: Recommended rules for a high quality specification. +documentationUrl: https://quobix.com/vacuum/rulesets/recommended +rules: + component-description: + category: + description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions. + id: descriptions + name: Descriptions + description: Component description check + formats: + - oas3 + - oas3_1 + - oas3_2 + given: $ + howToFix: Components are the inputs and outputs of a specification. A user needs to be able to understand each component and what id does. Descriptions are critical to understanding components. Add a description! + id: component-description + recommended: true + resolved: true + severity: warn + then: + function: oasComponentDescriptions + type: validation + duplicate-paths: + category: + description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth. + id: operations + name: Operations + description: Paths cannot be duplicated; only the last definition will be kept. + formats: + - oas3 + - oas3_1 + - oas3_2 + given: $ + howToFix: Duplicate path definitions found in your OpenAPI specification. In YAML, duplicate keys are allowed, but only the last occurrence is used. This means earlier path definitions are silently ignored, which can lead to missing API endpoints in your specification. + id: duplicate-paths + recommended: true + severity: error + then: + function: duplicatePaths + type: validation + duplicated-entry-in-enum: + category: + description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checking required fields and validating correct use of structures. + id: schemas + name: Schemas + description: Enum values must not have duplicate entry + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: Enums need to be unique, you can't duplicate them in the same definition. Please remove the duplicate value. + id: duplicated-entry-in-enum + recommended: true + severity: error + then: + function: duplicatedEnum + type: validation + info-description: + category: + description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed. + id: information + name: Contract Information + description: Info section is missing a description + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: The 'info' section is missing a description, surely you want people to know what this spec is all about, right? + id: info-description + recommended: true + resolved: true + severity: error + then: + function: infoDescription + type: validation + info-license-spdx: + category: + description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed. + id: information + name: Contract Information + description: License section cannot contain both an identifier and a URL, they are mutually exclusive. + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: A license can contain either a URL or an SPDX identifier, but not both, They are mutually exclusive and cannot both be present. Choose one or the other + id: info-license-spdx + recommended: true + resolved: true + severity: error + then: + function: infoLicenseURLSPDX + type: validation + migrate-zally-ignore: + category: + description: Validation rules make sure that certain characters or patterns have not been used that may cause issues when rendering in different types of applications. + id: validation + name: Validation + description: x-zally-ignore keys should be migrated to x-lint-ignore for compatibility with vacuum + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: Migrate x-zally-ignore directives to vacuum's x-lint-ignore. Rename the key to x-lint-ignore and update the ignored rule id to the vacuum equivalent rule. + id: migrate-zally-ignore + recommended: true + resolved: true + severity: warn + then: + function: migrateZallyIgnore + type: validation + no-$ref-siblings: + category: + description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checking required fields and validating correct use of structures. + id: schemas + name: Schemas + description: $ref values cannot be placed next to other properties (like a description) + formats: + - oas2 + - oas3 + given: $ + howToFix: $ref values must not be placed next to sibling nodes, There should only be a single node when using $ref. A common mistake is adding 'description' next to a $ref. This is wrong. remove all siblings! + id: no-$ref-siblings + recommended: true + severity: error + then: + function: refSiblings + type: validation + no-ambiguous-paths: + category: + description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth. + id: operations + name: Operations + description: Paths need to resolve unambiguously from one another + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: Paths must all resolve unambiguously, they can't be confused with one another (/{id}/ambiguous and /ambiguous/{id} are the same thing. Make sure every path and the variables used are unique and do conflict with one another. Check the ordering of variables and the naming of path segments. + id: no-ambiguous-paths + recommended: true + resolved: true + severity: error + then: + function: noAmbiguousPaths + type: validation + no-eval-in-markdown: + category: + description: Validation rules make sure that certain characters or patterns have not been used that may cause issues when rendering in different types of applications. + id: validation + name: Validation + description: Markdown descriptions must not have `eval()` statements' + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: Remove all references to 'eval()' in the description. These can be used by malicious actors to embed code in contracts that is then executed when read by a browser. + id: no-eval-in-markdown + recommended: true + resolved: true + severity: error + then: + function: noEvalDescription + functionOptions: + pattern: eval\( + type: validation + no-http-verbs-in-path: + category: + description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth. + id: operations + name: Operations + description: Path segments must not contain an HTTP verb + formats: + - oas3 + - oas3_1 + - oas3_2 + - oas2 + given: $ + howToFix: When HTTP verbs (get/post/put etc) are used in path segments, it muddies the semantics of REST and creates a confusing and inconsistent experience. It's highly recommended that verbs are not used in path segments. Replace those HTTP verbs with more meaningful nouns. + id: no-http-verbs-in-path + recommended: true + severity: warn + then: + function: noVerbsInPath + type: style + no-request-body: + category: + description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth. + id: operations + name: Operations + description: HTTP GET and DELETE should not accept request bodies + formats: + - oas3 + - oas3_1 + - oas3_2 + given: $ + howToFix: Remove 'requestBody' from HTTP GET and DELETE methods + id: no-request-body + recommended: true + severity: warn + then: + function: noRequestBody + type: style + no-script-tags-in-markdown: + category: + description: Validation rules make sure that certain characters or patterns have not been used that may cause issues when rendering in different types of applications. + id: validation + name: Validation + description: Markdown descriptions must not have `