diff --git a/backend/schema/common.json b/backend/schema/common.json index 343f125e..00b06e00 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 cd0218d7..d80eb06d 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 4ed25e5c..307cac82 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 ef3553d9..793483c7 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 792c2f81..b876ebf0 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 c2540cf1..6f350a08 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 f6398094..592ead2c 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 b852a014..cae9d26c 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 e9dcacb5..464b188e 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 e7a495fd..58169720 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 82407be3..4ae57bd7 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 d4ba0a27..602073ce 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 eec02a86..7acd0a42 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 ecda9cef..62c09ce1 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 74f59723..38ff1c76 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 9ca1b8d3..9f6ba2a9 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 a8b9adc6..ada40f5b 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 073585c8..182a883a 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 e67023f8..9705826f 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 7f887dad..61e80440 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 4c5a4edd..38b7003a 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 0d40bcb8..a99f619d 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 4b858cae..7c18d019 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 bc289573..46afbf87 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 b2c1dcd6..4466d38d 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 f38b8102..2b1ba3e6 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 ec064627..3efb1a06 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 bd45e62a..5884c972 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 f2bb2fa2..15406c8b 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 f4f82e3f..4d738d01 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 21eb325e..9fa2bd12 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 8a11a3f6..feb04ff2 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 f3aa81a5..eed0ebc0 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 2cdcecf4..2a4d08ae 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 ca3ce9fa..512c2a0a 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 47e2f8b1..a3c24edc 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 f9505ed4..e07217c4 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 c8bbb693..1ec38720 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 1d9f6335..7f8cb148 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 991ef0e9..da67944d 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 54ff8a66..14c2689c 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 9f052de0..fe504b78 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 5e10a9cf..351451c4 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 5cab6e75..7ae60e1a 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 85455fb6..77d772e9 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 0b35e0fc..dfeb6049 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 7330f362..0b3232e8 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 8433220d..f44af11f 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 bef53436..07bf44dd 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 d780f874..577b5144 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 fd97cbfa..454a3880 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 5bfde2c3..6aa53301 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 17969ee4..6dda8e34 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 0ee6c6eb..0c986de8 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 3a968525..585cd82d 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 d1c1b1c8..61de8516 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 dc914f5f..d27ce526 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 801af13a..22fae887 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 14adb163..21ae71ef 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 a40ddc72..682a97b8 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 d435b004..c9e601ea 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 5d148d8a..a99f7f22 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 405b976d..929f3e5f 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 4ca62429..050ad441 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 ef842eaf..4e6ae244 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 99703ff0..f8a639ad 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 37415301..79c31ba8 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 c0213fe0..49025e32 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 a72f5617..3dba45b5 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 7d4f3615..767edfe8 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 cb8ac61b..2cf5587d 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 6148d182..46001d2e 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 2dcd2aed..764e7466 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 60a6cd13..eabaa3a0 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 7feb4ebc..e7234d4e 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 00000000..63578e21 --- /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 a3a3cad6..d1ae44eb 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 00000000..fc129b72 --- /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 `