diff --git a/.version b/.version index 22e3b6b01b..3cf561c0b6 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.11.3 +2.12.1 diff --git a/Jenkinsfile b/Jenkinsfile index 1d8680a6b1..9b29ee9708 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -56,6 +56,13 @@ pipeline { sh 'sed -i -E "s/(version-)[0-9]+\\.[0-9]+\\.[0-9]+(-green)/\\1${BUILD_VERSION}\\2/" README.md' } } + stage('Docker Login') { + steps { + withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) { + sh 'docker login -u "${duser}" -p "${dpass}"' + } + } + } } } stage('Builds') { @@ -120,6 +127,11 @@ pipeline { junit 'test/results/junit/*' sh 'docker-compose down --remove-orphans --volumes -t 30 || true' } + unstable { + dir(path: 'testing/results') { + archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml') + } + } } } stage('Test Mysql') { @@ -148,6 +160,11 @@ pipeline { junit 'test/results/junit/*' sh 'docker-compose down --remove-orphans --volumes -t 30 || true' } + unstable { + dir(path: 'testing/results') { + archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml') + } + } } } stage('MultiArch Build') { @@ -157,10 +174,7 @@ pipeline { } } steps { - withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) { - sh 'docker login -u "${duser}" -p "${dpass}"' - sh "./scripts/buildx --push ${buildxPushTags}" - } + sh "./scripts/buildx --push ${buildxPushTags}" } } stage('Docs / Comment') { @@ -200,20 +214,13 @@ pipeline { always { sh 'echo Reverting ownership' sh 'docker run --rm -v "$(pwd):/data" jc21/ci-tools chown -R "$(id -u):$(id -g)" /data' - } - success { - juxtapose event: 'success' - sh 'figlet "SUCCESS"' + printResult(true) } failure { archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true) - juxtapose event: 'failure' - sh 'figlet "FAILURE"' } unstable { archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true) - juxtapose event: 'unstable' - sh 'figlet "UNSTABLE"' } } } diff --git a/README.md b/README.md index 55a986d185..9ac6a6c857 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@



- + diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json deleted file mode 100644 index 4e540ab309..0000000000 --- a/backend/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "editor.insertSpaces": false, - "editor.formatOnSave": true, - "files.trimTrailingWhitespace": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true - } -} \ No newline at end of file diff --git a/backend/app.js b/backend/app.js index e528a0bbe1..59f7def205 100644 --- a/backend/app.js +++ b/backend/app.js @@ -52,7 +52,7 @@ app.use(function (req, res, next) { }); app.use(require('./lib/express/jwt')()); -app.use('/', require('./routes/api/main')); +app.use('/', require('./routes/main')); // production error handler // no stacktraces leaked to user diff --git a/backend/config/default.json b/backend/config/default.json index 64ab577c8c..154e66e489 100644 --- a/backend/config/default.json +++ b/backend/config/default.json @@ -1,6 +1,6 @@ { "database": { - "engine": "mysql", + "engine": "mysql2", "host": "db", "name": "npm", "user": "npm", diff --git a/backend/doc/api.swagger.json b/backend/doc/api.swagger.json deleted file mode 100644 index 3fa19fc4b3..0000000000 --- a/backend/doc/api.swagger.json +++ /dev/null @@ -1,1456 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "title": "Nginx Proxy Manager API", - "version": "2.x.x" - }, - "servers": [ - { - "url": "http://127.0.0.1:81/api" - } - ], - "paths": { - "/": { - "get": { - "operationId": "health", - "summary": "Returns the API health status", - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "status": "OK", - "version": { - "major": 2, - "minor": 1, - "revision": 0 - } - } - } - }, - "schema": { - "$ref": "#/components/schemas/HealthObject" - } - } - } - } - } - } - }, - "/nginx/proxy-hosts": { - "get": { - "operationId": "getProxyHosts", - "summary": "Get all proxy hosts", - "tags": ["Proxy Hosts"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "query", - "name": "expand", - "description": "Expansions", - "schema": { - "type": "string", - "enum": ["access_list", "owner", "certificate"] - } - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": [ - { - "id": 1, - "created_on": "2023-03-30T01:12:23.000Z", - "modified_on": "2023-03-30T02:15:40.000Z", - "owner_user_id": 1, - "domain_names": ["aasdasdad"], - "forward_host": "asdasd", - "forward_port": 80, - "access_list_id": 0, - "certificate_id": 0, - "ssl_forced": 0, - "caching_enabled": 0, - "block_exploits": 0, - "advanced_config": "sdfsdfsdf", - "meta": { - "letsencrypt_agree": false, - "dns_challenge": false, - "nginx_online": false, - "nginx_err": "Command failed: /usr/sbin/nginx -t -g \"error_log off;\"\nnginx: [emerg] unknown directive \"sdfsdfsdf\" in /data/nginx/proxy_host/1.conf:37\nnginx: configuration file /etc/nginx/nginx.conf test failed\n" - }, - "allow_websocket_upgrade": 0, - "http2_support": 0, - "forward_scheme": "http", - "enabled": 1, - "locations": [], - "hsts_enabled": 0, - "hsts_subdomains": 0, - "owner": { - "id": 1, - "created_on": "2023-03-30T01:11:50.000Z", - "modified_on": "2023-03-30T01:11:50.000Z", - "is_deleted": 0, - "is_disabled": 0, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "Admin", - "avatar": "", - "roles": ["admin"] - }, - "access_list": null, - "certificate": null - }, - { - "id": 2, - "created_on": "2023-03-30T02:11:49.000Z", - "modified_on": "2023-03-30T02:11:49.000Z", - "owner_user_id": 1, - "domain_names": ["test.example.com"], - "forward_host": "1.1.1.1", - "forward_port": 80, - "access_list_id": 0, - "certificate_id": 0, - "ssl_forced": 0, - "caching_enabled": 0, - "block_exploits": 0, - "advanced_config": "", - "meta": { - "letsencrypt_agree": false, - "dns_challenge": false, - "nginx_online": true, - "nginx_err": null - }, - "allow_websocket_upgrade": 0, - "http2_support": 0, - "forward_scheme": "http", - "enabled": 1, - "locations": [], - "hsts_enabled": 0, - "hsts_subdomains": 0, - "owner": { - "id": 1, - "created_on": "2023-03-30T01:11:50.000Z", - "modified_on": "2023-03-30T01:11:50.000Z", - "is_deleted": 0, - "is_disabled": 0, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "Admin", - "avatar": "", - "roles": ["admin"] - }, - "access_list": null, - "certificate": null - } - ] - } - }, - "schema": { - "$ref": "#/components/schemas/ProxyHostsList" - } - } - } - } - } - }, - "post": { - "operationId": "createProxyHost", - "summary": "Create a Proxy Host", - "tags": ["Proxy Hosts"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "body", - "name": "proxyhost", - "description": "Proxy Host Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/ProxyHostObject" - } - } - ], - "responses": { - "201": { - "description": "201 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": 3, - "created_on": "2023-03-30T02:31:27.000Z", - "modified_on": "2023-03-30T02:31:27.000Z", - "owner_user_id": 1, - "domain_names": ["test2.example.com"], - "forward_host": "1.1.1.1", - "forward_port": 80, - "access_list_id": 0, - "certificate_id": 0, - "ssl_forced": 0, - "caching_enabled": 0, - "block_exploits": 0, - "advanced_config": "", - "meta": { - "letsencrypt_agree": false, - "dns_challenge": false - }, - "allow_websocket_upgrade": 0, - "http2_support": 0, - "forward_scheme": "http", - "enabled": 1, - "locations": [], - "hsts_enabled": 0, - "hsts_subdomains": 0, - "certificate": null, - "owner": { - "id": 1, - "created_on": "2023-03-30T01:11:50.000Z", - "modified_on": "2023-03-30T01:11:50.000Z", - "is_deleted": 0, - "is_disabled": 0, - "email": "admin@example.com", - "name": "Administrator", - "nickname": "Admin", - "avatar": "", - "roles": ["admin"] - }, - "access_list": null, - "use_default_location": true, - "ipv6": true - } - } - }, - "schema": { - "$ref": "#/components/schemas/ProxyHostObject" - } - } - } - } - } - } - }, - "/schema": { - "get": { - "operationId": "schema", - "responses": { - "200": { - "description": "200 response" - } - }, - "summary": "Returns this swagger API schema" - } - }, - "/tokens": { - "get": { - "operationId": "refreshToken", - "summary": "Refresh your access token", - "tags": ["Tokens"], - "security": [ - { - "BearerAuth": ["tokens"] - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "expires": 1566540510, - "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" - } - } - }, - "schema": { - "$ref": "#/components/schemas/TokenObject" - } - } - } - } - } - }, - "post": { - "operationId": "requestToken", - "parameters": [ - { - "description": "Credentials Payload", - "in": "body", - "name": "credentials", - "required": true, - "schema": { - "additionalProperties": false, - "properties": { - "identity": { - "minLength": 1, - "type": "string" - }, - "scope": { - "minLength": 1, - "type": "string", - "enum": ["user"] - }, - "secret": { - "minLength": 1, - "type": "string" - } - }, - "required": ["identity", "secret"], - "type": "object" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "result": { - "expires": 1566540510, - "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" - } - } - } - }, - "schema": { - "$ref": "#/components/schemas/TokenObject" - } - } - }, - "description": "200 response" - } - }, - "summary": "Request a new access token from credentials", - "tags": ["Tokens"] - } - }, - "/settings": { - "get": { - "operationId": "getSettings", - "summary": "Get all settings", - "tags": ["Settings"], - "security": [ - { - "BearerAuth": ["settings"] - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": [ - { - "id": "default-site", - "name": "Default Site", - "description": "What to show when Nginx is hit with an unknown Host", - "value": "congratulations", - "meta": {} - } - ] - } - }, - "schema": { - "$ref": "#/components/schemas/SettingsList" - } - } - } - } - } - } - }, - "/settings/{settingID}": { - "get": { - "operationId": "getSetting", - "summary": "Get a setting", - "tags": ["Settings"], - "security": [ - { - "BearerAuth": ["settings"] - } - ], - "parameters": [ - { - "in": "path", - "name": "settingID", - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "description": "Setting ID", - "example": "default-site" - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": "default-site", - "name": "Default Site", - "description": "What to show when Nginx is hit with an unknown Host", - "value": "congratulations", - "meta": {} - } - } - }, - "schema": { - "$ref": "#/components/schemas/SettingObject" - } - } - } - } - } - }, - "put": { - "operationId": "updateSetting", - "summary": "Update a setting", - "tags": ["Settings"], - "security": [ - { - "BearerAuth": ["settings"] - } - ], - "parameters": [ - { - "in": "path", - "name": "settingID", - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "description": "Setting ID", - "example": "default-site" - }, - { - "in": "body", - "name": "setting", - "description": "Setting Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/SettingObject" - } - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": "default-site", - "name": "Default Site", - "description": "What to show when Nginx is hit with an unknown Host", - "value": "congratulations", - "meta": {} - } - } - }, - "schema": { - "$ref": "#/components/schemas/SettingObject" - } - } - } - } - } - } - }, - "/users": { - "get": { - "operationId": "getUsers", - "summary": "Get all users", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "query", - "name": "expand", - "description": "Expansions", - "schema": { - "type": "string", - "enum": ["permissions"] - } - } - ], - "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": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"] - } - ] - }, - "withPermissions": { - "value": [ - { - "id": 1, - "created_on": "2020-01-30T09:36:08.000Z", - "modified_on": "2020-01-30T09:41:04.000Z", - "is_disabled": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"], - "permissions": { - "visibility": "all", - "proxy_hosts": "manage", - "redirection_hosts": "manage", - "dead_hosts": "manage", - "streams": "manage", - "access_lists": "manage", - "certificates": "manage" - } - } - ] - } - }, - "schema": { - "$ref": "#/components/schemas/UsersList" - } - } - } - } - } - }, - "post": { - "operationId": "createUser", - "summary": "Create a User", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "body", - "name": "user", - "description": "User Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/UserObject" - } - } - ], - "responses": { - "201": { - "description": "201 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": 2, - "created_on": "2020-01-30T09:36:08.000Z", - "modified_on": "2020-01-30T09:41:04.000Z", - "is_disabled": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"], - "permissions": { - "visibility": "all", - "proxy_hosts": "manage", - "redirection_hosts": "manage", - "dead_hosts": "manage", - "streams": "manage", - "access_lists": "manage", - "certificates": "manage" - } - } - } - }, - "schema": { - "$ref": "#/components/schemas/UserObject" - } - } - } - } - } - } - }, - "/users/{userID}": { - "get": { - "operationId": "getUser", - "summary": "Get a user", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "oneOf": [ - { - "type": "string", - "pattern": "^me$" - }, - { - "type": "integer", - "minimum": 1 - } - ] - }, - "required": true, - "description": "User ID or 'me' for yourself", - "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": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"] - } - } - }, - "schema": { - "$ref": "#/components/schemas/UserObject" - } - } - } - } - } - }, - "put": { - "operationId": "updateUser", - "summary": "Update a User", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "oneOf": [ - { - "type": "string", - "pattern": "^me$" - }, - { - "type": "integer", - "minimum": 1 - } - ] - }, - "required": true, - "description": "User ID or 'me' for yourself", - "example": 2 - }, - { - "in": "body", - "name": "user", - "description": "User Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/UserObject" - } - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "id": 2, - "created_on": "2020-01-30T09:36:08.000Z", - "modified_on": "2020-01-30T09:41:04.000Z", - "is_disabled": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": ["admin"] - } - } - }, - "schema": { - "$ref": "#/components/schemas/UserObject" - } - } - } - } - } - }, - "delete": { - "operationId": "deleteUser", - "summary": "Delete a User", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "description": "User ID", - "example": 2 - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": true - } - }, - "schema": { - "type": "boolean" - } - } - } - } - } - } - }, - "/users/{userID}/auth": { - "put": { - "operationId": "updateUserAuth", - "summary": "Update a User's Authentication", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "oneOf": [ - { - "type": "string", - "pattern": "^me$" - }, - { - "type": "integer", - "minimum": 1 - } - ] - }, - "required": true, - "description": "User ID or 'me' for yourself", - "example": 2 - }, - { - "in": "body", - "name": "user", - "description": "User Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/AuthObject" - } - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": true - } - }, - "schema": { - "type": "boolean" - } - } - } - } - } - } - }, - "/users/{userID}/permissions": { - "put": { - "operationId": "updateUserPermissions", - "summary": "Update a User's Permissions", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "description": "User ID", - "example": 2 - }, - { - "in": "body", - "name": "user", - "description": "Permissions Payload", - "required": true, - "schema": { - "$ref": "#/components/schemas/PermissionsObject" - } - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": true - } - }, - "schema": { - "type": "boolean" - } - } - } - } - } - } - }, - "/users/{userID}/login": { - "put": { - "operationId": "loginAsUser", - "summary": "Login as this user", - "tags": ["Users"], - "security": [ - { - "BearerAuth": ["users"] - } - ], - "parameters": [ - { - "in": "path", - "name": "userID", - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "description": "User ID", - "example": 2 - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "token": "eyJhbGciOiJSUzI1NiIsInR...16OjT8B3NLyXg", - "expires": "2020-01-31T10:56:23.239Z", - "user": { - "id": 1, - "created_on": "2020-01-30T10:43:44.000Z", - "modified_on": "2020-01-30T10:43:44.000Z", - "is_disabled": 0, - "email": "jc@jc21.com", - "name": "Jamie Curnow", - "nickname": "James", - "avatar": "//www.gravatar.com/avatar/3c8d73f45fd8763f827b964c76e6032a?default=mm", - "roles": ["admin"] - } - } - } - }, - "schema": { - "type": "object", - "description": "Login object", - "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" - }, - "user": { - "$ref": "#/components/schemas/UserObject" - } - } - } - } - } - } - } - } - }, - "/reports/hosts": { - "get": { - "operationId": "reportsHosts", - "summary": "Report on Host Statistics", - "tags": ["Reports"], - "security": [ - { - "BearerAuth": ["reports"] - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "proxy": 20, - "redirection": 1, - "stream": 0, - "dead": 1 - } - } - }, - "schema": { - "$ref": "#/components/schemas/HostReportObject" - } - } - } - } - } - } - }, - "/audit-log": { - "get": { - "operationId": "getAuditLog", - "summary": "Get Audit Log", - "tags": ["Audit Log"], - "security": [ - { - "BearerAuth": ["audit-log"] - } - ], - "responses": { - "200": { - "description": "200 response", - "content": { - "application/json": { - "examples": { - "default": { - "value": { - "proxy": 20, - "redirection": 1, - "stream": 0, - "dead": 1 - } - } - }, - "schema": { - "$ref": "#/components/schemas/HostReportObject" - } - } - } - } - } - } - } - }, - "components": { - "securitySchemes": { - "BearerAuth": { - "type": "http", - "scheme": "bearer" - } - }, - "schemas": { - "HealthObject": { - "type": "object", - "description": "Health object", - "additionalProperties": false, - "required": ["status", "version"], - "properties": { - "status": { - "type": "string", - "description": "Healthy", - "example": "OK" - }, - "version": { - "type": "object", - "description": "The version object", - "example": { - "major": 2, - "minor": 0, - "revision": 0 - }, - "additionalProperties": false, - "required": ["major", "minor", "revision"], - "properties": { - "major": { - "type": "integer", - "minimum": 0 - }, - "minor": { - "type": "integer", - "minimum": 0 - }, - "revision": { - "type": "integer", - "minimum": 0 - } - } - } - } - }, - "TokenObject": { - "type": "object", - "description": "Token object", - "required": ["expires", "token"], - "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" - } - } - }, - "ProxyHostObject": { - "type": "object", - "description": "Proxy Host object", - "required": [ - "id", - "created_on", - "modified_on", - "owner_user_id", - "domain_names", - "forward_host", - "forward_port", - "access_list_id", - "certificate_id", - "ssl_forced", - "caching_enabled", - "block_exploits", - "advanced_config", - "meta", - "allow_websocket_upgrade", - "http2_support", - "forward_scheme", - "enabled", - "locations", - "hsts_enabled", - "hsts_subdomains", - "certificate", - "use_default_location", - "ipv6" - ], - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "description": "Proxy Host ID", - "minimum": 1, - "example": 1 - }, - "created_on": { - "type": "string", - "description": "Created Date", - "example": "2020-01-30T09:36:08.000Z" - }, - "modified_on": { - "type": "string", - "description": "Modified Date", - "example": "2020-01-30T09:41:04.000Z" - }, - "owner_user_id": { - "type": "integer", - "minimum": 1, - "example": 1 - }, - "domain_names": { - "type": "array", - "minItems": 1, - "items": { - "type": "string", - "minLength": 1 - } - }, - "forward_host": { - "type": "string", - "minLength": 1 - }, - "forward_port": { - "type": "integer", - "minimum": 1 - }, - "access_list_id": { - "type": "integer" - }, - "certificate_id": { - "type": "integer" - }, - "ssl_forced": { - "type": "integer" - }, - "caching_enabled": { - "type": "integer" - }, - "block_exploits": { - "type": "integer" - }, - "advanced_config": { - "type": "string" - }, - "meta": { - "type": "object" - }, - "allow_websocket_upgrade": { - "type": "integer" - }, - "http2_support": { - "type": "integer" - }, - "forward_scheme": { - "type": "string" - }, - "enabled": { - "type": "integer" - }, - "locations": { - "type": "array" - }, - "hsts_enabled": { - "type": "integer" - }, - "hsts_subdomains": { - "type": "integer" - }, - "certificate": { - "type": "object", - "nullable": true - }, - "owner": { - "type": "object", - "nullable": true - }, - "access_list": { - "type": "object", - "nullable": true - }, - "use_default_location": { - "type": "boolean" - }, - "ipv6": { - "type": "boolean" - } - } - }, - "ProxyHostsList": { - "type": "array", - "description": "Proxyn Hosts list", - "items": { - "$ref": "#/components/schemas/ProxyHostObject" - } - }, - "SettingObject": { - "type": "object", - "description": "Setting object", - "required": ["id", "name", "description", "value", "meta"], - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "description": "Setting ID", - "minLength": 1, - "example": "default-site" - }, - "name": { - "type": "string", - "description": "Setting Display Name", - "minLength": 1, - "example": "Default Site" - }, - "description": { - "type": "string", - "description": "Meaningful description", - "minLength": 1, - "example": "What to show when Nginx is hit with an unknown Host" - }, - "value": { - "description": "Value in almost any form", - "example": "congratulations", - "oneOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "type": "integer" - }, - { - "type": "object" - }, - { - "type": "number" - }, - { - "type": "array" - } - ] - }, - "meta": { - "description": "Extra metadata", - "example": {}, - "type": "object" - } - } - }, - "SettingsList": { - "type": "array", - "description": "Setting list", - "items": { - "$ref": "#/components/schemas/SettingObject" - } - }, - "UserObject": { - "type": "object", - "description": "User object", - "required": ["id", "created_on", "modified_on", "is_disabled", "email", "name", "nickname", "avatar", "roles"], - "additionalProperties": false, - "properties": { - "id": { - "type": "integer", - "description": "User ID", - "minimum": 1, - "example": 1 - }, - "created_on": { - "type": "string", - "description": "Created Date", - "example": "2020-01-30T09:36:08.000Z" - }, - "modified_on": { - "type": "string", - "description": "Modified Date", - "example": "2020-01-30T09:41:04.000Z" - }, - "is_disabled": { - "type": "integer", - "minimum": 0, - "maximum": 1, - "description": "Is user Disabled (0 = false, 1 = true)", - "example": 0 - }, - "email": { - "type": "string", - "description": "Email", - "minLength": 3, - "example": "jc@jc21.com" - }, - "name": { - "type": "string", - "description": "Name", - "minLength": 1, - "example": "Jamie Curnow" - }, - "nickname": { - "type": "string", - "description": "Nickname", - "example": "James" - }, - "avatar": { - "type": "string", - "description": "Gravatar URL based on email, without scheme", - "example": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm" - }, - "roles": { - "description": "Roles applied", - "example": ["admin"], - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "UsersList": { - "type": "array", - "description": "User list", - "items": { - "$ref": "#/components/schemas/UserObject" - } - }, - "AuthObject": { - "type": "object", - "description": "Authentication Object", - "required": ["type", "secret"], - "properties": { - "type": { - "type": "string", - "pattern": "^password$", - "example": "password" - }, - "current": { - "type": "string", - "minLength": 1, - "maxLength": 64, - "example": "changeme" - }, - "secret": { - "type": "string", - "minLength": 8, - "maxLength": 64, - "example": "mySuperN3wP@ssword!" - } - } - }, - "PermissionsObject": { - "type": "object", - "properties": { - "visibility": { - "type": "string", - "description": "Visibility Type", - "enum": ["all", "user"] - }, - "access_lists": { - "type": "string", - "description": "Access Lists Permissions", - "enum": ["hidden", "view", "manage"] - }, - "dead_hosts": { - "type": "string", - "description": "404 Hosts Permissions", - "enum": ["hidden", "view", "manage"] - }, - "proxy_hosts": { - "type": "string", - "description": "Proxy Hosts Permissions", - "enum": ["hidden", "view", "manage"] - }, - "redirection_hosts": { - "type": "string", - "description": "Redirection Permissions", - "enum": ["hidden", "view", "manage"] - }, - "streams": { - "type": "string", - "description": "Streams Permissions", - "enum": ["hidden", "view", "manage"] - }, - "certificates": { - "type": "string", - "description": "Certificates Permissions", - "enum": ["hidden", "view", "manage"] - } - } - }, - "HostReportObject": { - "type": "object", - "properties": { - "proxy": { - "type": "integer", - "description": "Proxy Hosts Count" - }, - "redirection": { - "type": "integer", - "description": "Redirection Hosts Count" - }, - "stream": { - "type": "integer", - "description": "Streams Count" - }, - "dead": { - "type": "integer", - "description": "404 Hosts Count" - } - } - } - } - } -} diff --git a/backend/index.js b/backend/index.js index 3d6d60071b..5513782519 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,23 +1,20 @@ #!/usr/bin/env node +const schema = require('./schema'); const logger = require('./logger').global; async function appStart () { const migrate = require('./migrate'); const setup = require('./setup'); const app = require('./app'); - const apiValidator = require('./lib/validator/api'); const internalCertificate = require('./internal/certificate'); const internalIpRanges = require('./internal/ip_ranges'); return migrate.latest() .then(setup) - .then(() => { - return apiValidator.loadSchemas; - }) + .then(schema.getCompiledSchema) .then(internalIpRanges.fetch) .then(() => { - internalCertificate.initTimer(); internalIpRanges.initTimer(); @@ -34,7 +31,7 @@ async function appStart () { }); }) .catch((err) => { - logger.error(err.message); + logger.error(err.message, err); setTimeout(appStart, 1000); }); } diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index 017fc738c2..72326be68d 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -269,7 +269,7 @@ const internalAccessList = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } if (!skip_masking && typeof row.items !== 'undefined' && row.items) { @@ -296,7 +296,7 @@ const internalAccessList = { return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items', 'clients']}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 291056caa6..34b8fdf5a7 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -3,27 +3,29 @@ const fs = require('fs'); const https = require('https'); const tempWrite = require('temp-write'); const moment = require('moment'); +const archiver = require('archiver'); +const path = require('path'); +const { isArray } = require('lodash'); const logger = require('../logger').ssl; const config = require('../lib/config'); const error = require('../lib/error'); const utils = require('../lib/utils'); +const certbot = require('../lib/certbot'); const certificateModel = require('../models/certificate'); const tokenModel = require('../models/token'); const dnsPlugins = require('../global/certbot-dns-plugins.json'); const internalAuditLog = require('./audit-log'); const internalNginx = require('./nginx'); const internalHost = require('./host'); -const certbot = require('../lib/certbot'); -const archiver = require('archiver'); -const path = require('path'); -const { isArray } = require('lodash'); + const letsencryptStaging = config.useLetsencryptStaging(); +const letsencryptServer = config.useLetsencryptServer(); const letsencryptConfig = '/etc/letsencrypt.ini'; const certbotCommand = 'certbot'; function omissions() { - return ['is_deleted']; + return ['is_deleted', 'owner.is_deleted']; } const internalCertificate = { @@ -207,6 +209,7 @@ const internalCertificate = { .patchAndFetchById(certificate.id, { expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss') }) + .then(utils.omitRow(omissions())) .then((saved_row) => { // Add cert data for audit log saved_row.meta = _.assign({}, saved_row.meta, { @@ -323,7 +326,7 @@ const internalCertificate = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } // Custom omissions @@ -412,7 +415,7 @@ const internalCertificate = { return internalCertificate.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -730,29 +733,29 @@ const internalCertificate = { return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout') .then((result) => { + // Examples: + // subject=CN = *.jc21.com // subject=CN = something.example.com const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim; const match = regex.exec(result); - - if (typeof match[1] === 'undefined') { - throw new error.ValidationError('Could not determine subject from certificate: ' + result); + if (match && typeof match[1] !== 'undefined') { + certData['cn'] = match[1]; } - - certData['cn'] = match[1]; }) .then(() => { return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout'); }) + .then((result) => { + // Examples: // issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 + // issuer=C = US, O = Let's Encrypt, CN = E5 + // issuer=O = NginxProxyManager, CN = NginxProxyManager Intermediate CA","O = NginxProxyManager, CN = NginxProxyManager Intermediate CA const regex = /^(?:issuer=)?(.*)$/gim; const match = regex.exec(result); - - if (typeof match[1] === 'undefined') { - throw new error.ValidationError('Could not determine issuer from certificate: ' + result); + if (match && typeof match[1] !== 'undefined') { + certData['issuer'] = match[1]; } - - certData['issuer'] = match[1]; }) .then(() => { return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout'); @@ -827,17 +830,18 @@ const internalCertificate = { requestLetsEncryptSsl: (certificate) => { logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); - const cmd = certbotCommand + ' certonly ' + - '--config "' + letsencryptConfig + '" ' + + const cmd = `${certbotCommand} certonly ` + + `--config '${letsencryptConfig}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + - '--cert-name "npm-' + certificate.id + '" ' + + `--cert-name "npm-${certificate.id}" ` + '--agree-tos ' + '--authenticator webroot ' + - '--email "' + certificate.meta.letsencrypt_email + '" ' + + `--email '${certificate.meta.letsencrypt_email}' ` + '--preferred-challenges "dns,http" ' + - '--domains "' + certificate.domain_names.join(',') + '" ' + - (letsencryptStaging ? '--staging' : ''); + `--domains "${certificate.domain_names.join(',')}" ` + + (letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') + + (letsencryptStaging && letsencryptServer === null ? '--staging ' : ''); logger.info('Command:', cmd); @@ -868,25 +872,26 @@ const internalCertificate = { const hasConfigArg = certificate.meta.dns_provider !== 'route53'; let mainCmd = certbotCommand + ' certonly ' + - '--config "' + letsencryptConfig + '" ' + + `--config '${letsencryptConfig}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + - '--cert-name "npm-' + certificate.id + '" ' + + `--cert-name 'npm-${certificate.id}' ` + '--agree-tos ' + - '--email "' + certificate.meta.letsencrypt_email + '" ' + - '--domains "' + certificate.domain_names.join(',') + '" ' + - '--authenticator ' + dnsPlugin.full_plugin_name + ' ' + + `--email '${certificate.meta.letsencrypt_email}' ` + + `--domains '${certificate.domain_names.join(',')}' ` + + `--authenticator '${dnsPlugin.full_plugin_name}' ` + ( hasConfigArg - ? '--' + dnsPlugin.full_plugin_name + '-credentials "' + credentialsLocation + '"' + ? `--${dnsPlugin.full_plugin_name}-credentials '${credentialsLocation}' ` : '' ) + ( certificate.meta.propagation_seconds !== undefined - ? ' --' + dnsPlugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds + ? `--${dnsPlugin.full_plugin_name}-propagation-seconds '${certificate.meta.propagation_seconds}' ` : '' ) + - (letsencryptStaging ? ' --staging' : ''); + (letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') + + (letsencryptStaging && letsencryptServer === null ? '--staging ' : ''); // Prepend the path to the credentials file as an environment variable if (certificate.meta.dns_provider === 'route53') { @@ -963,14 +968,15 @@ const internalCertificate = { logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); const cmd = certbotCommand + ' renew --force-renewal ' + - '--config "' + letsencryptConfig + '" ' + + `--config '${letsencryptConfig}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + - '--cert-name "npm-' + certificate.id + '" ' + + `--cert-name 'npm-${certificate.id}' ` + '--preferred-challenges "dns,http" ' + '--no-random-sleep-on-renew ' + '--disable-hook-validation ' + - (letsencryptStaging ? '--staging' : ''); + (letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') + + (letsencryptStaging && letsencryptServer === null ? '--staging ' : ''); logger.info('Command:', cmd); @@ -995,13 +1001,14 @@ const internalCertificate = { logger.info(`Renewing Let'sEncrypt certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); let mainCmd = certbotCommand + ' renew --force-renewal ' + - '--config "' + letsencryptConfig + '" ' + + `--config "${letsencryptConfig}" ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + - '--cert-name "npm-' + certificate.id + '" ' + + `--cert-name 'npm-${certificate.id}' ` + '--disable-hook-validation ' + '--no-random-sleep-on-renew ' + - (letsencryptStaging ? ' --staging' : ''); + (letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') + + (letsencryptStaging && letsencryptServer === null ? '--staging ' : ''); // Prepend the path to the credentials file as an environment variable if (certificate.meta.dns_provider === 'route53') { @@ -1027,12 +1034,13 @@ const internalCertificate = { logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); const mainCmd = certbotCommand + ' revoke ' + - '--config "' + letsencryptConfig + '" ' + + `--config '${letsencryptConfig}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + - '--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + + `--cert-path '/etc/letsencrypt/live/npm-${certificate.id}/fullchain.pem' ` + '--delete-after-revoke ' + - (letsencryptStaging ? '--staging' : ''); + (letsencryptServer !== null ? `--server '${letsencryptServer}' ` : '') + + (letsencryptStaging && letsencryptServer === null ? '--staging ' : ''); // Don't fail command if file does not exist const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`; diff --git a/backend/internal/dead-host.js b/backend/internal/dead-host.js index 2a6258e96f..e672775eb0 100644 --- a/backend/internal/dead-host.js +++ b/backend/internal/dead-host.js @@ -48,6 +48,12 @@ const internalDeadHost = { data.owner_user_id = access.token.getUserId(1); data = internalHost.cleanSslHstsData(data); + // Fix for db field not having a default value + // for this optional field. + if (typeof data.advanced_config === 'undefined') { + data.advanced_config = ''; + } + return deadHostModel .query() .insertAndFetch(data) @@ -233,7 +239,7 @@ const internalDeadHost = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } // Custom omissions @@ -257,7 +263,7 @@ const internalDeadHost = { return internalDeadHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -305,7 +311,7 @@ const internalDeadHost = { }); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (row.enabled) { throw new error.ValidationError('Host is already enabled'); @@ -351,7 +357,7 @@ const internalDeadHost = { return internalDeadHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (!row.enabled) { throw new error.ValidationError('Host is already disabled'); diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 77933e733b..5f802c0048 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -181,7 +181,9 @@ const internalNginx = { * @param {Object} host * @returns {Promise} */ - generateConfig: (host_type, host) => { + generateConfig: (host_type, host_row) => { + // Prevent modifying the original object: + let host = JSON.parse(JSON.stringify(host_row)); const nice_host_type = internalNginx.getFileFriendlyHostType(host_type); if (config.debug()) { diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index dbff1147d0..61ac8b8c7a 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -8,7 +8,7 @@ const internalAuditLog = require('./audit-log'); const internalCertificate = require('./certificate'); function omissions () { - return ['is_deleted']; + return ['is_deleted', 'owner.is_deleted']; } const internalProxyHost = { @@ -48,6 +48,12 @@ const internalProxyHost = { data.owner_user_id = access.token.getUserId(1); data = internalHost.cleanSslHstsData(data); + // Fix for db field not having a default value + // for this optional field. + if (typeof data.advanced_config === 'undefined') { + data.advanced_config = ''; + } + return proxyHostModel .query() .insertAndFetch(data) @@ -239,7 +245,7 @@ const internalProxyHost = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } row = internalHost.cleanRowCertificateMeta(row); @@ -264,7 +270,7 @@ const internalProxyHost = { return internalProxyHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -312,7 +318,7 @@ const internalProxyHost = { }); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (row.enabled) { throw new error.ValidationError('Host is already enabled'); @@ -358,7 +364,7 @@ const internalProxyHost = { return internalProxyHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (!row.enabled) { throw new error.ValidationError('Host is already disabled'); diff --git a/backend/internal/redirection-host.js b/backend/internal/redirection-host.js index 775d94f3a4..41ff5b0937 100644 --- a/backend/internal/redirection-host.js +++ b/backend/internal/redirection-host.js @@ -48,6 +48,12 @@ const internalRedirectionHost = { data.owner_user_id = access.token.getUserId(1); data = internalHost.cleanSslHstsData(data); + // Fix for db field not having a default value + // for this optional field. + if (typeof data.advanced_config === 'undefined') { + data.advanced_config = ''; + } + return redirectionHostModel .query() .insertAndFetch(data) @@ -232,7 +238,7 @@ const internalRedirectionHost = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } row = internalHost.cleanRowCertificateMeta(row); @@ -257,7 +263,7 @@ const internalRedirectionHost = { return internalRedirectionHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -305,7 +311,7 @@ const internalRedirectionHost = { }); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (row.enabled) { throw new error.ValidationError('Host is already enabled'); @@ -351,7 +357,7 @@ const internalRedirectionHost = { return internalRedirectionHost.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (!row.enabled) { throw new error.ValidationError('Host is already disabled'); diff --git a/backend/internal/stream.js b/backend/internal/stream.js index 6c9ab24df7..8dcb0507eb 100644 --- a/backend/internal/stream.js +++ b/backend/internal/stream.js @@ -197,7 +197,7 @@ const internalStream = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } row = internalHost.cleanRowCertificateMeta(row); @@ -222,7 +222,7 @@ const internalStream = { return internalStream.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -270,7 +270,7 @@ const internalStream = { }); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (row.enabled) { throw new error.ValidationError('Stream is already enabled'); @@ -316,7 +316,7 @@ const internalStream = { return internalStream.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } else if (!row.enabled) { throw new error.ValidationError('Stream is already disabled'); diff --git a/backend/internal/user.js b/backend/internal/user.js index a1d90447fe..742ab65d33 100644 --- a/backend/internal/user.js +++ b/backend/internal/user.js @@ -194,7 +194,7 @@ const internalUser = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } // Custom omissions diff --git a/backend/knexfile.js b/backend/knexfile.js index 391ca00508..607552f6fc 100644 --- a/backend/knexfile.js +++ b/backend/knexfile.js @@ -1,6 +1,6 @@ module.exports = { development: { - client: 'mysql', + client: 'mysql2', migrations: { tableName: 'migrations', stub: 'lib/migrate_template.js', @@ -9,7 +9,7 @@ module.exports = { }, production: { - client: 'mysql', + client: 'mysql2', migrations: { tableName: 'migrations', stub: 'lib/migrate_template.js', diff --git a/backend/lib/access.js b/backend/lib/access.js index 5b9ebc93c4..0e658a6561 100644 --- a/backend/lib/access.js +++ b/backend/lib/access.js @@ -10,7 +10,7 @@ const _ = require('lodash'); const logger = require('../logger').access; -const validator = require('ajv'); +const Ajv = require('ajv/dist/2020'); const error = require('./error'); const userModel = require('../models/user'); const proxyHostModel = require('../models/proxy_host'); @@ -174,7 +174,6 @@ module.exports = function (token_string) { let schema = { $id: 'objects', - $schema: 'http://json-schema.org/draft-07/schema#', description: 'Actor Properties', type: 'object', additionalProperties: false, @@ -251,7 +250,7 @@ module.exports = function (token_string) { // Initialised, token decoded ok return this.getObjectSchema(permission) .then((objectSchema) => { - let data_schema = { + const data_schema = { [permission]: { data: data, scope: Token.get('scope'), @@ -267,24 +266,18 @@ module.exports = function (token_string) { }; let permissionSchema = { - $schema: 'http://json-schema.org/draft-07/schema#', $async: true, $id: 'permissions', + type: 'object', additionalProperties: false, properties: {} }; permissionSchema.properties[permission] = require('./access/' + permission.replace(/:/gim, '-') + '.json'); - // logger.info('objectSchema', JSON.stringify(objectSchema, null, 2)); - // logger.info('permissionSchema', JSON.stringify(permissionSchema, null, 2)); - // logger.info('data_schema', JSON.stringify(data_schema, null, 2)); - - let ajv = validator({ + const ajv = new Ajv({ verbose: true, allErrors: true, - format: 'full', - missingRefs: 'fail', breakOnError: true, coerceTypes: true, schemas: [ diff --git a/backend/lib/access/permissions.json b/backend/lib/access/permissions.json index 8480f9a1c8..e7a82ece3b 100644 --- a/backend/lib/access/permissions.json +++ b/backend/lib/access/permissions.json @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", "$id": "perms", "definitions": { "view": { diff --git a/backend/lib/access/roles.json b/backend/lib/access/roles.json index 16b33b55bb..c97313da81 100644 --- a/backend/lib/access/roles.json +++ b/backend/lib/access/roles.json @@ -1,5 +1,4 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", "$id": "roles", "definitions": { "admin": { diff --git a/backend/lib/config.js b/backend/lib/config.js index a484fc5b2a..f7fbdca6fd 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -34,7 +34,7 @@ const configure = () => { logger.info('Using MySQL configuration'); instance = { database: { - engine: 'mysql', + engine: 'mysql2', host: envMysqlHost, port: process.env.DB_MYSQL_PORT || 3306, user: envMysqlUser, @@ -180,5 +180,15 @@ module.exports = { */ useLetsencryptStaging: function () { return !!process.env.LE_STAGING; + }, + + /** + * @returns {string|null} + */ + useLetsencryptServer: function () { + if (process.env.LE_SERVER) { + return process.env.LE_SERVER; + } + return null; } }; diff --git a/backend/lib/express/cors.js b/backend/lib/express/cors.js index c9befeec86..6d5b8b5fba 100644 --- a/backend/lib/express/cors.js +++ b/backend/lib/express/cors.js @@ -1,40 +1,16 @@ -const validator = require('../validator'); - module.exports = function (req, res, next) { - if (req.headers.origin) { - - const originSchema = { - oneOf: [ - { - type: 'string', - pattern: '^[a-z\\-]+:\\/\\/(?:[\\w\\-\\.]+(:[0-9]+)?/?)?$' - }, - { - type: 'string', - pattern: '^[a-z\\-]+:\\/\\/(?:\\[([a-z0-9]{0,4}\\:?)+\\])?/?(:[0-9]+)?$' - } - ] - }; - - // very relaxed validation.... - validator(originSchema, req.headers.origin) - .then(function () { - res.set({ - 'Access-Control-Allow-Origin': req.headers.origin, - 'Access-Control-Allow-Credentials': true, - 'Access-Control-Allow-Methods': 'OPTIONS, GET, POST', - 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control, Pragma, Expires, Authorization, X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit', - 'Access-Control-Max-Age': 5 * 60, - 'Access-Control-Expose-Headers': 'X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit' - }); - next(); - }) - .catch(next); - + res.set({ + 'Access-Control-Allow-Origin': req.headers.origin, + 'Access-Control-Allow-Credentials': true, + 'Access-Control-Allow-Methods': 'OPTIONS, GET, POST', + 'Access-Control-Allow-Headers': 'Content-Type, Cache-Control, Pragma, Expires, Authorization, X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit', + 'Access-Control-Max-Age': 5 * 60, + 'Access-Control-Expose-Headers': 'X-Dataset-Total, X-Dataset-Offset, X-Dataset-Limit' + }); + next(); } else { // No origin next(); } - }; diff --git a/backend/lib/helpers.js b/backend/lib/helpers.js index e38be991e4..f7e98bebcc 100644 --- a/backend/lib/helpers.js +++ b/backend/lib/helpers.js @@ -27,6 +27,24 @@ module.exports = { } return null; + }, + + convertIntFieldsToBool: function (obj, fields) { + fields.forEach(function (field) { + if (typeof obj[field] !== 'undefined') { + obj[field] = obj[field] === 1; + } + }); + return obj; + }, + + convertBoolFieldsToInt: function (obj, fields) { + fields.forEach(function (field) { + if (typeof obj[field] !== 'undefined') { + obj[field] = obj[field] ? 1 : 0; + } + }); + return obj; } }; diff --git a/backend/lib/validator/api.js b/backend/lib/validator/api.js index 3f51b59699..fb31e64c6f 100644 --- a/backend/lib/validator/api.js +++ b/backend/lib/validator/api.js @@ -1,13 +1,12 @@ -const error = require('../error'); -const path = require('path'); -const parser = require('json-schema-ref-parser'); +const Ajv = require('ajv/dist/2020'); +const error = require('../error'); -const ajv = require('ajv')({ - verbose: true, - validateSchema: true, - allErrors: false, - format: 'full', - coerceTypes: true +const ajv = new Ajv({ + verbose: true, + allErrors: true, + allowUnionTypes: true, + strict: false, + coerceTypes: true, }); /** @@ -17,12 +16,18 @@ const ajv = require('ajv')({ */ function apiValidator (schema, payload/*, description*/) { return new Promise(function Promise_apiValidator (resolve, reject) { + if (schema === null) { + reject(new error.ValidationError('Schema is undefined')); + return; + } + if (typeof payload === 'undefined') { reject(new error.ValidationError('Payload is undefined')); + return; } - let validate = ajv.compile(schema); - let valid = validate(payload); + const validate = ajv.compile(schema); + const valid = validate(payload); if (valid && !validate.errors) { resolve(payload); @@ -35,11 +40,4 @@ function apiValidator (schema, payload/*, description*/) { }); } -apiValidator.loadSchemas = parser - .dereference(path.resolve('schema/index.json')) - .then((schema) => { - ajv.addSchema(schema); - return schema; - }); - module.exports = apiValidator; diff --git a/backend/lib/validator/index.js b/backend/lib/validator/index.js index d09c9be5f1..c6d240967e 100644 --- a/backend/lib/validator/index.js +++ b/backend/lib/validator/index.js @@ -1,17 +1,17 @@ -const _ = require('lodash'); -const error = require('../error'); -const definitions = require('../../schema/definitions.json'); +const _ = require('lodash'); +const Ajv = require('ajv/dist/2020'); +const error = require('../error'); +const commonDefinitions = require('../../schema/common.json'); RegExp.prototype.toJSON = RegExp.prototype.toString; -const ajv = require('ajv')({ - verbose: true, - allErrors: true, - format: 'full', // strict regexes for format checks - coerceTypes: true, - schemas: [ - definitions - ] +const ajv = new Ajv({ + verbose: true, + allErrors: true, + allowUnionTypes: true, + coerceTypes: true, + strict: false, + schemas: [commonDefinitions] }); /** @@ -27,23 +27,19 @@ function validator (schema, payload) { } else { try { let validate = ajv.compile(schema); + let valid = validate(payload); - let valid = validate(payload); if (valid && !validate.errors) { resolve(_.cloneDeep(payload)); } else { let message = ajv.errorsText(validate.errors); reject(new error.InternalValidationError(message)); } - } catch (err) { reject(err); } - } - }); - } module.exports = validator; diff --git a/backend/models/access_list.js b/backend/models/access_list.js index fbf9bda770..959df05f3d 100644 --- a/backend/models/access_list.js +++ b/backend/models/access_list.js @@ -2,6 +2,7 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const User = require('./user'); const AccessListAuth = require('./access_list_auth'); @@ -10,6 +11,12 @@ const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'satisfy_any', + 'pass_auth', +]; + class AccessList extends Model { $beforeInsert () { this.created_on = now(); @@ -25,6 +32,16 @@ class AccessList extends Model { this.modified_on = now(); } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'AccessList'; } diff --git a/backend/models/auth.js b/backend/models/auth.js index 2ee4319755..469e96bf4f 100644 --- a/backend/models/auth.js +++ b/backend/models/auth.js @@ -1,14 +1,19 @@ // Objection Docs: // http://vincit.github.io/objection.js/ -const bcrypt = require('bcrypt'); -const db = require('../db'); -const Model = require('objection').Model; -const User = require('./user'); -const now = require('./now_helper'); +const bcrypt = require('bcrypt'); +const db = require('../db'); +const helpers = require('../lib/helpers'); +const Model = require('objection').Model; +const User = require('./user'); +const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', +]; + function encryptPassword () { /* jshint -W040 */ let _this = this; @@ -41,6 +46,16 @@ class Auth extends Model { return encryptPassword.apply(this, queryContext); } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + /** * Verify a plain password against the encrypted password * diff --git a/backend/models/certificate.js b/backend/models/certificate.js index 4f0f2ef648..534d927cbb 100644 --- a/backend/models/certificate.js +++ b/backend/models/certificate.js @@ -1,13 +1,18 @@ // Objection Docs: // http://vincit.github.io/objection.js/ -const db = require('../db'); -const Model = require('objection').Model; -const User = require('./user'); -const now = require('./now_helper'); +const db = require('../db'); +const helpers = require('../lib/helpers'); +const Model = require('objection').Model; +const User = require('./user'); +const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', +]; + class Certificate extends Model { $beforeInsert () { this.created_on = now(); @@ -40,6 +45,16 @@ class Certificate extends Model { } } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'Certificate'; } diff --git a/backend/models/dead_host.js b/backend/models/dead_host.js index 2e31043ae4..483da3b6be 100644 --- a/backend/models/dead_host.js +++ b/backend/models/dead_host.js @@ -2,6 +2,7 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const User = require('./user'); const Certificate = require('./certificate'); @@ -9,6 +10,11 @@ const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'enabled', +]; + class DeadHost extends Model { $beforeInsert () { this.created_on = now(); @@ -36,6 +42,16 @@ class DeadHost extends Model { } } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'DeadHost'; } diff --git a/backend/models/proxy_host.js b/backend/models/proxy_host.js index d84181cf18..07aa5dd3c8 100644 --- a/backend/models/proxy_host.js +++ b/backend/models/proxy_host.js @@ -2,6 +2,7 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const User = require('./user'); const AccessList = require('./access_list'); @@ -10,6 +11,18 @@ const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'ssl_forced', + 'caching_enabled', + 'block_exploits', + 'allow_websocket_upgrade', + 'http2_support', + 'enabled', + 'hsts_enabled', + 'hsts_subdomains', +]; + class ProxyHost extends Model { $beforeInsert () { this.created_on = now(); @@ -37,6 +50,16 @@ class ProxyHost extends Model { } } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'ProxyHost'; } diff --git a/backend/models/redirection_host.js b/backend/models/redirection_host.js index c90a6de6c1..556742f0c6 100644 --- a/backend/models/redirection_host.js +++ b/backend/models/redirection_host.js @@ -3,6 +3,7 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const User = require('./user'); const Certificate = require('./certificate'); @@ -10,6 +11,14 @@ const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'enabled', + 'preserve_path', + 'ssl_forced', + 'block_exploits', +]; + class RedirectionHost extends Model { $beforeInsert () { this.created_on = now(); @@ -37,6 +46,16 @@ class RedirectionHost extends Model { } } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'RedirectionHost'; } diff --git a/backend/models/stream.js b/backend/models/stream.js index 23dd7ac0d8..c28b86cde0 100644 --- a/backend/models/stream.js +++ b/backend/models/stream.js @@ -2,6 +2,7 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const User = require('./user'); const now = require('./now_helper'); @@ -9,6 +10,12 @@ const Certificate = require('./certificate'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'tcp_forwarding', + 'udp_forwarding', +]; + class Stream extends Model { $beforeInsert () { this.created_on = now(); @@ -24,6 +31,16 @@ class Stream extends Model { this.modified_on = now(); } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'Stream'; } diff --git a/backend/models/user.js b/backend/models/user.js index 93489fefef..78fd3dd67d 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -2,12 +2,18 @@ // http://vincit.github.io/objection.js/ const db = require('../db'); +const helpers = require('../lib/helpers'); const Model = require('objection').Model; const UserPermission = require('./user_permission'); const now = require('./now_helper'); Model.knex(db); +const boolFields = [ + 'is_deleted', + 'is_disabled', +]; + class User extends Model { $beforeInsert () { this.created_on = now(); @@ -23,6 +29,16 @@ class User extends Model { this.modified_on = now(); } + $parseDatabaseJson(json) { + json = super.$parseDatabaseJson(json); + return helpers.convertIntFieldsToBool(json, boolFields); + } + + $formatDatabaseJson(json) { + json = helpers.convertBoolFieldsToInt(json, boolFields); + return super.$formatDatabaseJson(json); + } + static get name () { return 'User'; } diff --git a/backend/package.json b/backend/package.json index b938c9a9ca..1bc3ef1653 100644 --- a/backend/package.json +++ b/backend/package.json @@ -2,24 +2,24 @@ "name": "nginx-proxy-manager", "version": "0.0.0", "description": "A beautiful interface for creating Nginx endpoints", - "main": "js/index.js", + "main": "index.js", "dependencies": { - "ajv": "^6.12.0", + "@apidevtools/json-schema-ref-parser": "^11.7.0", + "ajv": "^8.17.1", "archiver": "^5.3.0", "batchflow": "^0.4.0", "bcrypt": "^5.0.0", - "body-parser": "^1.19.0", + "body-parser": "^1.20.3", "compression": "^1.7.4", - "express": "^4.19.2", + "express": "^4.20.0", "express-fileupload": "^1.1.9", "gravatar": "^1.8.0", - "json-schema-ref-parser": "^8.0.0", "jsonwebtoken": "^9.0.0", "knex": "2.4.2", "liquidjs": "10.6.1", "lodash": "^4.17.21", "moment": "^2.29.4", - "mysql": "^2.18.1", + "mysql2": "^3.11.1", "node-rsa": "^1.0.8", "objection": "3.0.1", "path": "^0.12.7", @@ -34,9 +34,14 @@ "author": "Jamie Curnow ", "license": "MIT", "devDependencies": { + "@apidevtools/swagger-parser": "^10.1.0", + "chalk": "4.1.2", "eslint": "^8.36.0", "eslint-plugin-align-assignments": "^1.1.2", "nodemon": "^2.0.2", "prettier": "^2.0.4" + }, + "scripts": { + "validate-schema": "node validate-schema.js" } } diff --git a/backend/routes/api/audit-log.js b/backend/routes/audit-log.js similarity index 73% rename from backend/routes/api/audit-log.js rename to backend/routes/audit-log.js index 8a2490c3f6..c68c7b35be 100644 --- a/backend/routes/api/audit-log.js +++ b/backend/routes/audit-log.js @@ -1,7 +1,7 @@ const express = require('express'); -const validator = require('../../lib/validator'); -const jwtdecode = require('../../lib/express/jwt-decode'); -const internalAuditLog = require('../../internal/audit-log'); +const validator = require('../lib/validator'); +const jwtdecode = require('../lib/express/jwt-decode'); +const internalAuditLog = require('../internal/audit-log'); let router = express.Router({ caseSensitive: true, @@ -14,7 +14,7 @@ let router = express.Router({ */ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -29,10 +29,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { diff --git a/backend/routes/api/main.js b/backend/routes/main.js similarity index 90% rename from backend/routes/api/main.js rename to backend/routes/main.js index 33cbbc21f2..b97096d0e5 100644 --- a/backend/routes/api/main.js +++ b/backend/routes/main.js @@ -1,6 +1,6 @@ const express = require('express'); -const pjson = require('../../package.json'); -const error = require('../../lib/error'); +const pjson = require('../package.json'); +const error = require('../lib/error'); let router = express.Router({ caseSensitive: true, @@ -43,7 +43,7 @@ router.use('/nginx/certificates', require('./nginx/certificates')); * * ALL /api/* */ -router.all(/(.+)/, function (req, res, next) { +router.all(/(.+)/, function (req, _, next) { req.params.page = req.params['0']; next(new error.ItemNotFoundError(req.params.page)); }); diff --git a/backend/routes/api/nginx/access_lists.js b/backend/routes/nginx/access_lists.js similarity index 79% rename from backend/routes/api/nginx/access_lists.js rename to backend/routes/nginx/access_lists.js index d55c3ae123..3837512775 100644 --- a/backend/routes/api/nginx/access_lists.js +++ b/backend/routes/nginx/access_lists.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalAccessList = require('../../../internal/access-list'); -const apiValidator = require('../../../lib/validator/api'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalAccessList = require('../../internal/access-list'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -30,10 +31,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +57,7 @@ router * Create a new access-list */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/access-lists#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/access-lists', 'post'), req.body) .then((payload) => { return internalAccessList.create(res.locals.access, payload); }) @@ -74,7 +75,7 @@ router */ router .route('/:list_id') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -90,10 +91,10 @@ router additionalProperties: false, properties: { list_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -119,7 +120,7 @@ router * Update and existing access-list */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/access-lists#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/access-lists/{listID}', 'put'), req.body) .then((payload) => { payload.id = parseInt(req.params.list_id, 10); return internalAccessList.update(res.locals.access, payload); diff --git a/backend/routes/api/nginx/certificates.js b/backend/routes/nginx/certificates.js similarity index 80% rename from backend/routes/api/nginx/certificates.js rename to backend/routes/nginx/certificates.js index ffdfb515d5..bf47c03fcc 100644 --- a/backend/routes/api/nginx/certificates.js +++ b/backend/routes/nginx/certificates.js @@ -1,8 +1,10 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalCertificate = require('../../../internal/certificate'); -const apiValidator = require('../../../lib/validator/api'); +const error = require('../../lib/error'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalCertificate = require('../../internal/certificate'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -15,7 +17,7 @@ let router = express.Router({ */ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -30,10 +32,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +58,7 @@ router * Create a new certificate */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/certificates#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/certificates', 'post'), req.body) .then((payload) => { req.setTimeout(900000); // 15 minutes timeout return internalCertificate.create(res.locals.access, payload); @@ -75,17 +77,22 @@ router */ router .route('/test-http') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) -/** - * GET /api/nginx/certificates/test-http - * - * Test HTTP challenge for domains - */ + /** + * GET /api/nginx/certificates/test-http + * + * Test HTTP challenge for domains + */ .get((req, res, next) => { + if (req.query.domains === undefined) { + next(new error.ValidationError('Domains are required as query parameters')); + return; + } + internalCertificate.testHttpsChallenge(res.locals.access, JSON.parse(req.query.domains)) .then((result) => { res.status(200) @@ -101,7 +108,7 @@ router */ router .route('/:certificate_id') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -117,10 +124,10 @@ router additionalProperties: false, properties: { certificate_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -140,24 +147,6 @@ router .catch(next); }) - /** - * PUT /api/nginx/certificates/123 - * - * Update and existing certificate - */ - .put((req, res, next) => { - apiValidator({$ref: 'endpoints/certificates#/links/2/schema'}, req.body) - .then((payload) => { - payload.id = parseInt(req.params.certificate_id, 10); - return internalCertificate.update(res.locals.access, payload); - }) - .then((result) => { - res.status(200) - .send(result); - }) - .catch(next); - }) - /** * DELETE /api/nginx/certificates/123 * @@ -179,7 +168,7 @@ router */ router .route('/:certificate_id/upload') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -213,7 +202,7 @@ router */ router .route('/:certificate_id/renew') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -270,7 +259,7 @@ router */ router .route('/validate') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) diff --git a/backend/routes/api/nginx/dead_hosts.js b/backend/routes/nginx/dead_hosts.js similarity index 83% rename from backend/routes/api/nginx/dead_hosts.js rename to backend/routes/nginx/dead_hosts.js index 08b58f2de3..83b3776534 100644 --- a/backend/routes/api/nginx/dead_hosts.js +++ b/backend/routes/nginx/dead_hosts.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalDeadHost = require('../../../internal/dead-host'); -const apiValidator = require('../../../lib/validator/api'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalDeadHost = require('../../internal/dead-host'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -15,7 +16,7 @@ let router = express.Router({ */ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -30,10 +31,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +57,7 @@ router * Create a new dead-host */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/dead-hosts#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/dead-hosts', 'post'), req.body) .then((payload) => { return internalDeadHost.create(res.locals.access, payload); }) @@ -90,10 +91,10 @@ router additionalProperties: false, properties: { host_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -119,7 +120,7 @@ router * Update and existing dead-host */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/dead-hosts#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/dead-hosts/{hostID}', 'put'), req.body) .then((payload) => { payload.id = parseInt(req.params.host_id, 10); return internalDeadHost.update(res.locals.access, payload); @@ -152,7 +153,7 @@ router */ router .route('/:host_id/enable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -176,7 +177,7 @@ router */ router .route('/:host_id/disable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) diff --git a/backend/routes/api/nginx/proxy_hosts.js b/backend/routes/nginx/proxy_hosts.js similarity index 83% rename from backend/routes/api/nginx/proxy_hosts.js rename to backend/routes/nginx/proxy_hosts.js index 6f933c3d39..3be4582a87 100644 --- a/backend/routes/api/nginx/proxy_hosts.js +++ b/backend/routes/nginx/proxy_hosts.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalProxyHost = require('../../../internal/proxy-host'); -const apiValidator = require('../../../lib/validator/api'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalProxyHost = require('../../internal/proxy-host'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -30,10 +31,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +57,7 @@ router * Create a new proxy-host */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/proxy-hosts#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/proxy-hosts', 'post'), req.body) .then((payload) => { return internalProxyHost.create(res.locals.access, payload); }) @@ -90,10 +91,10 @@ router additionalProperties: false, properties: { host_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -119,7 +120,7 @@ router * Update and existing proxy-host */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/proxy-hosts#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/proxy-hosts/{hostID}', 'put'), req.body) .then((payload) => { payload.id = parseInt(req.params.host_id, 10); return internalProxyHost.update(res.locals.access, payload); @@ -152,7 +153,7 @@ router */ router .route('/:host_id/enable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -176,7 +177,7 @@ router */ router .route('/:host_id/disable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) diff --git a/backend/routes/api/nginx/redirection_hosts.js b/backend/routes/nginx/redirection_hosts.js similarity index 84% rename from backend/routes/api/nginx/redirection_hosts.js rename to backend/routes/nginx/redirection_hosts.js index 4d44c11264..a46feb8416 100644 --- a/backend/routes/api/nginx/redirection_hosts.js +++ b/backend/routes/nginx/redirection_hosts.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalRedirectionHost = require('../../../internal/redirection-host'); -const apiValidator = require('../../../lib/validator/api'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalRedirectionHost = require('../../internal/redirection-host'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -30,10 +31,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +57,7 @@ router * Create a new redirection-host */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/redirection-hosts#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/redirection-hosts', 'post'), req.body) .then((payload) => { return internalRedirectionHost.create(res.locals.access, payload); }) @@ -90,10 +91,10 @@ router additionalProperties: false, properties: { host_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -119,7 +120,7 @@ router * Update and existing redirection-host */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/redirection-hosts#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/redirection-hosts/{hostID}', 'put'), req.body) .then((payload) => { payload.id = parseInt(req.params.host_id, 10); return internalRedirectionHost.update(res.locals.access, payload); diff --git a/backend/routes/api/nginx/streams.js b/backend/routes/nginx/streams.js similarity index 84% rename from backend/routes/api/nginx/streams.js rename to backend/routes/nginx/streams.js index 5e3fc28fe7..c033f2ef19 100644 --- a/backend/routes/api/nginx/streams.js +++ b/backend/routes/nginx/streams.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../../lib/validator'); -const jwtdecode = require('../../../lib/express/jwt-decode'); -const internalStream = require('../../../internal/stream'); -const apiValidator = require('../../../lib/validator/api'); +const validator = require('../../lib/validator'); +const jwtdecode = require('../../lib/express/jwt-decode'); +const apiValidator = require('../../lib/validator/api'); +const internalStream = require('../../internal/stream'); +const schema = require('../../schema'); let router = express.Router({ caseSensitive: true, @@ -30,10 +31,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -56,7 +57,7 @@ router * Create a new stream */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/streams#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/streams', 'post'), req.body) .then((payload) => { return internalStream.create(res.locals.access, payload); }) @@ -90,10 +91,10 @@ router additionalProperties: false, properties: { stream_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -119,7 +120,7 @@ router * Update and existing stream */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/streams#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/nginx/streams/{streamID}', 'put'), req.body) .then((payload) => { payload.id = parseInt(req.params.stream_id, 10); return internalStream.update(res.locals.access, payload); @@ -152,7 +153,7 @@ router */ router .route('/:host_id/enable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -176,7 +177,7 @@ router */ router .route('/:host_id/disable') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) diff --git a/backend/routes/api/reports.js b/backend/routes/reports.js similarity index 67% rename from backend/routes/api/reports.js rename to backend/routes/reports.js index 9e2c98c895..98c6cf86d2 100644 --- a/backend/routes/api/reports.js +++ b/backend/routes/reports.js @@ -1,6 +1,6 @@ const express = require('express'); -const jwtdecode = require('../../lib/express/jwt-decode'); -const internalReport = require('../../internal/report'); +const jwtdecode = require('../lib/express/jwt-decode'); +const internalReport = require('../internal/report'); let router = express.Router({ caseSensitive: true, @@ -10,14 +10,14 @@ let router = express.Router({ router .route('/hosts') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) /** * GET /reports/hosts */ - .get(jwtdecode(), (req, res, next) => { + .get(jwtdecode(), (_, res, next) => { internalReport.getHostsReport(res.locals.access) .then((data) => { res.status(200) diff --git a/backend/routes/api/schema.js b/backend/routes/schema.js similarity index 71% rename from backend/routes/api/schema.js rename to backend/routes/schema.js index fc6bd5bdf1..fc3e48b6cc 100644 --- a/backend/routes/api/schema.js +++ b/backend/routes/schema.js @@ -1,8 +1,8 @@ -const express = require('express'); -const swaggerJSON = require('../../doc/api.swagger.json'); -const PACKAGE = require('../../package.json'); +const express = require('express'); +const schema = require('../schema'); +const PACKAGE = require('../package.json'); -let router = express.Router({ +const router = express.Router({ caseSensitive: true, strict: true, mergeParams: true @@ -10,14 +10,16 @@ let router = express.Router({ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) /** * GET /schema */ - .get((req, res/*, next*/) => { + .get(async (req, res) => { + let swaggerJSON = await schema.getCompiledSchema(); + let proto = req.protocol; if (typeof req.headers['x-forwarded-proto'] !== 'undefined' && req.headers['x-forwarded-proto']) { proto = req.headers['x-forwarded-proto']; diff --git a/backend/routes/api/settings.js b/backend/routes/settings.js similarity index 74% rename from backend/routes/api/settings.js rename to backend/routes/settings.js index d08b2bf5c5..dac4c3d1a7 100644 --- a/backend/routes/api/settings.js +++ b/backend/routes/settings.js @@ -1,8 +1,9 @@ const express = require('express'); -const validator = require('../../lib/validator'); -const jwtdecode = require('../../lib/express/jwt-decode'); -const internalSetting = require('../../internal/setting'); -const apiValidator = require('../../lib/validator/api'); +const validator = require('../lib/validator'); +const jwtdecode = require('../lib/express/jwt-decode'); +const apiValidator = require('../lib/validator/api'); +const internalSetting = require('../internal/setting'); +const schema = require('../schema'); let router = express.Router({ caseSensitive: true, @@ -15,7 +16,7 @@ let router = express.Router({ */ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -25,7 +26,7 @@ router * * Retrieve all settings */ - .get((req, res, next) => { + .get((_, res, next) => { internalSetting.getAll(res.locals.access) .then((rows) => { res.status(200) @@ -41,7 +42,7 @@ router */ router .route('/:setting_id') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -57,7 +58,8 @@ router additionalProperties: false, properties: { setting_id: { - $ref: 'definitions#/definitions/setting_id' + type: 'string', + minLength: 1 } } }, { @@ -81,7 +83,7 @@ router * Update and existing setting */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/settings#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/settings/{settingID}', 'put'), req.body) .then((payload) => { payload.id = req.params.setting_id; return internalSetting.update(res.locals.access, payload); diff --git a/backend/routes/api/tokens.js b/backend/routes/tokens.js similarity index 70% rename from backend/routes/api/tokens.js rename to backend/routes/tokens.js index a21f998ae1..72d01d41d8 100644 --- a/backend/routes/api/tokens.js +++ b/backend/routes/tokens.js @@ -1,7 +1,8 @@ const express = require('express'); -const jwtdecode = require('../../lib/express/jwt-decode'); -const internalToken = require('../../internal/token'); -const apiValidator = require('../../lib/validator/api'); +const jwtdecode = require('../lib/express/jwt-decode'); +const apiValidator = require('../lib/validator/api'); +const internalToken = require('../internal/token'); +const schema = require('../schema'); let router = express.Router({ caseSensitive: true, @@ -11,7 +12,7 @@ let router = express.Router({ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) @@ -39,11 +40,9 @@ router * * Create a new Token */ - .post((req, res, next) => { - apiValidator({$ref: 'endpoints/tokens#/links/0/schema'}, req.body) - .then((payload) => { - return internalToken.getTokenFromEmail(payload); - }) + .post(async (req, res, next) => { + apiValidator(schema.getValidationSchema('/tokens', 'post'), req.body) + .then(internalToken.getTokenFromEmail) .then((data) => { res.status(200) .send(data); diff --git a/backend/routes/api/users.js b/backend/routes/users.js similarity index 79% rename from backend/routes/api/users.js rename to backend/routes/users.js index 1c6bd0ad27..f8ce366c9d 100644 --- a/backend/routes/api/users.js +++ b/backend/routes/users.js @@ -1,9 +1,10 @@ const express = require('express'); -const validator = require('../../lib/validator'); -const jwtdecode = require('../../lib/express/jwt-decode'); -const userIdFromMe = require('../../lib/express/user-id-from-me'); -const internalUser = require('../../internal/user'); -const apiValidator = require('../../lib/validator/api'); +const validator = require('../lib/validator'); +const jwtdecode = require('../lib/express/jwt-decode'); +const userIdFromMe = require('../lib/express/user-id-from-me'); +const internalUser = require('../internal/user'); +const apiValidator = require('../lib/validator/api'); +const schema = require('../schema'); let router = express.Router({ caseSensitive: true, @@ -16,7 +17,7 @@ let router = express.Router({ */ router .route('/') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -31,10 +32,10 @@ router additionalProperties: false, properties: { expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' }, query: { - $ref: 'definitions#/definitions/query' + $ref: 'common#/properties/query' } } }, { @@ -48,7 +49,11 @@ router res.status(200) .send(users); }) - .catch(next); + .catch((err) => { + console.log(err); + next(err); + }); + //.catch(next); }) /** @@ -57,7 +62,7 @@ router * Create a new User */ .post((req, res, next) => { - apiValidator({$ref: 'endpoints/users#/links/1/schema'}, req.body) + apiValidator(schema.getValidationSchema('/users', 'post'), req.body) .then((payload) => { return internalUser.create(res.locals.access, payload); }) @@ -75,7 +80,7 @@ router */ router .route('/:user_id') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) @@ -92,10 +97,10 @@ router additionalProperties: false, properties: { user_id: { - $ref: 'definitions#/definitions/id' + $ref: 'common#/properties/id' }, expand: { - $ref: 'definitions#/definitions/expand' + $ref: 'common#/properties/expand' } } }, { @@ -113,7 +118,10 @@ router res.status(200) .send(user); }) - .catch(next); + .catch((err) => { + console.log(err); + next(err); + }); }) /** @@ -122,7 +130,7 @@ router * Update and existing user */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/users#/links/2/schema'}, req.body) + apiValidator(schema.getValidationSchema('/users/{userID}', 'put'), req.body) .then((payload) => { payload.id = req.params.user_id; return internalUser.update(res.locals.access, payload); @@ -167,7 +175,7 @@ router * Update password for a user */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/users#/links/4/schema'}, req.body) + apiValidator(schema.getValidationSchema('/users/{userID}/auth', 'put'), req.body) .then((payload) => { payload.id = req.params.user_id; return internalUser.setPassword(res.locals.access, payload); @@ -198,7 +206,7 @@ router * Set some or all permissions for a user */ .put((req, res, next) => { - apiValidator({$ref: 'endpoints/users#/links/5/schema'}, req.body) + apiValidator(schema.getValidationSchema('/users/{userID}/permissions', 'put'), req.body) .then((payload) => { payload.id = req.params.user_id; return internalUser.setPermissions(res.locals.access, payload); @@ -217,7 +225,7 @@ router */ router .route('/:user_id/login') - .options((req, res) => { + .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) diff --git a/backend/schema/common.json b/backend/schema/common.json new file mode 100644 index 0000000000..83de0143cb --- /dev/null +++ b/backend/schema/common.json @@ -0,0 +1,115 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "common", + "type": "object", + "properties": { + "id": { + "description": "Unique identifier", + "readOnly": true, + "type": "integer", + "minimum": 1 + }, + "expand": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + ] + }, + "query": { + "anyOf": [ + { + "type": "null" + }, + { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + ] + }, + "created_on": { + "description": "Date and time of creation", + "readOnly": true, + "type": "string" + }, + "modified_on": { + "description": "Date and time of last update", + "readOnly": true, + "type": "string" + }, + "user_id": { + "description": "User ID", + "type": "integer", + "minimum": 1 + }, + "certificate_id": { + "description": "Certificate ID", + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string", + "pattern": "^new$" + } + ] + }, + "access_list_id": { + "description": "Access List ID", + "type": "integer", + "minimum": 0 + }, + "domain_names": { + "description": "Domain Names separated by a comma", + "type": "array", + "minItems": 1, + "maxItems": 100, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[^&| @!#%^();:/\\\\}{=+?<>,~`'\"]+$" + } + }, + "enabled": { + "description": "Is Enabled", + "type": "boolean" + }, + "ssl_forced": { + "description": "Is SSL Forced", + "type": "boolean" + }, + "hsts_enabled": { + "description": "Is HSTS Enabled", + "type": "boolean" + }, + "hsts_subdomains": { + "description": "Is HSTS applicable to all subdomains", + "type": "boolean" + }, + "ssl_provider": { + "type": "string", + "pattern": "^(letsencrypt|other)$" + }, + "http2_support": { + "description": "HTTP2 Protocol Support", + "type": "boolean" + }, + "block_exploits": { + "description": "Should we block common exploits", + "type": "boolean" + }, + "caching_enabled": { + "description": "Should we cache assets", + "type": "boolean" + } + } +} diff --git a/backend/schema/components/access-list-object.json b/backend/schema/components/access-list-object.json new file mode 100644 index 0000000000..cd0218d725 --- /dev/null +++ b/backend/schema/components/access-list-object.json @@ -0,0 +1,53 @@ +{ + "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, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "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" + }, + "meta": { + "type": "object" + } + } +} diff --git a/backend/schema/components/audit-log-object.json b/backend/schema/components/audit-log-object.json new file mode 100644 index 0000000000..3e5e8594b8 --- /dev/null +++ b/backend/schema/components/audit-log-object.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "description": "Audit Log object", + "required": ["id", "created_on", "modified_on", "user_id", "object_type", "object_id", "action", "meta"], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "object_type": { + "type": "string" + }, + "object_id": { + "$ref": "../common.json#/properties/id" + }, + "action": { + "type": "string" + }, + "meta": { + "type": "object" + } + } +} diff --git a/backend/schema/components/certificate-list.json b/backend/schema/components/certificate-list.json new file mode 100644 index 0000000000..cec4db82c9 --- /dev/null +++ b/backend/schema/components/certificate-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "Certificates list", + "items": { + "$ref": "./certificate-object.json" + } +} diff --git a/backend/schema/components/certificate-object.json b/backend/schema/components/certificate-object.json new file mode 100644 index 0000000000..b75dcf61d4 --- /dev/null +++ b/backend/schema/components/certificate-object.json @@ -0,0 +1,81 @@ +{ + "type": "object", + "description": "Certificate object", + "required": ["id", "created_on", "modified_on", "owner_user_id", "provider", "nice_name", "domain_names", "expires_on", "meta"], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "provider": { + "$ref": "../common.json#/properties/ssl_provider" + }, + "nice_name": { + "type": "string", + "description": "Nice Name for the custom certificate" + }, + "domain_names": { + "description": "Domain Names separated by a comma", + "type": "array", + "maxItems": 100, + "uniqueItems": true, + "items": { + "type": "string", + "pattern": "^[^&| @!#%^();:/\\\\}{=+?<>,~`'\"]+$" + } + }, + "expires_on": { + "description": "Date and time of expiration", + "readOnly": true, + "type": "string" + }, + "owner": { + "$ref": "./user-object.json" + }, + "meta": { + "type": "object", + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string", + "minLength": 1 + }, + "certificate_key": { + "type": "string", + "minLength": 1 + }, + "dns_challenge": { + "type": "boolean" + }, + "dns_provider": { + "type": "string" + }, + "dns_provider_credentials": { + "type": "string" + }, + "letsencrypt_agree": { + "type": "boolean" + }, + "letsencrypt_certificate": { + "type": "object" + }, + "letsencrypt_email": { + "type": "string" + }, + "propagation_seconds": { + "type": "integer", + "minimum": 0 + } + } + } + } +} diff --git a/backend/schema/components/dead-host-list.json b/backend/schema/components/dead-host-list.json new file mode 100644 index 0000000000..56ff303ba3 --- /dev/null +++ b/backend/schema/components/dead-host-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "404 Hosts list", + "items": { + "$ref": "./dead-host-object.json" + } +} diff --git a/backend/schema/components/dead-host-object.json b/backend/schema/components/dead-host-object.json new file mode 100644 index 0000000000..792c2f81ed --- /dev/null +++ b/backend/schema/components/dead-host-object.json @@ -0,0 +1,47 @@ +{ + "type": "object", + "description": "404 Host object", + "required": ["id", "created_on", "modified_on", "owner_user_id", "domain_names", "certificate_id", "ssl_forced", "hsts_enabled", "hsts_subdomains", "http2_support", "advanced_config", "enabled", "meta"], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "domain_names": { + "$ref": "../common.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../common.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../common.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../common.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../common.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../common.json#/properties/http2_support" + }, + "advanced_config": { + "type": "string" + }, + "enabled": { + "$ref": "../common.json#/properties/enabled" + }, + "meta": { + "type": "object" + } + } +} diff --git a/backend/schema/components/error-object.json b/backend/schema/components/error-object.json new file mode 100644 index 0000000000..c2540cf1fd --- /dev/null +++ b/backend/schema/components/error-object.json @@ -0,0 +1,14 @@ +{ + "type": "object", + "description": "Error object", + "additionalProperties": false, + "required": ["code", "message"], + "properties": { + "code": { + "type": "integer" + }, + "message": { + "type": "string" + } + } +} diff --git a/backend/schema/components/error.json b/backend/schema/components/error.json new file mode 100644 index 0000000000..ceb3e1492a --- /dev/null +++ b/backend/schema/components/error.json @@ -0,0 +1,9 @@ +{ + "type": "object", + "description": "Error", + "properties": { + "error": { + "$ref": "./error-object.json" + } + } +} diff --git a/backend/schema/components/health-object.json b/backend/schema/components/health-object.json new file mode 100644 index 0000000000..8d223417be --- /dev/null +++ b/backend/schema/components/health-object.json @@ -0,0 +1,38 @@ +{ + "type": "object", + "description": "Health object", + "additionalProperties": false, + "required": ["status", "version"], + "properties": { + "status": { + "type": "string", + "description": "Healthy", + "example": "OK" + }, + "version": { + "type": "object", + "description": "The version object", + "example": { + "major": 2, + "minor": 0, + "revision": 0 + }, + "additionalProperties": false, + "required": ["major", "minor", "revision"], + "properties": { + "major": { + "type": "integer", + "minimum": 0 + }, + "minor": { + "type": "integer", + "minimum": 0 + }, + "revision": { + "type": "integer", + "minimum": 0 + } + } + } + } +} diff --git a/backend/schema/components/permission-object.json b/backend/schema/components/permission-object.json new file mode 100644 index 0000000000..b852a014d0 --- /dev/null +++ b/backend/schema/components/permission-object.json @@ -0,0 +1,41 @@ +{ + "type": "object", + "minProperties": 1, + "properties": { + "visibility": { + "type": "string", + "description": "Visibility Type", + "enum": ["all", "user"] + }, + "access_lists": { + "type": "string", + "description": "Access Lists Permissions", + "enum": ["hidden", "view", "manage"] + }, + "dead_hosts": { + "type": "string", + "description": "404 Hosts Permissions", + "enum": ["hidden", "view", "manage"] + }, + "proxy_hosts": { + "type": "string", + "description": "Proxy Hosts Permissions", + "enum": ["hidden", "view", "manage"] + }, + "redirection_hosts": { + "type": "string", + "description": "Redirection Permissions", + "enum": ["hidden", "view", "manage"] + }, + "streams": { + "type": "string", + "description": "Streams Permissions", + "enum": ["hidden", "view", "manage"] + }, + "certificates": { + "type": "string", + "description": "Certificates Permissions", + "enum": ["hidden", "view", "manage"] + } + } +} diff --git a/backend/schema/components/proxy-host-list.json b/backend/schema/components/proxy-host-list.json new file mode 100644 index 0000000000..39789b4a73 --- /dev/null +++ b/backend/schema/components/proxy-host-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "Proxy Hosts list", + "items": { + "$ref": "./proxy-host-object.json" + } +} diff --git a/backend/schema/components/proxy-host-object.json b/backend/schema/components/proxy-host-object.json new file mode 100644 index 0000000000..5098802b11 --- /dev/null +++ b/backend/schema/components/proxy-host-object.json @@ -0,0 +1,154 @@ +{ + "type": "object", + "description": "Proxy Host object", + "required": [ + "id", + "created_on", + "modified_on", + "owner_user_id", + "domain_names", + "forward_host", + "forward_port", + "access_list_id", + "certificate_id", + "ssl_forced", + "caching_enabled", + "block_exploits", + "advanced_config", + "meta", + "allow_websocket_upgrade", + "http2_support", + "forward_scheme", + "enabled", + "locations", + "hsts_enabled", + "hsts_subdomains", + "certificate" + ], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "domain_names": { + "$ref": "../common.json#/properties/domain_names" + }, + "forward_host": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "forward_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "access_list_id": { + "$ref": "../common.json#/properties/access_list_id" + }, + "certificate_id": { + "$ref": "../common.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../common.json#/properties/ssl_forced" + }, + "caching_enabled": { + "$ref": "../common.json#/properties/caching_enabled" + }, + "block_exploits": { + "$ref": "../common.json#/properties/block_exploits" + }, + "advanced_config": { + "type": "string" + }, + "meta": { + "type": "object" + }, + "allow_websocket_upgrade": { + "description": "Allow Websocket Upgrade for all paths", + "example": true, + "type": "boolean" + }, + "http2_support": { + "$ref": "../common.json#/properties/http2_support" + }, + "forward_scheme": { + "type": "string", + "enum": ["http", "https"] + }, + "enabled": { + "$ref": "../common.json#/properties/enabled" + }, + "locations": { + "type": "array", + "minItems": 0, + "items": { + "type": "object", + "required": ["forward_scheme", "forward_host", "forward_port", "path"], + "additionalProperties": false, + "properties": { + "id": { + "type": ["integer", "null"] + }, + "path": { + "type": "string", + "minLength": 1 + }, + "forward_scheme": { + "$ref": "#/properties/forward_scheme" + }, + "forward_host": { + "$ref": "#/properties/forward_host" + }, + "forward_port": { + "$ref": "#/properties/forward_port" + }, + "forward_path": { + "type": "string" + }, + "advanced_config": { + "type": "string" + } + } + } + }, + "hsts_enabled": { + "$ref": "../common.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../common.json#/properties/hsts_subdomains" + }, + "certificate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "./certificate-object.json" + } + ] + }, + "owner": { + "$ref": "./user-object.json" + }, + "access_list": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "./access-list-object.json" + } + ] + } + } +} diff --git a/backend/schema/components/redirection-host-list.json b/backend/schema/components/redirection-host-list.json new file mode 100644 index 0000000000..716dcfa1da --- /dev/null +++ b/backend/schema/components/redirection-host-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "Redirection Hosts list", + "items": { + "$ref": "./redirection-host-object.json" + } +} diff --git a/backend/schema/components/redirection-host-object.json b/backend/schema/components/redirection-host-object.json new file mode 100644 index 0000000000..e7a495fd39 --- /dev/null +++ b/backend/schema/components/redirection-host-object.json @@ -0,0 +1,72 @@ +{ + "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"], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "domain_names": { + "$ref": "../common.json#/properties/domain_names" + }, + "forward_http_code": { + "description": "Redirect HTTP Status Code", + "example": 302, + "type": "integer", + "minimum": 300, + "maximum": 308 + }, + "forward_scheme": { + "type": "string", + "enum": ["auto", "http", "https"] + }, + "forward_domain_name": { + "description": "Domain Name", + "example": "jc21.com", + "type": "string", + "pattern": "^(?:[^.*]+\\.?)+[^.]$" + }, + "preserve_path": { + "description": "Should the path be preserved", + "example": true, + "type": "boolean" + }, + "certificate_id": { + "$ref": "../common.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../common.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../common.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../common.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../common.json#/properties/http2_support" + }, + "block_exploits": { + "$ref": "../common.json#/properties/block_exploits" + }, + "advanced_config": { + "type": "string" + }, + "enabled": { + "$ref": "../common.json#/properties/enabled" + }, + "meta": { + "type": "object" + } + } +} diff --git a/backend/schema/components/security-schemes.json b/backend/schema/components/security-schemes.json new file mode 100644 index 0000000000..82407be3f8 --- /dev/null +++ b/backend/schema/components/security-schemes.json @@ -0,0 +1,6 @@ +{ + "BearerAuth": { + "type": "http", + "scheme": "bearer" + } +} diff --git a/backend/schema/components/setting-list.json b/backend/schema/components/setting-list.json new file mode 100644 index 0000000000..c66f099ea4 --- /dev/null +++ b/backend/schema/components/setting-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "Setting list", + "items": { + "$ref": "./setting-object.json" + } +} diff --git a/backend/schema/components/setting-object.json b/backend/schema/components/setting-object.json new file mode 100644 index 0000000000..b9c6a1039d --- /dev/null +++ b/backend/schema/components/setting-object.json @@ -0,0 +1,56 @@ +{ + "type": "object", + "description": "Setting object", + "required": ["id", "name", "description", "value", "meta"], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "description": "Setting ID", + "minLength": 1, + "example": "default-site" + }, + "name": { + "type": "string", + "description": "Setting Display Name", + "minLength": 1, + "example": "Default Site" + }, + "description": { + "type": "string", + "description": "Meaningful description", + "minLength": 1, + "example": "What to show when Nginx is hit with an unknown Host" + }, + "value": { + "description": "Value in almost any form", + "example": "congratulations", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "integer" + }, + { + "type": "object" + }, + { + "type": "number" + }, + { + "type": "array" + } + ] + }, + "meta": { + "description": "Extra metadata", + "example": { + "redirect": "http://example.com", + "html": "

404

" + }, + "type": "object" + } + } +} diff --git a/backend/schema/components/stream-list.json b/backend/schema/components/stream-list.json new file mode 100644 index 0000000000..39789b4a73 --- /dev/null +++ b/backend/schema/components/stream-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "Proxy Hosts list", + "items": { + "$ref": "./proxy-host-object.json" + } +} diff --git a/backend/schema/components/stream-object.json b/backend/schema/components/stream-object.json new file mode 100644 index 0000000000..cd8e1374f8 --- /dev/null +++ b/backend/schema/components/stream-object.json @@ -0,0 +1,76 @@ +{ + "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"], + "additionalProperties": false, + "properties": { + "id": { + "$ref": "../common.json#/properties/id" + }, + "created_on": { + "$ref": "../common.json#/properties/created_on" + }, + "modified_on": { + "$ref": "../common.json#/properties/modified_on" + }, + "owner_user_id": { + "$ref": "../common.json#/properties/user_id" + }, + "incoming_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "forwarding_host": { + "anyOf": [ + { + "description": "Domain Name", + "example": "jc21.com", + "type": "string", + "pattern": "^(?:[^.*]+\\.?)+[^.]$" + }, + { + "type": "string", + "format": "ipv4" + }, + { + "type": "string", + "format": "ipv6" + } + ] + }, + "forwarding_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "tcp_forwarding": { + "type": "boolean" + }, + "udp_forwarding": { + "type": "boolean" + }, + "domain_names": { + "$ref": "../common.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../common.json#/properties/certificate_id" + }, + "certificate": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "./certificate-object.json" + } + ] + }, + "enabled": { + "$ref": "../common.json#/properties/enabled" + }, + "meta": { + "type": "object" + } + } +} diff --git a/backend/schema/components/token-object.json b/backend/schema/components/token-object.json new file mode 100644 index 0000000000..a7044bce9b --- /dev/null +++ b/backend/schema/components/token-object.json @@ -0,0 +1,19 @@ +{ + "type": "object", + "description": "Token object", + "required": ["expires", "token"], + "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" + } + } +} diff --git a/backend/schema/components/user-list.json b/backend/schema/components/user-list.json new file mode 100644 index 0000000000..c5c0f71169 --- /dev/null +++ b/backend/schema/components/user-list.json @@ -0,0 +1,7 @@ +{ + "type": "array", + "description": "User list", + "items": { + "$ref": "./user-object.json" + } +} diff --git a/backend/schema/components/user-object.json b/backend/schema/components/user-object.json new file mode 100644 index 0000000000..180e8f1976 --- /dev/null +++ b/backend/schema/components/user-object.json @@ -0,0 +1,59 @@ +{ + "type": "object", + "description": "User object", + "required": ["id", "created_on", "modified_on", "is_disabled", "email", "name", "nickname", "avatar", "roles"], + "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "description": "User ID", + "minimum": 1, + "example": 1 + }, + "created_on": { + "type": "string", + "description": "Created Date", + "example": "2020-01-30T09:36:08.000Z" + }, + "modified_on": { + "type": "string", + "description": "Modified Date", + "example": "2020-01-30T09:41:04.000Z" + }, + "is_disabled": { + "type": "boolean", + "description": "Is user Disabled", + "example": true + }, + "email": { + "type": "string", + "description": "Email", + "minLength": 3, + "example": "jc@jc21.com" + }, + "name": { + "type": "string", + "description": "Name", + "minLength": 1, + "example": "Jamie Curnow" + }, + "nickname": { + "type": "string", + "description": "Nickname", + "example": "James" + }, + "avatar": { + "type": "string", + "description": "Gravatar URL based on email, without scheme", + "example": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm" + }, + "roles": { + "description": "Roles applied", + "example": ["admin"], + "type": "array", + "items": { + "type": "string" + } + } + } +} diff --git a/backend/schema/definitions.json b/backend/schema/definitions.json deleted file mode 100644 index 640093a088..0000000000 --- a/backend/schema/definitions.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "definitions", - "definitions": { - "id": { - "description": "Unique identifier", - "example": 123456, - "readOnly": true, - "type": "integer", - "minimum": 1 - }, - "setting_id": { - "description": "Unique identifier for a Setting", - "example": "default-site", - "readOnly": true, - "type": "string", - "minLength": 2 - }, - "token": { - "type": "string", - "minLength": 10 - }, - "expand": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - } - } - ] - }, - "sort": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "required": [ - "field", - "dir" - ], - "additionalProperties": false, - "properties": { - "field": { - "type": "string" - }, - "dir": { - "type": "string", - "pattern": "^(asc|desc)$" - } - } - } - }, - "query": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "string", - "minLength": 1, - "maxLength": 255 - } - ] - }, - "criteria": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "object" - } - ] - }, - "fields": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - } - } - ] - }, - "omit": { - "anyOf": [ - { - "type": "null" - }, - { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - } - } - ] - }, - "created_on": { - "description": "Date and time of creation", - "format": "date-time", - "readOnly": true, - "type": "string" - }, - "modified_on": { - "description": "Date and time of last update", - "format": "date-time", - "readOnly": true, - "type": "string" - }, - "user_id": { - "description": "User ID", - "example": 1234, - "type": "integer", - "minimum": 1 - }, - "certificate_id": { - "description": "Certificate ID", - "example": 1234, - "anyOf": [ - { - "type": "integer", - "minimum": 0 - }, - { - "type": "string", - "pattern": "^new$" - } - ] - }, - "access_list_id": { - "description": "Access List ID", - "example": 1234, - "type": "integer", - "minimum": 0 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 255 - }, - "email": { - "description": "Email Address", - "example": "john@example.com", - "format": "email", - "type": "string", - "minLength": 6, - "maxLength": 100 - }, - "password": { - "description": "Password", - "type": "string", - "minLength": 8, - "maxLength": 255 - }, - "domain_name": { - "description": "Domain Name", - "example": "jc21.com", - "type": "string", - "pattern": "^(?:[^.*]+\\.?)+[^.]$" - }, - "domain_names": { - "description": "Domain Names separated by a comma", - "example": "*.jc21.com,blog.jc21.com", - "type": "array", - "maxItems": 100, - "uniqueItems": true, - "items": { - "type": "string", - "pattern": "^(?:\\*\\.)?(?:[^.*]+\\.?)+[^.]$" - } - }, - "http_code": { - "description": "Redirect HTTP Status Code", - "example": 302, - "type": "integer", - "minimum": 300, - "maximum": 308 - }, - "scheme": { - "description": "RFC Protocol", - "example": "HTTPS or $scheme", - "type": "string", - "minLength": 4 - }, - "enabled": { - "description": "Is Enabled", - "example": true, - "type": "boolean" - }, - "ssl_enabled": { - "description": "Is SSL Enabled", - "example": true, - "type": "boolean" - }, - "ssl_forced": { - "description": "Is SSL Forced", - "example": false, - "type": "boolean" - }, - "hsts_enabled": { - "description": "Is HSTS Enabled", - "example": false, - "type": "boolean" - }, - "hsts_subdomains": { - "description": "Is HSTS applicable to all subdomains", - "example": false, - "type": "boolean" - }, - "ssl_provider": { - "type": "string", - "pattern": "^(letsencrypt|other)$" - }, - "http2_support": { - "description": "HTTP2 Protocol Support", - "example": false, - "type": "boolean" - }, - "block_exploits": { - "description": "Should we block common exploits", - "example": true, - "type": "boolean" - }, - "caching_enabled": { - "description": "Should we cache assets", - "example": true, - "type": "boolean" - } - } -} diff --git a/backend/schema/endpoints/access-lists.json b/backend/schema/endpoints/access-lists.json deleted file mode 100644 index 404e323765..0000000000 --- a/backend/schema/endpoints/access-lists.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/access-lists", - "title": "Access Lists", - "description": "Endpoints relating to Access Lists", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "name": { - "type": "string", - "description": "Name of the Access List" - }, - "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" - }, - "meta": { - "type": "object" - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "name": { - "$ref": "#/definitions/name" - }, - "meta": { - "$ref": "#/definitions/meta" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Access Lists", - "href": "/nginx/access-lists", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new Access List", - "href": "/nginx/access-list", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": ["name"], - "properties": { - "name": { - "$ref": "#/definitions/name" - }, - "satisfy_any": { - "$ref": "#/definitions/satisfy_any" - }, - "pass_auth": { - "$ref": "#/definitions/pass_auth" - }, - "items": { - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 1 - } - } - } - }, - "clients": { - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "address": { - "$ref": "#/definitions/address" - }, - "directive": { - "$ref": "#/definitions/directive" - } - } - } - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing Access List", - "href": "/nginx/access-list/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "$ref": "#/definitions/name" - }, - "satisfy_any": { - "$ref": "#/definitions/satisfy_any" - }, - "pass_auth": { - "$ref": "#/definitions/pass_auth" - }, - "items": { - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "username": { - "type": "string", - "minLength": 1 - }, - "password": { - "type": "string", - "minLength": 0 - } - } - } - }, - "clients": { - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "address": { - "$ref": "#/definitions/address" - }, - "directive": { - "$ref": "#/definitions/directive" - } - } - } - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing Access List", - "href": "/nginx/access-list/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - } - ] -} diff --git a/backend/schema/endpoints/certificates.json b/backend/schema/endpoints/certificates.json deleted file mode 100644 index 955ca75c97..0000000000 --- a/backend/schema/endpoints/certificates.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/certificates", - "title": "Certificates", - "description": "Endpoints relating to Certificates", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "provider": { - "$ref": "../definitions.json#/definitions/ssl_provider" - }, - "nice_name": { - "type": "string", - "description": "Nice Name for the custom certificate" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "expires_on": { - "description": "Date and time of expiration", - "format": "date-time", - "readOnly": true, - "type": "string" - }, - "meta": { - "type": "object", - "additionalProperties": false, - "properties": { - "letsencrypt_email": { - "type": "string", - "format": "email" - }, - "letsencrypt_agree": { - "type": "boolean" - }, - "dns_challenge": { - "type": "boolean" - }, - "dns_provider": { - "type": "string" - }, - "dns_provider_credentials": { - "type": "string" - }, - "propagation_seconds": { - "anyOf": [ - { - "type": "integer", - "minimum": 0 - } - ] - - } - } - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "provider": { - "$ref": "#/definitions/provider" - }, - "nice_name": { - "$ref": "#/definitions/nice_name" - }, - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "expires_on": { - "$ref": "#/definitions/expires_on" - }, - "meta": { - "$ref": "#/definitions/meta" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Certificates", - "href": "/nginx/certificates", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new Certificate", - "href": "/nginx/certificates", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "provider" - ], - "properties": { - "provider": { - "$ref": "#/definitions/provider" - }, - "nice_name": { - "$ref": "#/definitions/nice_name" - }, - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing Certificate", - "href": "/nginx/certificates/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Test HTTP Challenge", - "description": "Tests whether the HTTP challenge should work", - "href": "/nginx/certificates/{definitions.identity.example}/test-http", - "access": "private", - "method": "GET", - "rel": "info", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - } - } - ] -} diff --git a/backend/schema/endpoints/dead-hosts.json b/backend/schema/endpoints/dead-hosts.json deleted file mode 100644 index 0c73c3be16..0000000000 --- a/backend/schema/endpoints/dead-hosts.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/dead-hosts", - "title": "404 Hosts", - "description": "Endpoints relating to 404 Hosts", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "../definitions.json#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "../definitions.json#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "../definitions.json#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "../definitions.json#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "../definitions.json#/definitions/http2_support" - }, - "advanced_config": { - "type": "string" - }, - "enabled": { - "$ref": "../definitions.json#/definitions/enabled" - }, - "meta": { - "type": "object" - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of 404 Hosts", - "href": "/nginx/dead-hosts", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new 404 Host", - "href": "/nginx/dead-hosts", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "domain_names" - ], - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing 404 Host", - "href": "/nginx/dead-hosts/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing 404 Host", - "href": "/nginx/dead-hosts/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Enable", - "description": "Enables a existing 404 Host", - "href": "/nginx/dead-hosts/{definitions.identity.example}/enable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Disable", - "description": "Disables a existing 404 Host", - "href": "/nginx/dead-hosts/{definitions.identity.example}/disable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - } - ] -} diff --git a/backend/schema/endpoints/proxy-hosts.json b/backend/schema/endpoints/proxy-hosts.json deleted file mode 100644 index 9a3fff2fc7..0000000000 --- a/backend/schema/endpoints/proxy-hosts.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/proxy-hosts", - "title": "Proxy Hosts", - "description": "Endpoints relating to Proxy Hosts", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "forward_scheme": { - "type": "string", - "enum": ["http", "https"] - }, - "forward_host": { - "type": "string", - "minLength": 1, - "maxLength": 255 - }, - "forward_port": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "certificate_id": { - "$ref": "../definitions.json#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "../definitions.json#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "../definitions.json#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "../definitions.json#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "../definitions.json#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "../definitions.json#/definitions/block_exploits" - }, - "caching_enabled": { - "$ref": "../definitions.json#/definitions/caching_enabled" - }, - "allow_websocket_upgrade": { - "description": "Allow Websocket Upgrade for all paths", - "example": true, - "type": "boolean" - }, - "access_list_id": { - "$ref": "../definitions.json#/definitions/access_list_id" - }, - "advanced_config": { - "type": "string" - }, - "enabled": { - "$ref": "../definitions.json#/definitions/enabled" - }, - "meta": { - "type": "object" - }, - "locations": { - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "required": [ - "forward_scheme", - "forward_host", - "forward_port", - "path" - ], - "additionalProperties": false, - "properties": { - "id": { - "type": ["integer", "null"] - }, - "path": { - "type": "string", - "minLength": 1 - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_host": { - "$ref": "#/definitions/forward_host" - }, - "forward_port": { - "$ref": "#/definitions/forward_port" - }, - "forward_path": { - "type": "string" - }, - "advanced_config": { - "type": "string" - } - } - } - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_host": { - "$ref": "#/definitions/forward_host" - }, - "forward_port": { - "$ref": "#/definitions/forward_port" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "caching_enabled": { - "$ref": "#/definitions/caching_enabled" - }, - "allow_websocket_upgrade": { - "$ref": "#/definitions/allow_websocket_upgrade" - }, - "access_list_id": { - "$ref": "#/definitions/access_list_id" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - }, - "locations": { - "$ref": "#/definitions/locations" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Proxy Hosts", - "href": "/nginx/proxy-hosts", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new Proxy Host", - "href": "/nginx/proxy-hosts", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "domain_names", - "forward_scheme", - "forward_host", - "forward_port" - ], - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_host": { - "$ref": "#/definitions/forward_host" - }, - "forward_port": { - "$ref": "#/definitions/forward_port" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "caching_enabled": { - "$ref": "#/definitions/caching_enabled" - }, - "allow_websocket_upgrade": { - "$ref": "#/definitions/allow_websocket_upgrade" - }, - "access_list_id": { - "$ref": "#/definitions/access_list_id" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - }, - "locations": { - "$ref": "#/definitions/locations" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing Proxy Host", - "href": "/nginx/proxy-hosts/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_host": { - "$ref": "#/definitions/forward_host" - }, - "forward_port": { - "$ref": "#/definitions/forward_port" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "caching_enabled": { - "$ref": "#/definitions/caching_enabled" - }, - "allow_websocket_upgrade": { - "$ref": "#/definitions/allow_websocket_upgrade" - }, - "access_list_id": { - "$ref": "#/definitions/access_list_id" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - }, - "locations": { - "$ref": "#/definitions/locations" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing Proxy Host", - "href": "/nginx/proxy-hosts/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Enable", - "description": "Enables a existing Proxy Host", - "href": "/nginx/proxy-hosts/{definitions.identity.example}/enable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Disable", - "description": "Disables a existing Proxy Host", - "href": "/nginx/proxy-hosts/{definitions.identity.example}/disable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - } - ] -} diff --git a/backend/schema/endpoints/redirection-hosts.json b/backend/schema/endpoints/redirection-hosts.json deleted file mode 100644 index 14a4699853..0000000000 --- a/backend/schema/endpoints/redirection-hosts.json +++ /dev/null @@ -1,305 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/redirection-hosts", - "title": "Redirection Hosts", - "description": "Endpoints relating to Redirection Hosts", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "forward_http_code": { - "$ref": "../definitions.json#/definitions/http_code" - }, - "forward_scheme": { - "$ref": "../definitions.json#/definitions/scheme" - }, - "forward_domain_name": { - "$ref": "../definitions.json#/definitions/domain_name" - }, - "preserve_path": { - "description": "Should the path be preserved", - "example": true, - "type": "boolean" - }, - "certificate_id": { - "$ref": "../definitions.json#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "../definitions.json#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "../definitions.json#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "../definitions.json#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "../definitions.json#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "../definitions.json#/definitions/block_exploits" - }, - "advanced_config": { - "type": "string" - }, - "enabled": { - "$ref": "../definitions.json#/definitions/enabled" - }, - "meta": { - "type": "object" - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_http_code": { - "$ref": "#/definitions/forward_http_code" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_domain_name": { - "$ref": "#/definitions/forward_domain_name" - }, - "preserve_path": { - "$ref": "#/definitions/preserve_path" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_subdomains" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Redirection Hosts", - "href": "/nginx/redirection-hosts", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new Redirection Host", - "href": "/nginx/redirection-hosts", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "domain_names", - "forward_scheme", - "forward_http_code", - "forward_domain_name" - ], - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_http_code": { - "$ref": "#/definitions/forward_http_code" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_domain_name": { - "$ref": "#/definitions/forward_domain_name" - }, - "preserve_path": { - "$ref": "#/definitions/preserve_path" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing Redirection Host", - "href": "/nginx/redirection-hosts/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "domain_names": { - "$ref": "#/definitions/domain_names" - }, - "forward_http_code": { - "$ref": "#/definitions/forward_http_code" - }, - "forward_scheme": { - "$ref": "#/definitions/forward_scheme" - }, - "forward_domain_name": { - "$ref": "#/definitions/forward_domain_name" - }, - "preserve_path": { - "$ref": "#/definitions/preserve_path" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "ssl_forced": { - "$ref": "#/definitions/ssl_forced" - }, - "hsts_enabled": { - "$ref": "#/definitions/hsts_enabled" - }, - "hsts_subdomains": { - "$ref": "#/definitions/hsts_enabled" - }, - "http2_support": { - "$ref": "#/definitions/http2_support" - }, - "block_exploits": { - "$ref": "#/definitions/block_exploits" - }, - "advanced_config": { - "$ref": "#/definitions/advanced_config" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing Redirection Host", - "href": "/nginx/redirection-hosts/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Enable", - "description": "Enables a existing Redirection Host", - "href": "/nginx/redirection-hosts/{definitions.identity.example}/enable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Disable", - "description": "Disables a existing Redirection Host", - "href": "/nginx/redirection-hosts/{definitions.identity.example}/disable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - } - ] -} diff --git a/backend/schema/endpoints/settings.json b/backend/schema/endpoints/settings.json deleted file mode 100644 index 29e2865ae8..0000000000 --- a/backend/schema/endpoints/settings.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/settings", - "title": "Settings", - "description": "Endpoints relating to Settings", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/setting_id" - }, - "name": { - "description": "Name", - "example": "Default Site", - "type": "string", - "minLength": 2, - "maxLength": 100 - }, - "description": { - "description": "Description", - "example": "Default Site", - "type": "string", - "minLength": 2, - "maxLength": 255 - }, - "value": { - "description": "Value", - "example": "404", - "type": "string", - "maxLength": 255 - }, - "meta": { - "type": "object" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Settings", - "href": "/settings", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing Setting", - "href": "/settings/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "properties": { - "value": { - "$ref": "#/definitions/value" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - } - ], - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "name": { - "$ref": "#/definitions/description" - }, - "description": { - "$ref": "#/definitions/description" - }, - "value": { - "$ref": "#/definitions/value" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } -} diff --git a/backend/schema/endpoints/streams.json b/backend/schema/endpoints/streams.json deleted file mode 100644 index 7d97d2ab58..0000000000 --- a/backend/schema/endpoints/streams.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/streams", - "title": "Streams", - "description": "Endpoints relating to Streams", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "incoming_port": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "forwarding_host": { - "anyOf": [ - { - "$ref": "../definitions.json#/definitions/domain_name" - }, - { - "type": "string", - "format": "ipv4" - }, - { - "type": "string", - "format": "ipv6" - } - ] - }, - "forwarding_port": { - "type": "integer", - "minimum": 1, - "maximum": 65535 - }, - "tcp_forwarding": { - "type": "boolean" - }, - "udp_forwarding": { - "type": "boolean" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "../definitions.json#/definitions/certificate_id" - }, - "enabled": { - "$ref": "../definitions.json#/definitions/enabled" - }, - "meta": { - "type": "object" - } - }, - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "incoming_port": { - "$ref": "#/definitions/incoming_port" - }, - "forwarding_host": { - "$ref": "#/definitions/forwarding_host" - }, - "forwarding_port": { - "$ref": "#/definitions/forwarding_port" - }, - "tcp_forwarding": { - "$ref": "#/definitions/tcp_forwarding" - }, - "udp_forwarding": { - "$ref": "#/definitions/udp_forwarding" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "enabled": { - "$ref": "#/definitions/enabled" - }, - "meta": { - "$ref": "#/definitions/meta" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Steams", - "href": "/nginx/streams", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new Stream", - "href": "/nginx/streams", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "incoming_port", - "forwarding_host", - "forwarding_port" - ], - "properties": { - "incoming_port": { - "$ref": "#/definitions/incoming_port" - }, - "forwarding_host": { - "$ref": "#/definitions/forwarding_host" - }, - "forwarding_port": { - "$ref": "#/definitions/forwarding_port" - }, - "tcp_forwarding": { - "$ref": "#/definitions/tcp_forwarding" - }, - "udp_forwarding": { - "$ref": "#/definitions/udp_forwarding" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing Stream", - "href": "/nginx/streams/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "incoming_port": { - "$ref": "#/definitions/incoming_port" - }, - "forwarding_host": { - "$ref": "#/definitions/forwarding_host" - }, - "forwarding_port": { - "$ref": "#/definitions/forwarding_port" - }, - "tcp_forwarding": { - "$ref": "#/definitions/tcp_forwarding" - }, - "udp_forwarding": { - "$ref": "#/definitions/udp_forwarding" - }, - "domain_names": { - "$ref": "../definitions.json#/definitions/domain_names" - }, - "certificate_id": { - "$ref": "#/definitions/certificate_id" - }, - "meta": { - "$ref": "#/definitions/meta" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing Stream", - "href": "/nginx/streams/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Enable", - "description": "Enables a existing Stream", - "href": "/nginx/streams/{definitions.identity.example}/enable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Disable", - "description": "Disables a existing Stream", - "href": "/nginx/streams/{definitions.identity.example}/disable", - "access": "private", - "method": "POST", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - } - ] -} diff --git a/backend/schema/endpoints/tokens.json b/backend/schema/endpoints/tokens.json deleted file mode 100644 index 920af63f4a..0000000000 --- a/backend/schema/endpoints/tokens.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/tokens", - "title": "Token", - "description": "Tokens are required to authenticate against the API", - "stability": "stable", - "type": "object", - "definitions": { - "identity": { - "description": "Email Address or other 3rd party providers identifier", - "example": "john@example.com", - "type": "string" - }, - "secret": { - "description": "A password or key", - "example": "correct horse battery staple", - "type": "string" - }, - "token": { - "description": "JWT", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.O_frfYM8RzmRsUNigHtu0_jZ_utSejyr1axMGa8rlsk", - "type": "string" - }, - "expires": { - "description": "Token expiry time", - "format": "date-time", - "type": "string" - }, - "scope": { - "description": "Scope of the Token, defaults to 'user'", - "example": "user", - "type": "string" - } - }, - "links": [ - { - "title": "Create", - "description": "Creates a new token.", - "href": "/tokens", - "access": "public", - "method": "POST", - "rel": "create", - "schema": { - "type": "object", - "required": [ - "identity", - "secret" - ], - "properties": { - "identity": { - "$ref": "#/definitions/identity" - }, - "secret": { - "$ref": "#/definitions/secret" - }, - "scope": { - "$ref": "#/definitions/scope" - } - } - }, - "targetSchema": { - "type": "object", - "properties": { - "token": { - "$ref": "#/definitions/token" - }, - "expires": { - "$ref": "#/definitions/expires" - } - } - } - }, - { - "title": "Refresh", - "description": "Returns a new token.", - "href": "/tokens", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": {}, - "targetSchema": { - "type": "object", - "properties": { - "token": { - "$ref": "#/definitions/token" - }, - "expires": { - "$ref": "#/definitions/expires" - }, - "scope": { - "$ref": "#/definitions/scope" - } - } - } - } - ] -} diff --git a/backend/schema/endpoints/users.json b/backend/schema/endpoints/users.json deleted file mode 100644 index 42f44eac7c..0000000000 --- a/backend/schema/endpoints/users.json +++ /dev/null @@ -1,287 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "endpoints/users", - "title": "Users", - "description": "Endpoints relating to Users", - "stability": "stable", - "type": "object", - "definitions": { - "id": { - "$ref": "../definitions.json#/definitions/id" - }, - "created_on": { - "$ref": "../definitions.json#/definitions/created_on" - }, - "modified_on": { - "$ref": "../definitions.json#/definitions/modified_on" - }, - "name": { - "description": "Name", - "example": "Jamie Curnow", - "type": "string", - "minLength": 2, - "maxLength": 100 - }, - "nickname": { - "description": "Nickname", - "example": "Jamie", - "type": "string", - "minLength": 2, - "maxLength": 50 - }, - "email": { - "$ref": "../definitions.json#/definitions/email" - }, - "avatar": { - "description": "Avatar", - "example": "http://somewhere.jpg", - "type": "string", - "minLength": 2, - "maxLength": 150, - "readOnly": true - }, - "roles": { - "description": "Roles", - "example": [ - "admin" - ], - "type": "array" - }, - "is_disabled": { - "description": "Is Disabled", - "example": false, - "type": "boolean" - } - }, - "links": [ - { - "title": "List", - "description": "Returns a list of Users", - "href": "/users", - "access": "private", - "method": "GET", - "rel": "self", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "array", - "items": { - "$ref": "#/properties" - } - } - }, - { - "title": "Create", - "description": "Creates a new User", - "href": "/users", - "access": "private", - "method": "POST", - "rel": "create", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "required": [ - "name", - "nickname", - "email" - ], - "properties": { - "name": { - "$ref": "#/definitions/name" - }, - "nickname": { - "$ref": "#/definitions/nickname" - }, - "email": { - "$ref": "#/definitions/email" - }, - "roles": { - "$ref": "#/definitions/roles" - }, - "is_disabled": { - "$ref": "#/definitions/is_disabled" - }, - "auth": { - "type": "object", - "description": "Auth Credentials", - "example": { - "type": "password", - "secret": "bigredhorsebanana" - } - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Update", - "description": "Updates a existing User", - "href": "/users/{definitions.identity.example}", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "properties": { - "name": { - "$ref": "#/definitions/name" - }, - "nickname": { - "$ref": "#/definitions/nickname" - }, - "email": { - "$ref": "#/definitions/email" - }, - "roles": { - "$ref": "#/definitions/roles" - }, - "is_disabled": { - "$ref": "#/definitions/is_disabled" - } - } - }, - "targetSchema": { - "properties": { - "$ref": "#/properties" - } - } - }, - { - "title": "Delete", - "description": "Deletes a existing User", - "href": "/users/{definitions.identity.example}", - "access": "private", - "method": "DELETE", - "rel": "delete", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Set Password", - "description": "Sets a password for an existing User", - "href": "/users/{definitions.identity.example}/auth", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "required": [ - "type", - "secret" - ], - "properties": { - "type": { - "type": "string", - "pattern": "^password$" - }, - "current": { - "type": "string", - "minLength": 1, - "maxLength": 64 - }, - "secret": { - "type": "string", - "minLength": 8, - "maxLength": 64 - } - } - }, - "targetSchema": { - "type": "boolean" - } - }, - { - "title": "Set Permissions", - "description": "Sets Permissions for a User", - "href": "/users/{definitions.identity.example}/permissions", - "access": "private", - "method": "PUT", - "rel": "update", - "http_header": { - "$ref": "../examples.json#/definitions/auth_header" - }, - "schema": { - "type": "object", - "properties": { - "visibility": { - "type": "string", - "pattern": "^(all|user)$" - }, - "access_lists": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - }, - "dead_hosts": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - }, - "proxy_hosts": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - }, - "redirection_hosts": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - }, - "streams": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - }, - "certificates": { - "type": "string", - "pattern": "^(hidden|view|manage)$" - } - } - }, - "targetSchema": { - "type": "boolean" - } - } - ], - "properties": { - "id": { - "$ref": "#/definitions/id" - }, - "created_on": { - "$ref": "#/definitions/created_on" - }, - "modified_on": { - "$ref": "#/definitions/modified_on" - }, - "name": { - "$ref": "#/definitions/name" - }, - "nickname": { - "$ref": "#/definitions/nickname" - }, - "email": { - "$ref": "#/definitions/email" - }, - "avatar": { - "$ref": "#/definitions/avatar" - }, - "roles": { - "$ref": "#/definitions/roles" - }, - "is_disabled": { - "$ref": "#/definitions/is_disabled" - } - } -} diff --git a/backend/schema/examples.json b/backend/schema/examples.json deleted file mode 100644 index 37bc6c4d3b..0000000000 --- a/backend/schema/examples.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "examples", - "type": "object", - "definitions": { - "name": { - "description": "Name", - "example": "John Smith", - "type": "string", - "minLength": 1, - "maxLength": 255 - }, - "auth_header": { - "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.O_frfYM8RzmRsUNigHtu0_jZ_utSejyr1axMGa8rlsk", - "X-API-Version": "next" - }, - "token": { - "type": "string", - "description": "JWT", - "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.O_frfYM8RzmRsUNigHtu0_jZ_utSejyr1axMGa8rlsk" - } - } -} diff --git a/backend/schema/index.js b/backend/schema/index.js new file mode 100644 index 0000000000..87b75f2570 --- /dev/null +++ b/backend/schema/index.js @@ -0,0 +1,41 @@ +const refParser = require('@apidevtools/json-schema-ref-parser'); + +let compiledSchema = null; + +module.exports = { + + /** + * Compiles the schema, by dereferencing it, only once + * and returns the memory cached value + */ + getCompiledSchema: async () => { + if (compiledSchema === null) { + compiledSchema = await refParser.dereference(__dirname + '/swagger.json', { + mutateInputSchema: false, + }); + } + return compiledSchema; + }, + + /** + * Scans the schema for the validation schema for the given path and method + * and returns it. + * + * @param {string} path + * @param {string} method + * @returns string|null + */ + getValidationSchema: (path, method) => { + if (compiledSchema !== null && + typeof compiledSchema.paths[path] !== 'undefined' && + typeof compiledSchema.paths[path][method] !== 'undefined' && + typeof compiledSchema.paths[path][method].requestBody !== 'undefined' && + typeof compiledSchema.paths[path][method].requestBody.content !== 'undefined' && + typeof compiledSchema.paths[path][method].requestBody.content['application/json'] !== 'undefined' && + typeof compiledSchema.paths[path][method].requestBody.content['application/json'].schema !== 'undefined' + ) { + return compiledSchema.paths[path][method].requestBody.content['application/json'].schema; + } + return null; + } +}; diff --git a/backend/schema/index.json b/backend/schema/index.json deleted file mode 100644 index 6e7d1c8af9..0000000000 --- a/backend/schema/index.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "root", - "title": "Nginx Proxy Manager REST API", - "description": "This is the Nginx Proxy Manager REST API", - "version": "2.0.0", - "links": [ - { - "href": "http://npm.example.com/api", - "rel": "self" - } - ], - "properties": { - "tokens": { - "$ref": "endpoints/tokens.json" - }, - "users": { - "$ref": "endpoints/users.json" - }, - "proxy-hosts": { - "$ref": "endpoints/proxy-hosts.json" - }, - "redirection-hosts": { - "$ref": "endpoints/redirection-hosts.json" - }, - "dead-hosts": { - "$ref": "endpoints/dead-hosts.json" - }, - "streams": { - "$ref": "endpoints/streams.json" - }, - "certificates": { - "$ref": "endpoints/certificates.json" - }, - "access-lists": { - "$ref": "endpoints/access-lists.json" - }, - "settings": { - "$ref": "endpoints/settings.json" - } - } -} diff --git a/backend/schema/paths/audit-log/get.json b/backend/schema/paths/audit-log/get.json new file mode 100644 index 0000000000..bc43e29ddc --- /dev/null +++ b/backend/schema/paths/audit-log/get.json @@ -0,0 +1,53 @@ +{ + "operationId": "getAuditLog", + "summary": "Get Audit Log", + "tags": ["Audit Log"], + "security": [ + { + "BearerAuth": ["audit-log"] + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 7, + "created_on": "2024-10-08T13:09:54.000Z", + "modified_on": "2024-10-08T13:09:54.000Z", + "user_id": 1, + "object_type": "user", + "object_id": 3, + "action": "updated", + "meta": { + "name": "John Doe", + "permissions": { + "user_id": 3, + "visibility": "all", + "access_lists": "manage", + "dead_hosts": "hidden", + "proxy_hosts": "manage", + "redirection_hosts": "view", + "streams": "hidden", + "certificates": "manage", + "id": 3, + "modified_on": "2024-10-08T13:09:54.000Z", + "created_on": "2024-10-08T13:09:51.000Z" + } + } + } + ] + } + }, + "schema": { + "$ref": "../../components/audit-log-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/get.json b/backend/schema/paths/get.json new file mode 100644 index 0000000000..8c3a4e025f --- /dev/null +++ b/backend/schema/paths/get.json @@ -0,0 +1,29 @@ +{ + "operationId": "health", + "summary": "Returns the API health status", + "tags": ["Public"], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "status": "OK", + "version": { + "major": 2, + "minor": 1, + "revision": 0 + } + } + } + }, + "schema": { + "$ref": "../components/health-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/access-lists/get.json b/backend/schema/paths/nginx/access-lists/get.json new file mode 100644 index 0000000000..a8b9adc699 --- /dev/null +++ b/backend/schema/paths/nginx/access-lists/get.json @@ -0,0 +1,50 @@ +{ + "operationId": "getAccessLists", + "summary": "Get all access lists", + "tags": ["Access Lists"], + "security": [ + { + "BearerAuth": ["access_lists"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["owner", "items", "clients", "proxy_hosts"] + } + } + ], + "responses": { + "200": { + "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 + } + ] + } + }, + "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 new file mode 100644 index 0000000000..073585c8bd --- /dev/null +++ b/backend/schema/paths/nginx/access-lists/listID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteAccessList", + "summary": "Delete a Access List", + "tags": ["Access Lists"], + "security": [ + { + "BearerAuth": ["access_lists"] + } + ], + "parameters": [ + { + "in": "path", + "name": "listID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/access-lists/listID/get.json b/backend/schema/paths/nginx/access-lists/listID/get.json new file mode 100644 index 0000000000..e67023f89d --- /dev/null +++ b/backend/schema/paths/nginx/access-lists/listID/get.json @@ -0,0 +1,49 @@ +{ + "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" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/access-lists/listID/put.json b/backend/schema/paths/nginx/access-lists/listID/put.json new file mode 100644 index 0000000000..3a69f85674 --- /dev/null +++ b/backend/schema/paths/nginx/access-lists/listID/put.json @@ -0,0 +1,164 @@ +{ + "operationId": "updateAccessList", + "summary": "Update a Access List", + "tags": ["Access Lists"], + "security": [ + { + "BearerAuth": ["access_lists"] + } + ], + "parameters": [ + { + "in": "path", + "name": "listID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "requestBody": { + "description": "Access List Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "name": { + "$ref": "../../../../components/access-list-object.json#/properties/name" + }, + "satisfy_any": { + "$ref": "../../../../components/access-list-object.json#/properties/satisfy_any" + }, + "pass_auth": { + "$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 + } + } + } + }, + "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" + } + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:34:34.000Z", + "owner_user_id": 1, + "name": "test123!!", + "meta": {}, + "satisfy_any": true, + "pass_auth": false, + "proxy_host_count": 0, + "owner": { + "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"] + }, + "items": [ + { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "username": "admin", + "password": "", + "meta": {}, + "hint": "a****" + }, + { + "id": 2, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "username": "asdad", + "password": "", + "meta": {}, + "hint": "a*****" + } + ], + "clients": [ + { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "address": "127.0.0.1", + "directive": "allow", + "meta": {} + } + ], + "proxy_hosts": [] + } + } + }, + "schema": { + "$ref": "../../../../components/access-list-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/access-lists/post.json b/backend/schema/paths/nginx/access-lists/post.json new file mode 100644 index 0000000000..4c5a4edd29 --- /dev/null +++ b/backend/schema/paths/nginx/access-lists/post.json @@ -0,0 +1,155 @@ +{ + "operationId": "createAccessList", + "summary": "Create a Access List", + "tags": ["Access Lists"], + "security": [ + { + "BearerAuth": ["access_lists"] + } + ], + "requestBody": { + "description": "Access List Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["name"], + "properties": { + "name": { + "$ref": "../../../components/access-list-object.json#/properties/name" + }, + "satisfy_any": { + "$ref": "../../../components/access-list-object.json#/properties/satisfy_any" + }, + "pass_auth": { + "$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 + } + } + } + }, + "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" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 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, + "owner": { + "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"] + }, + "items": [ + { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "username": "admin", + "password": "", + "meta": {}, + "hint": "a****" + }, + { + "id": 2, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "username": "asdad", + "password": "", + "meta": {}, + "hint": "a*****" + } + ], + "proxy_hosts": [], + "clients": [ + { + "id": 1, + "created_on": "2024-10-08T22:15:40.000Z", + "modified_on": "2024-10-08T22:15:40.000Z", + "access_list_id": 1, + "address": "127.0.0.1", + "directive": "allow", + "meta": {} + } + ] + } + } + }, + "schema": { + "$ref": "../../../components/access-list-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/certID/delete.json b/backend/schema/paths/nginx/certificates/certID/delete.json new file mode 100644 index 0000000000..0d40bcb8c4 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/certID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteCertificate", + "summary": "Delete a Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "path", + "name": "certID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/certID/download/get.json b/backend/schema/paths/nginx/certificates/certID/download/get.json new file mode 100644 index 0000000000..4b858cae75 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/certID/download/get.json @@ -0,0 +1,35 @@ +{ + "operationId": "downloadCertificate", + "summary": "Downloads a Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "path", + "name": "certID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/zip": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/certID/get.json b/backend/schema/paths/nginx/certificates/certID/get.json new file mode 100644 index 0000000000..22317b337f --- /dev/null +++ b/backend/schema/paths/nginx/certificates/certID/get.json @@ -0,0 +1,53 @@ +{ + "operationId": "getCertificate", + "summary": "Get a Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "path", + "name": "certID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 4, + "created_on": "2024-10-09T05:31:58.000Z", + "modified_on": "2024-10-09T05:32:11.000Z", + "owner_user_id": 1, + "provider": "letsencrypt", + "nice_name": "test.example.com", + "domain_names": ["test.example.com"], + "expires_on": "2025-01-07T04:34:18.000Z", + "meta": { + "letsencrypt_email": "jc@jc21.com", + "letsencrypt_agree": true, + "dns_challenge": false + } + } + } + }, + "schema": { + "$ref": "../../../../components/certificate-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/certID/renew/post.json b/backend/schema/paths/nginx/certificates/certID/renew/post.json new file mode 100644 index 0000000000..ef4d20e5b1 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/certID/renew/post.json @@ -0,0 +1,54 @@ +{ + "operationId": "renewCertificate", + "summary": "Renews a Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "path", + "name": "certID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "expires_on": "2025-01-07T06:41:58.000Z", + "modified_on": "2024-10-09T07:39:51.000Z", + "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"], + "meta": { + "letsencrypt_email": "jc@jc21.com", + "letsencrypt_agree": true, + "dns_challenge": false + } + } + } + }, + "schema": { + "$ref": "../../../../../components/certificate-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/certID/upload/post.json b/backend/schema/paths/nginx/certificates/certID/upload/post.json new file mode 100644 index 0000000000..f38b8102a4 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/certID/upload/post.json @@ -0,0 +1,82 @@ +{ + "operationId": "uploadCertificate", + "summary": "Uploads a custom Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "path", + "name": "certID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "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" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEYDCCAsigAwIBAgIRAPoSC0hvitb26ODMlsH6YbowDQYJKoZIhvcNAQELBQAw\ngZExHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTEzMDEGA1UECwwqamN1\ncm5vd0BKYW1pZXMtTGFwdG9wLmxvY2FsIChKYW1pZSBDdXJub3cpMTowOAYDVQQD\nDDFta2NlcnQgamN1cm5vd0BKYW1pZXMtTGFwdG9wLmxvY2FsIChKYW1pZSBDdXJu\nb3cpMB4XDTI0MTAwOTA3MjIxN1oXDTI3MDEwOTA3MjIxN1owXjEnMCUGA1UEChMe\nbWtjZXJ0IGRldmVsb3BtZW50IGNlcnRpZmljYXRlMTMwMQYDVQQLDCpqY3Vybm93\nQEphbWllcy1MYXB0b3AubG9jYWwgKEphbWllIEN1cm5vdykwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQC1n9j9C5Bes1ndqACDckERauxXVNKCnUlUM1bu\nGBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2wrbmvZvLuPmXePOKbIKS+XXh+\n2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHgeYz6Cv/Si2/LJPCh/CoBfM4hU\nQJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQoxRAHiOR9081Xn1WeoKr7kVB\nIa5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7ZEo+nS8Wr/4QWicatIWZXpVaE\nOPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79XzGONeH1PAgMBAAGjZTBjMA4G\nA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBSB\n/vfmBUd4W7CvyEMl7YpMVQs8vTAbBgNVHREEFDASghB0ZXN0LmV4YW1wbGUuY29t\nMA0GCSqGSIb3DQEBCwUAA4IBgQASwON/jPAHzcARSenY0ZGY1m5OVTYoQ/JWH0oy\nl8SyFCQFEXt7UHDD/eTtLT0vMyc190nP57P8lTnZGf7hSinZz1B1d6V4cmzxpk0s\nVXZT+irL6bJVJoMBHRpllKAhGULIo33baTrWFKA0oBuWx4AevSWKcLW5j87kEawn\nATCuMQ1I3ifR1mSlB7X8fb+vF+571q0NGuB3a42j6rdtXJ6SmH4+9B4qO0sfHDNt\nIImpLCH/tycDpcYrGSCn1QrekFG1bSEh+Bb9i8rqMDSDsYrTFPZTuOQ3EtjGni9u\nm+rEP3OyJg+md8c+0LVP7/UU4QWWnw3/Wolo5kSCxE8vNTFqi4GhVbdLnUtcIdTV\nXxuR6cKyW87Snj1a0nG76ZLclt/akxDhtzqeV60BO0p8pmiev8frp+E94wFNYCmp\n1cr3CnMEGRaficLSDFC6EBENzlZW2BQT6OMIV+g0NBgSyQe39s2zcdEl5+SzDVuw\nhp8bJUp/QN7pnOVCDbjTQ+HVMXw=\n-----END CERTIFICATE-----\n", + "certificate_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1n9j9C5Bes1nd\nqACDckERauxXVNKCnUlUM1buGBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2w\nrbmvZvLuPmXePOKbIKS+XXh+2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHge\nYz6Cv/Si2/LJPCh/CoBfM4hUQJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQ\noxRAHiOR9081Xn1WeoKr7kVBIa5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7Z\nEo+nS8Wr/4QWicatIWZXpVaEOPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79X\nzGONeH1PAgMBAAECggEAANb3Wtwl07pCjRrMvc7WbC0xYIn82yu8/g2qtjkYUJcU\nia5lQbYN7RGCS85Oc/tkq48xQEG5JQWNH8b918jDEMTrFab0aUEyYcru1q9L8PL6\nYHaNgZSrMrDcHcS8h0QOXNRJT5jeGkiHJaTR0irvB526tqF3knbK9yW22KTfycUe\na0Z9voKn5xRk1DCbHi/nk2EpT7xnjeQeLFaTIRXbS68omkr4YGhwWm5OizoyEGZu\nW0Zum5BkQyMr6kor3wdxOTG97ske2rcyvvHi+ErnwL0xBv0qY0Dhe8DpuXpDezqw\no72yY8h31Fu84i7sAj24YuE5Df8DozItFXQpkgbQ6QKBgQDPrufhvIFm2S/MzBdW\nH8JxY7CJlJPyxOvc1NIl9RczQGAQR90kx52cgIcuIGEG6/wJ/xnGfMmW40F0DnQ+\nN+oLgB9SFxeLkRb7s9Z/8N3uIN8JJFYcerEOiRQeN2BXEEWJ7bUThNtsVrAcKoUh\nELsDmnHW/3V+GKwhd0vpk842+wKBgQDf4PGLG9PTE5tlAoyHFodJRd2RhTJQkwsU\nMDNjLJ+KecLv+Nl+QiJhoflG1ccqtSFlBSCG067CDQ5LV0xm3mLJ7pfJoMgjcq31\nqjEmX4Ls91GuVOPtbwst3yFKjsHaSoKB5fBvWRcKFpBUezM7Qcw2JP3+dQT+bQIq\ncMTkRWDSvQKBgQDOdCQFDjxg/lR7NQOZ1PaZe61aBz5P3pxNqa7ClvMaOsuEQ7w9\nvMYcdtRq8TsjA2JImbSI0TIg8gb2FQxPcYwTJKl+FICOeIwtaSg5hTtJZpnxX5LO\nutTaC0DZjNkTk5RdOdWA8tihyUdGqKoxJY2TVmwGe2rUEDjFB++J4inkEwKBgB6V\ng0nmtkxanFrzOzFlMXwgEEHF+Xaqb9QFNa/xs6XeNnREAapO7JV75Cr6H2hFMFe1\nmJjyqCgYUoCWX3iaHtLJRnEkBtNY4kzyQB6m46LtsnnnXO/dwKA2oDyoPfFNRoDq\nYatEd3JIXNU9s2T/+x7WdOBjKhh72dTkbPFmTPDdAoGAU6rlPBevqOFdObYxdPq8\nEQWu44xqky3Mf5sBpOwtu6rqCYuziLiN7K4sjN5GD5mb1cEU+oS92ZiNcUQ7MFXk\n8yTYZ7U0VcXyAcpYreWwE8thmb0BohJBr+Mp3wLTx32x0HKdO6vpUa0d35LUTUmM\nRrKmPK/msHKK/sVHiL+NFqo=\n-----END PRIVATE KEY-----\n" + } + } + }, + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["certificate", "certificate_key"], + "properties": { + "certificate": { + "type": "string", + "minLength": 1 + }, + "certificate_key": { + "type": "string", + "minLength": 1 + }, + "intermediate_certificate": { + "type": "string", + "minLength": 1 + } + } + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/get.json b/backend/schema/paths/nginx/certificates/get.json new file mode 100644 index 0000000000..2f4b556afe --- /dev/null +++ b/backend/schema/paths/nginx/certificates/get.json @@ -0,0 +1,54 @@ +{ + "operationId": "getCertificates", + "summary": "Get all certificates", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["owner"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 4, + "created_on": "2024-10-09T05:31:58.000Z", + "modified_on": "2024-10-09T05:32:11.000Z", + "owner_user_id": 1, + "provider": "letsencrypt", + "nice_name": "test.example.com", + "domain_names": ["test.example.com"], + "expires_on": "2025-01-07T04:34:18.000Z", + "meta": { + "letsencrypt_email": "jc@jc21.com", + "letsencrypt_agree": true, + "dns_challenge": false + } + } + ] + } + }, + "schema": { + "$ref": "../../../components/certificate-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/post.json b/backend/schema/paths/nginx/certificates/post.json new file mode 100644 index 0000000000..5a3306c22f --- /dev/null +++ b/backend/schema/paths/nginx/certificates/post.json @@ -0,0 +1,97 @@ +{ + "operationId": "createCertificate", + "summary": "Create a Certificate", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "requestBody": { + "description": "Certificate Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["provider"], + "properties": { + "provider": { + "$ref": "../../../components/certificate-object.json#/properties/provider" + }, + "nice_name": { + "$ref": "../../../components/certificate-object.json#/properties/nice_name" + }, + "domain_names": { + "$ref": "../../../components/certificate-object.json#/properties/domain_names" + }, + "meta": { + "$ref": "../../../components/certificate-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "expires_on": "2025-01-07 04:30:17", + "modified_on": "2024-10-09 05:28:51", + "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"], + "meta": { + "letsencrypt_email": "jc@jc21.com", + "letsencrypt_agree": true, + "dns_challenge": false, + "letsencrypt_certificate": { + "cn": "test.example.com", + "issuer": "C = US, O = Let's Encrypt, CN = E5", + "dates": { + "from": 1728448218, + "to": 1736224217 + } + } + } + } + } + }, + "schema": { + "$ref": "../../../components/certificate-object.json" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Domains are invalid" + } + } + } + }, + "schema": { + "$ref": "../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/test-http/get.json b/backend/schema/paths/nginx/certificates/test-http/get.json new file mode 100644 index 0000000000..2b9a8dd3b0 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/test-http/get.json @@ -0,0 +1,40 @@ +{ + "operationId": "testHttpReach", + "summary": "Test HTTP Reachability", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "parameters": [ + { + "in": "query", + "name": "domains", + "description": "Expansions", + "required": true, + "schema": { + "type": "string", + "example": "[\"test.example.ord\",\"test.example.com\",\"nonexistent.example.com\"]" + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "test.example.org": "ok", + "test.example.com": "other:Invalid domain or IP", + "nonexistent.example.com": "404" + } + } + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/certificates/validate/post.json b/backend/schema/paths/nginx/certificates/validate/post.json new file mode 100644 index 0000000000..21eb325ef2 --- /dev/null +++ b/backend/schema/paths/nginx/certificates/validate/post.json @@ -0,0 +1,114 @@ +{ + "operationId": "validateCertificates", + "summary": "Validates given Custom Certificates", + "tags": ["Certificates"], + "security": [ + { + "BearerAuth": ["certificates"] + } + ], + "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" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "certificate": { + "cn": "mkcert", + "issuer": "O = mkcert development CA, OU = jc@jc-Laptop.local (John Doe), CN = mkcert jc@jc-Laptop.local (John Doe)", + "dates": { + "from": 1728458537, + "to": 1799479337 + } + }, + "certificate_key": true + } + } + }, + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["certificate", "certificate_key"], + "properties": { + "certificate": { + "type": "object", + "additionalProperties": false, + "required": ["cn", "issuer", "dates"], + "properties": { + "cn": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "dates": { + "type": "object", + "additionalProperties": false, + "required": ["from", "to"], + "properties": { + "from": { + "type": "integer" + }, + "to": { + "type": "integer" + } + } + } + } + }, + "certificate_key": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Certificate is not valid" + } + } + } + }, + "schema": { + "$ref": "../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/get.json b/backend/schema/paths/nginx/dead-hosts/get.json new file mode 100644 index 0000000000..8a11a3f66d --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/get.json @@ -0,0 +1,57 @@ +{ + "operationId": "getDeadHosts", + "summary": "Get all 404 hosts", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["owner", "certificate"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 1, + "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"], + "certificate_id": 0, + "ssl_forced": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false + } + ] + } + }, + "schema": { + "$ref": "../../../components/dead-host-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/delete.json b/backend/schema/paths/nginx/dead-hosts/hostID/delete.json new file mode 100644 index 0000000000..f3aa81a5b0 --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/hostID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteDeadHost", + "summary": "Delete a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json new file mode 100644 index 0000000000..2cdcecf4b4 --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/hostID/disable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "disableDeadHost", + "summary": "Disable a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already disabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json new file mode 100644 index 0000000000..ca3ce9faec --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/hostID/enable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "enableDeadHost", + "summary": "Enable a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already enabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/get.json b/backend/schema/paths/nginx/dead-hosts/hostID/get.json new file mode 100644 index 0000000000..47e2f8b125 --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/hostID/get.json @@ -0,0 +1,56 @@ +{ + "operationId": "getDeadHost", + "summary": "Get a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "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"], + "certificate_id": 0, + "ssl_forced": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false + } + } + }, + "schema": { + "$ref": "../../../../components/dead-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/hostID/put.json b/backend/schema/paths/nginx/dead-hosts/hostID/put.json new file mode 100644 index 0000000000..f9505ed48e --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/hostID/put.json @@ -0,0 +1,108 @@ +{ + "operationId": "updateDeadHost", + "summary": "Update a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "requestBody": { + "description": "404 Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "domain_names": { + "$ref": "../../../../components/dead-host-object.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../../../../components/dead-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../../components/dead-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../../components/dead-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../../components/dead-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../../components/dead-host-object.json#/properties/http2_support" + }, + "advanced_config": { + "$ref": "../../../../components/dead-host-object.json#/properties/advanced_config" + }, + "meta": { + "$ref": "../../../../components/dead-host-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T01:38:52.000Z", + "modified_on": "2024-10-09T01:46:06.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "certificate_id": 0, + "ssl_forced": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "owner": { + "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"] + }, + "certificate": null + } + } + }, + "schema": { + "$ref": "../../../../components/dead-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/dead-hosts/post.json b/backend/schema/paths/nginx/dead-hosts/post.json new file mode 100644 index 0000000000..c8bbb6932c --- /dev/null +++ b/backend/schema/paths/nginx/dead-hosts/post.json @@ -0,0 +1,93 @@ +{ + "operationId": "create404Host", + "summary": "Create a 404 Host", + "tags": ["404 Hosts"], + "security": [ + { + "BearerAuth": ["dead_hosts"] + } + ], + "requestBody": { + "description": "404 Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["domain_names"], + "properties": { + "domain_names": { + "$ref": "../../../components/dead-host-object.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../../../components/dead-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../components/dead-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../components/dead-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../components/dead-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../components/dead-host-object.json#/properties/http2_support" + }, + "advanced_config": { + "$ref": "../../../components/dead-host-object.json#/properties/advanced_config" + }, + "meta": { + "$ref": "../../../components/dead-host-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "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"], + "certificate_id": 0, + "ssl_forced": false, + "advanced_config": "", + "meta": {}, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "certificate": null, + "owner": { + "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"] + } + } + } + }, + "schema": { + "$ref": "../../../components/dead-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/get.json b/backend/schema/paths/nginx/proxy-hosts/get.json new file mode 100644 index 0000000000..1d9f633512 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/get.json @@ -0,0 +1,65 @@ +{ + "operationId": "getProxyHosts", + "summary": "Get all proxy hosts", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["access_list", "owner", "certificate"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 1, + "created_on": "2024-10-08T23:23:03.000Z", + "modified_on": "2024-10-08T23:23:04.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_host": "127.0.0.1", + "forward_port": 8989, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": false, + "caching_enabled": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "allow_websocket_upgrade": false, + "http2_support": false, + "forward_scheme": "http", + "enabled": true, + "locations": null, + "hsts_enabled": false, + "hsts_subdomains": false + } + ] + } + }, + "schema": { + "$ref": "../../../components/proxy-host-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json b/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json new file mode 100644 index 0000000000..991ef0e9e3 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteProxyHost", + "summary": "Delete a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json new file mode 100644 index 0000000000..54ff8a6632 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/disable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "disableProxyHost", + "summary": "Disable a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already disabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json new file mode 100644 index 0000000000..9f052de052 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/enable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "enableProxyHost", + "summary": "Enable a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already enabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/get.json b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json new file mode 100644 index 0000000000..5e10a9cfd1 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/get.json @@ -0,0 +1,64 @@ +{ + "operationId": "getProxyHost", + "summary": "Get a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-08T23:23:03.000Z", + "modified_on": "2024-10-08T23:26:38.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_host": "192.168.0.10", + "forward_port": 8989, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": false, + "caching_enabled": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "allow_websocket_upgrade": false, + "http2_support": false, + "forward_scheme": "http", + "enabled": true, + "locations": null, + "hsts_enabled": false, + "hsts_subdomains": false + } + } + }, + "schema": { + "$ref": "../../../../components/proxy-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json new file mode 100644 index 0000000000..5cab6e7520 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json @@ -0,0 +1,143 @@ +{ + "operationId": "updateProxyHost", + "summary": "Update a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "requestBody": { + "description": "Proxy Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "domain_names": { + "$ref": "../../../../components/proxy-host-object.json#/properties/domain_names" + }, + "forward_scheme": { + "$ref": "../../../../components/proxy-host-object.json#/properties/forward_scheme" + }, + "forward_host": { + "$ref": "../../../../components/proxy-host-object.json#/properties/forward_host" + }, + "forward_port": { + "$ref": "../../../../components/proxy-host-object.json#/properties/forward_port" + }, + "certificate_id": { + "$ref": "../../../../components/proxy-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../../components/proxy-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../../components/proxy-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../../components/proxy-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../../components/proxy-host-object.json#/properties/http2_support" + }, + "block_exploits": { + "$ref": "../../../../components/proxy-host-object.json#/properties/block_exploits" + }, + "caching_enabled": { + "$ref": "../../../../components/proxy-host-object.json#/properties/caching_enabled" + }, + "allow_websocket_upgrade": { + "$ref": "../../../../components/proxy-host-object.json#/properties/allow_websocket_upgrade" + }, + "access_list_id": { + "$ref": "../../../../components/proxy-host-object.json#/properties/access_list_id" + }, + "advanced_config": { + "$ref": "../../../../components/proxy-host-object.json#/properties/advanced_config" + }, + "enabled": { + "$ref": "../../../../components/proxy-host-object.json#/properties/enabled" + }, + "meta": { + "$ref": "../../../../components/proxy-host-object.json#/properties/meta" + }, + "locations": { + "$ref": "../../../../components/proxy-host-object.json#/properties/locations" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-08T23:23:03.000Z", + "modified_on": "2024-10-08T23:26:37.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_host": "192.168.0.10", + "forward_port": 8989, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": false, + "caching_enabled": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "allow_websocket_upgrade": false, + "http2_support": false, + "forward_scheme": "http", + "enabled": true, + "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, + "is_disabled": false, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "some guy", + "avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm", + "roles": ["admin"] + }, + "certificate": null, + "access_list": null + } + } + }, + "schema": { + "$ref": "../../../../components/proxy-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/proxy-hosts/post.json b/backend/schema/paths/nginx/proxy-hosts/post.json new file mode 100644 index 0000000000..85455fb6b6 --- /dev/null +++ b/backend/schema/paths/nginx/proxy-hosts/post.json @@ -0,0 +1,128 @@ +{ + "operationId": "createProxyHost", + "summary": "Create a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["proxy_hosts"] + } + ], + "requestBody": { + "description": "Proxy Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["domain_names", "forward_scheme", "forward_host", "forward_port"], + "properties": { + "domain_names": { + "$ref": "../../../components/proxy-host-object.json#/properties/domain_names" + }, + "forward_scheme": { + "$ref": "../../../components/proxy-host-object.json#/properties/forward_scheme" + }, + "forward_host": { + "$ref": "../../../components/proxy-host-object.json#/properties/forward_host" + }, + "forward_port": { + "$ref": "../../../components/proxy-host-object.json#/properties/forward_port" + }, + "certificate_id": { + "$ref": "../../../components/proxy-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../components/proxy-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../components/proxy-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../components/proxy-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../components/proxy-host-object.json#/properties/http2_support" + }, + "block_exploits": { + "$ref": "../../../components/proxy-host-object.json#/properties/block_exploits" + }, + "caching_enabled": { + "$ref": "../../../components/proxy-host-object.json#/properties/caching_enabled" + }, + "allow_websocket_upgrade": { + "$ref": "../../../components/proxy-host-object.json#/properties/allow_websocket_upgrade" + }, + "access_list_id": { + "$ref": "../../../components/proxy-host-object.json#/properties/access_list_id" + }, + "advanced_config": { + "$ref": "../../../components/proxy-host-object.json#/properties/advanced_config" + }, + "enabled": { + "$ref": "../../../components/proxy-host-object.json#/properties/enabled" + }, + "meta": { + "$ref": "../../../components/proxy-host-object.json#/properties/meta" + }, + "locations": { + "$ref": "../../../components/proxy-host-object.json#/properties/locations" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-08T23:23:03.000Z", + "modified_on": "2024-10-08T23:23:03.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_host": "127.0.0.1", + "forward_port": 8989, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": false, + "caching_enabled": false, + "block_exploits": false, + "advanced_config": "", + "meta": {}, + "allow_websocket_upgrade": false, + "http2_support": false, + "forward_scheme": "http", + "enabled": true, + "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, + "is_disabled": false, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "some guy", + "avatar": "//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?default=mm", + "roles": ["admin"] + }, + "access_list": null + } + } + }, + "schema": { + "$ref": "../../../components/proxy-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/get.json b/backend/schema/paths/nginx/redirection-hosts/get.json new file mode 100644 index 0000000000..0b35e0fc4a --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/get.json @@ -0,0 +1,62 @@ +{ + "operationId": "getRedirectionHosts", + "summary": "Get all Redirection hosts", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["owner", "certificate"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 1, + "created_on": "2024-10-09T01:13:12.000Z", + "modified_on": "2024-10-09T01:13:13.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_domain_name": "something-else.com", + "preserve_path": false, + "certificate_id": 0, + "ssl_forced": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "forward_scheme": "http", + "forward_http_code": 301 + } + ] + } + }, + "schema": { + "$ref": "../../../components/redirection-host-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json b/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json new file mode 100644 index 0000000000..7330f36239 --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteRedirectionHost", + "summary": "Delete a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json b/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json new file mode 100644 index 0000000000..8433220d5f --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/disable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "disableRedirectionHost", + "summary": "Disable a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already disabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json b/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json new file mode 100644 index 0000000000..bef53436b7 --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/enable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "enableRedirectionHost", + "summary": "Enable a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already enabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/get.json b/backend/schema/paths/nginx/redirection-hosts/hostID/get.json new file mode 100644 index 0000000000..d780f874b0 --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/get.json @@ -0,0 +1,61 @@ +{ + "operationId": "getRedirectionHost", + "summary": "Get a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 1 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T01:13:12.000Z", + "modified_on": "2024-10-09T01:13:13.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_domain_name": "something-else.com", + "preserve_path": false, + "certificate_id": 0, + "ssl_forced": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "forward_scheme": "http", + "forward_http_code": 301 + } + } + }, + "schema": { + "$ref": "../../../../components/redirection-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/hostID/put.json b/backend/schema/paths/nginx/redirection-hosts/hostID/put.json new file mode 100644 index 0000000000..fd97cbfa8f --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/hostID/put.json @@ -0,0 +1,128 @@ +{ + "operationId": "updateRedirectionHost", + "summary": "Update a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "parameters": [ + { + "in": "path", + "name": "hostID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "requestBody": { + "description": "Redirection Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "domain_names": { + "$ref": "../../../../components/redirection-host-object.json#/properties/domain_names" + }, + "forward_http_code": { + "$ref": "../../../../components/redirection-host-object.json#/properties/forward_http_code" + }, + "forward_scheme": { + "$ref": "../../../../components/redirection-host-object.json#/properties/forward_scheme" + }, + "forward_domain_name": { + "$ref": "../../../../components/redirection-host-object.json#/properties/forward_domain_name" + }, + "preserve_path": { + "$ref": "../../../../components/redirection-host-object.json#/properties/preserve_path" + }, + "certificate_id": { + "$ref": "../../../../components/redirection-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../../components/redirection-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../../components/redirection-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../../components/redirection-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../../components/redirection-host-object.json#/properties/http2_support" + }, + "block_exploits": { + "$ref": "../../../../components/redirection-host-object.json#/properties/block_exploits" + }, + "advanced_config": { + "$ref": "../../../../components/redirection-host-object.json#/properties/advanced_config" + }, + "meta": { + "$ref": "../../../../components/redirection-host-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T01:13:12.000Z", + "modified_on": "2024-10-09T01:18:11.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_domain_name": "something-else.com", + "preserve_path": false, + "certificate_id": 0, + "ssl_forced": false, + "block_exploits": false, + "advanced_config": "", + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "forward_scheme": "http", + "forward_http_code": 301, + "owner": { + "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"] + }, + "certificate": null + } + } + }, + "schema": { + "$ref": "../../../../components/redirection-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/redirection-hosts/post.json b/backend/schema/paths/nginx/redirection-hosts/post.json new file mode 100644 index 0000000000..5bfde2c388 --- /dev/null +++ b/backend/schema/paths/nginx/redirection-hosts/post.json @@ -0,0 +1,113 @@ +{ + "operationId": "createRedirectionHost", + "summary": "Create a Redirection Host", + "tags": ["Redirection Hosts"], + "security": [ + { + "BearerAuth": ["redirection_hosts"] + } + ], + "requestBody": { + "description": "Redirection Host Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["domain_names", "forward_scheme", "forward_http_code", "forward_domain_name"], + "properties": { + "domain_names": { + "$ref": "../../../components/redirection-host-object.json#/properties/domain_names" + }, + "forward_http_code": { + "$ref": "../../../components/redirection-host-object.json#/properties/forward_http_code" + }, + "forward_scheme": { + "$ref": "../../../components/redirection-host-object.json#/properties/forward_scheme" + }, + "forward_domain_name": { + "$ref": "../../../components/redirection-host-object.json#/properties/forward_domain_name" + }, + "preserve_path": { + "$ref": "../../../components/redirection-host-object.json#/properties/preserve_path" + }, + "certificate_id": { + "$ref": "../../../components/redirection-host-object.json#/properties/certificate_id" + }, + "ssl_forced": { + "$ref": "../../../components/redirection-host-object.json#/properties/ssl_forced" + }, + "hsts_enabled": { + "$ref": "../../../components/redirection-host-object.json#/properties/hsts_enabled" + }, + "hsts_subdomains": { + "$ref": "../../../components/redirection-host-object.json#/properties/hsts_subdomains" + }, + "http2_support": { + "$ref": "../../../components/redirection-host-object.json#/properties/http2_support" + }, + "block_exploits": { + "$ref": "../../../components/redirection-host-object.json#/properties/block_exploits" + }, + "advanced_config": { + "$ref": "../../../components/redirection-host-object.json#/properties/advanced_config" + }, + "meta": { + "$ref": "../../../components/redirection-host-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T01:13:12.000Z", + "modified_on": "2024-10-09T01:13:12.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_domain_name": "something-else.com", + "preserve_path": false, + "certificate_id": 0, + "ssl_forced": false, + "block_exploits": false, + "advanced_config": "", + "meta": {}, + "http2_support": false, + "enabled": true, + "hsts_enabled": false, + "hsts_subdomains": false, + "forward_scheme": "http", + "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, + "is_disabled": false, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "Admin", + "avatar": "", + "roles": ["admin"] + } + } + } + }, + "schema": { + "$ref": "../../../components/redirection-host-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/get.json b/backend/schema/paths/nginx/streams/get.json new file mode 100644 index 0000000000..596afc6e74 --- /dev/null +++ b/backend/schema/paths/nginx/streams/get.json @@ -0,0 +1,55 @@ +{ + "operationId": "getStreams", + "summary": "Get all streams", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["access_list", "owner", "certificate"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 1, + "created_on": "2024-10-09T02:33:45.000Z", + "modified_on": "2024-10-09T02:33:45.000Z", + "owner_user_id": 1, + "incoming_port": 9090, + "forwarding_host": "router.internal", + "forwarding_port": 80, + "tcp_forwarding": true, + "udp_forwarding": false, + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "enabled": true + } + ] + } + }, + "schema": { + "$ref": "../../../components/stream-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/post.json b/backend/schema/paths/nginx/streams/post.json new file mode 100644 index 0000000000..3e3cd55e67 --- /dev/null +++ b/backend/schema/paths/nginx/streams/post.json @@ -0,0 +1,95 @@ +{ + "operationId": "createStream", + "summary": "Create a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "requestBody": { + "description": "Stream Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["incoming_port", "forwarding_host", "forwarding_port"], + "properties": { + "incoming_port": { + "$ref": "../../../components/stream-object.json#/properties/incoming_port" + }, + "forwarding_host": { + "$ref": "../../../components/stream-object.json#/properties/forwarding_host" + }, + "forwarding_port": { + "$ref": "../../../components/stream-object.json#/properties/forwarding_port" + }, + "tcp_forwarding": { + "$ref": "../../../components/stream-object.json#/properties/tcp_forwarding" + }, + "udp_forwarding": { + "$ref": "../../../components/stream-object.json#/properties/udp_forwarding" + }, + "domain_names": { + "$ref": "../../../components/stream-object.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../../../components/stream-object.json#/properties/certificate_id" + }, + "meta": { + "$ref": "../../../components/stream-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T02:33:45.000Z", + "modified_on": "2024-10-09T02:33:45.000Z", + "owner_user_id": 1, + "incoming_port": 9090, + "forwarding_host": "router.internal", + "forwarding_port": 80, + "tcp_forwarding": true, + "udp_forwarding": false, + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "enabled": true, + "owner": { + "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"] + }, + "certificate_id": 0, + "certificate": null + } + } + }, + "schema": { + "$ref": "../../../components/stream-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/streamID/delete.json b/backend/schema/paths/nginx/streams/streamID/delete.json new file mode 100644 index 0000000000..3a96852582 --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/delete.json @@ -0,0 +1,39 @@ +{ + "operationId": "deleteStream", + "summary": "Delete a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "path", + "name": "streamID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/streamID/disable/post.json b/backend/schema/paths/nginx/streams/streamID/disable/post.json new file mode 100644 index 0000000000..d1c1b1c84a --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/disable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "disableStream", + "summary": "Disable a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "path", + "name": "streamID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already disabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/streamID/enable/post.json b/backend/schema/paths/nginx/streams/streamID/enable/post.json new file mode 100644 index 0000000000..dc914f5f27 --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/enable/post.json @@ -0,0 +1,59 @@ +{ + "operationId": "enableStream", + "summary": "Enable a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "path", + "name": "streamID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "400 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "error": { + "code": 400, + "message": "Host is already enabled" + } + } + } + }, + "schema": { + "$ref": "../../../../../components/error.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/streamID/get.json b/backend/schema/paths/nginx/streams/streamID/get.json new file mode 100644 index 0000000000..6547656dfc --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/get.json @@ -0,0 +1,54 @@ +{ + "operationId": "getStream", + "summary": "Get a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "path", + "name": "streamID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-09T02:33:45.000Z", + "modified_on": "2024-10-09T02:33:45.000Z", + "owner_user_id": 1, + "incoming_port": 9090, + "forwarding_host": "router.internal", + "forwarding_port": 80, + "tcp_forwarding": true, + "udp_forwarding": false, + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "enabled": true + } + } + }, + "schema": { + "$ref": "../../../../components/stream-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/nginx/streams/streamID/put.json b/backend/schema/paths/nginx/streams/streamID/put.json new file mode 100644 index 0000000000..8fa64cdf65 --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/put.json @@ -0,0 +1,107 @@ +{ + "operationId": "updateStream", + "summary": "Update a Stream", + "tags": ["Streams"], + "security": [ + { + "BearerAuth": ["streams"] + } + ], + "parameters": [ + { + "in": "path", + "name": "streamID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 2 + } + ], + "requestBody": { + "description": "Stream Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "incoming_port": { + "$ref": "../../../../components/stream-object.json#/properties/incoming_port" + }, + "forwarding_host": { + "$ref": "../../../../components/stream-object.json#/properties/forwarding_host" + }, + "forwarding_port": { + "$ref": "../../../../components/stream-object.json#/properties/forwarding_port" + }, + "tcp_forwarding": { + "$ref": "../../../../components/stream-object.json#/properties/tcp_forwarding" + }, + "udp_forwarding": { + "$ref": "../../../../components/stream-object.json#/properties/udp_forwarding" + }, + "domain_names": { + "$ref": "../../../../components/stream-object.json#/properties/domain_names" + }, + "certificate_id": { + "$ref": "../../../../components/stream-object.json#/properties/certificate_id" + }, + "meta": { + "$ref": "../../../../components/stream-object.json#/properties/meta" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 1, + "created_on": "2024-10-08T23:23:03.000Z", + "modified_on": "2024-10-08T23:26:37.000Z", + "owner_user_id": 1, + "incoming_port": 9090, + "forwarding_host": "router.internal", + "forwarding_port": 80, + "tcp_forwarding": true, + "udp_forwarding": false, + "meta": { + "nginx_online": true, + "nginx_err": null + }, + "enabled": true, + "owner": { + "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"] + }, + "certificate": null, + "access_list": null + } + } + }, + "schema": { + "$ref": "../../../../components/stream-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/reports/hosts/get.json b/backend/schema/paths/reports/hosts/get.json new file mode 100644 index 0000000000..a40ddc723c --- /dev/null +++ b/backend/schema/paths/reports/hosts/get.json @@ -0,0 +1,50 @@ +{ + "operationId": "reportsHosts", + "summary": "Report on Host Statistics", + "tags": ["Reports"], + "security": [ + { + "BearerAuth": ["reports"] + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "proxy": 20, + "redirection": 1, + "stream": 0, + "dead": 1 + } + } + }, + "schema": { + "type": "object", + "properties": { + "proxy": { + "type": "integer", + "description": "Proxy Hosts Count" + }, + "redirection": { + "type": "integer", + "description": "Redirection Hosts Count" + }, + "stream": { + "type": "integer", + "description": "Streams Count" + }, + "dead": { + "type": "integer", + "description": "404 Hosts Count" + } + } + } + } + } + } + } +} diff --git a/backend/schema/paths/schema/get.json b/backend/schema/paths/schema/get.json new file mode 100644 index 0000000000..d435b00429 --- /dev/null +++ b/backend/schema/paths/schema/get.json @@ -0,0 +1,10 @@ +{ + "operationId": "schema", + "summary": "Returns this swagger API schema", + "tags": ["Public"], + "responses": { + "200": { + "description": "200 response" + } + } +} diff --git a/backend/schema/paths/settings/get.json b/backend/schema/paths/settings/get.json new file mode 100644 index 0000000000..5d148d8af4 --- /dev/null +++ b/backend/schema/paths/settings/get.json @@ -0,0 +1,35 @@ +{ + "operationId": "getSettings", + "summary": "Get all settings", + "tags": ["Settings"], + "security": [ + { + "BearerAuth": ["settings"] + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": "default-site", + "name": "Default Site", + "description": "What to show when Nginx is hit with an unknown Host", + "value": "congratulations", + "meta": {} + } + ] + } + }, + "schema": { + "$ref": "../../components/setting-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/settings/settingID/get.json b/backend/schema/paths/settings/settingID/get.json new file mode 100644 index 0000000000..405b976d28 --- /dev/null +++ b/backend/schema/paths/settings/settingID/get.json @@ -0,0 +1,46 @@ +{ + "operationId": "getSetting", + "summary": "Get a setting", + "tags": ["Settings"], + "security": [ + { + "BearerAuth": ["settings"] + } + ], + "parameters": [ + { + "in": "path", + "name": "settingID", + "schema": { + "type": "string", + "minLength": 1 + }, + "required": true, + "description": "Setting ID", + "example": "default-site" + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": "default-site", + "name": "Default Site", + "description": "What to show when Nginx is hit with an unknown Host", + "value": "congratulations", + "meta": {} + } + } + }, + "schema": { + "$ref": "../../../components/setting-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/settings/settingID/put.json b/backend/schema/paths/settings/settingID/put.json new file mode 100644 index 0000000000..4ca6242939 --- /dev/null +++ b/backend/schema/paths/settings/settingID/put.json @@ -0,0 +1,79 @@ +{ + "operationId": "updateSetting", + "summary": "Update a setting", + "tags": ["Settings"], + "security": [ + { + "BearerAuth": ["settings"] + } + ], + "parameters": [ + { + "in": "path", + "name": "settingID", + "schema": { + "type": "string", + "minLength": 1, + "enum": ["default-site"] + }, + "required": true, + "description": "Setting ID", + "example": "default-site" + } + ], + "requestBody": { + "description": "Setting Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "value": { + "type": "string", + "minLength": 1, + "enum": ["congratulations", "404", "444", "redirect", "html"] + }, + "meta": { + "type": "object", + "additionalProperties": false, + "properties": { + "redirect": { + "type": "string" + }, + "html": { + "type": "string" + } + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": "default-site", + "name": "Default Site", + "description": "What to show when Nginx is hit with an unknown Host", + "value": "congratulations", + "meta": {} + } + } + }, + "schema": { + "$ref": "../../../components/setting-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/tokens/get.json b/backend/schema/paths/tokens/get.json new file mode 100644 index 0000000000..859bc61a4f --- /dev/null +++ b/backend/schema/paths/tokens/get.json @@ -0,0 +1,30 @@ +{ + "operationId": "refreshToken", + "summary": "Refresh your access token", + "tags": ["Tokens"], + "security": [ + { + "BearerAuth": ["tokens"] + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "expires": 1566540510, + "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" + } + } + }, + "schema": { + "$ref": "../../components/token-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/tokens/post.json b/backend/schema/paths/tokens/post.json new file mode 100644 index 0000000000..dece6b6567 --- /dev/null +++ b/backend/schema/paths/tokens/post.json @@ -0,0 +1,55 @@ +{ + "operationId": "requestToken", + "summary": "Request a new access token from credentials", + "tags": ["Tokens"], + "requestBody": { + "description": "Credentials Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "identity": { + "minLength": 1, + "type": "string" + }, + "scope": { + "minLength": 1, + "type": "string", + "enum": ["user"] + }, + "secret": { + "minLength": 1, + "type": "string" + } + }, + "required": ["identity", "secret"], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "result": { + "expires": 1566540510, + "token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4" + } + } + } + }, + "schema": { + "$ref": "../../components/token-object.json" + } + } + }, + "description": "200 response" + } + } +} diff --git a/backend/schema/paths/users/get.json b/backend/schema/paths/users/get.json new file mode 100644 index 0000000000..3741530114 --- /dev/null +++ b/backend/schema/paths/users/get.json @@ -0,0 +1,74 @@ +{ + "operationId": "getUsers", + "summary": "Get all users", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["permissions"] + } + } + ], + "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"] + } + ] + }, + "withPermissions": { + "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"], + "permissions": { + "visibility": "all", + "proxy_hosts": "manage", + "redirection_hosts": "manage", + "dead_hosts": "manage", + "streams": "manage", + "access_lists": "manage", + "certificates": "manage" + } + } + ] + } + }, + "schema": { + "$ref": "../../components/user-list.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/post.json b/backend/schema/paths/users/post.json new file mode 100644 index 0000000000..c0213fe05b --- /dev/null +++ b/backend/schema/paths/users/post.json @@ -0,0 +1,88 @@ +{ + "operationId": "createUser", + "summary": "Create a User", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "requestBody": { + "description": "User Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "required": ["name", "nickname", "email"], + "properties": { + "name": { + "$ref": "../../components/user-object.json#/properties/name" + }, + "nickname": { + "$ref": "../../components/user-object.json#/properties/nickname" + }, + "email": { + "$ref": "../../components/user-object.json#/properties/email" + }, + "roles": { + "$ref": "../../components/user-object.json#/properties/roles" + }, + "is_disabled": { + "$ref": "../../components/user-object.json#/properties/is_disabled" + }, + "auth": { + "type": "object", + "description": "Auth Credentials", + "example": { + "type": "password", + "secret": "bigredhorsebanana" + } + } + } + } + } + } + }, + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 2, + "created_on": "2020-01-30T09:41:04.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"], + "permissions": { + "id": 3, + "created_on": "2020-01-30T09:41:04.000Z", + "modified_on": "2020-01-30T09:41:04.000Z", + "user_id": 2, + "visibility": "user", + "proxy_hosts": "manage", + "redirection_hosts": "manage", + "dead_hosts": "manage", + "streams": "manage", + "access_lists": "manage", + "certificates": "manage" + } + } + } + }, + "schema": { + "$ref": "../../components/user-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/userID/auth/put.json b/backend/schema/paths/users/userID/auth/put.json new file mode 100644 index 0000000000..a72f5617c4 --- /dev/null +++ b/backend/schema/paths/users/userID/auth/put.json @@ -0,0 +1,79 @@ +{ + "operationId": "updateUserAuth", + "summary": "Update a User's Authentication", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "oneOf": [ + { + "type": "string", + "pattern": "^me$" + }, + { + "type": "integer", + "minimum": 1 + } + ] + }, + "required": true, + "description": "User ID or 'me' for yourself", + "example": 2 + } + ], + "requestBody": { + "description": "Auth Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["type", "secret"], + "properties": { + "type": { + "type": "string", + "pattern": "^password$", + "example": "password" + }, + "current": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "example": "changeme" + }, + "secret": { + "type": "string", + "minLength": 8, + "maxLength": 64, + "example": "mySuperN3wP@ssword!" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/userID/delete.json b/backend/schema/paths/users/userID/delete.json new file mode 100644 index 0000000000..7d4f36151d --- /dev/null +++ b/backend/schema/paths/users/userID/delete.json @@ -0,0 +1,40 @@ +{ + "operationId": "deleteUser", + "summary": "Delete a User", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "description": "User ID", + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/userID/get.json b/backend/schema/paths/users/userID/get.json new file mode 100644 index 0000000000..cb8ac61b46 --- /dev/null +++ b/backend/schema/paths/users/userID/get.json @@ -0,0 +1,58 @@ +{ + "operationId": "getUser", + "summary": "Get a user", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "oneOf": [ + { + "type": "string", + "pattern": "^me$" + }, + { + "type": "integer", + "minimum": 1 + } + ] + }, + "required": true, + "description": "User ID or 'me' for yourself", + "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/user-object.json" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/userID/login/post.json b/backend/schema/paths/users/userID/login/post.json new file mode 100644 index 0000000000..6148d182b4 --- /dev/null +++ b/backend/schema/paths/users/userID/login/post.json @@ -0,0 +1,73 @@ +{ + "operationId": "loginAsUser", + "summary": "Login as this user", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "description": "User ID", + "example": 2 + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "token": "eyJhbGciOiJSUzI1NiIsInR...16OjT8B3NLyXg", + "expires": "2020-01-31T10:56:23.239Z", + "user": { + "id": 1, + "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", + "avatar": "//www.gravatar.com/avatar/3c8d73f45fd8763f827b964c76e6032a?default=mm", + "roles": ["admin"] + } + } + } + }, + "schema": { + "type": "object", + "description": "Login object", + "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" + }, + "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 new file mode 100644 index 0000000000..2dcd2aed71 --- /dev/null +++ b/backend/schema/paths/users/userID/permissions/put.json @@ -0,0 +1,51 @@ +{ + "operationId": "updateUserPermissions", + "summary": "Update a User's Permissions", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "description": "User ID", + "example": 2 + } + ], + "requestBody": { + "description": "Permissions Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "../../../../components/permission-object.json" + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": true + } + }, + "schema": { + "type": "boolean" + } + } + } + } + } +} diff --git a/backend/schema/paths/users/userID/put.json b/backend/schema/paths/users/userID/put.json new file mode 100644 index 0000000000..60a6cd132d --- /dev/null +++ b/backend/schema/paths/users/userID/put.json @@ -0,0 +1,88 @@ +{ + "operationId": "updateUser", + "summary": "Update a User", + "tags": ["Users"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "path", + "name": "userID", + "schema": { + "oneOf": [ + { + "type": "string", + "pattern": "^me$" + }, + { + "type": "integer", + "minimum": 1 + } + ] + }, + "required": true, + "description": "User ID or 'me' for yourself", + "example": 2 + } + ], + "requestBody": { + "description": "User Payload", + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "name": { + "$ref": "../../../components/user-object.json#/properties/name" + }, + "nickname": { + "$ref": "../../../components/user-object.json#/properties/nickname" + }, + "email": { + "$ref": "../../../components/user-object.json#/properties/email" + }, + "roles": { + "$ref": "../../../components/user-object.json#/properties/roles" + }, + "is_disabled": { + "$ref": "../../../components/user-object.json#/properties/is_disabled" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 2, + "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/user-object.json" + } + } + } + } + } +} diff --git a/backend/schema/swagger.json b/backend/schema/swagger.json new file mode 100644 index 0000000000..5a0142bff7 --- /dev/null +++ b/backend/schema/swagger.json @@ -0,0 +1,265 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Nginx Proxy Manager API", + "version": "2.x.x" + }, + "servers": [ + { + "url": "http://127.0.0.1:81/api" + } + ], + "paths": { + "/": { + "get": { + "$ref": "./paths/get.json" + } + }, + "/audit-log": { + "get": { + "$ref": "./paths/audit-log/get.json" + } + }, + "/nginx/access-lists": { + "get": { + "$ref": "./paths/nginx/access-lists/get.json" + }, + "post": { + "$ref": "./paths/nginx/access-lists/post.json" + } + }, + "/nginx/access-lists/{listID}": { + "get": { + "$ref": "./paths/nginx/access-lists/listID/get.json" + }, + "put": { + "$ref": "./paths/nginx/access-lists/listID/put.json" + }, + "delete": { + "$ref": "./paths/nginx/access-lists/listID/delete.json" + } + }, + "/nginx/certificates": { + "get": { + "$ref": "./paths/nginx/certificates/get.json" + }, + "post": { + "$ref": "./paths/nginx/certificates/post.json" + } + }, + "/nginx/certificates/validate": { + "post": { + "$ref": "./paths/nginx/certificates/validate/post.json" + } + }, + "/nginx/certificates/test-http": { + "get": { + "$ref": "./paths/nginx/certificates/test-http/get.json" + } + }, + "/nginx/certificates/{certID}": { + "get": { + "$ref": "./paths/nginx/certificates/certID/get.json" + }, + "delete": { + "$ref": "./paths/nginx/certificates/certID/delete.json" + } + }, + "/nginx/certificates/{certID}/download": { + "get": { + "$ref": "./paths/nginx/certificates/certID/download/get.json" + } + }, + "/nginx/certificates/{certID}/renew": { + "post": { + "$ref": "./paths/nginx/certificates/certID/renew/post.json" + } + }, + "/nginx/certificates/{certID}/upload": { + "post": { + "$ref": "./paths/nginx/certificates/certID/upload/post.json" + } + }, + "/nginx/proxy-hosts": { + "get": { + "$ref": "./paths/nginx/proxy-hosts/get.json" + }, + "post": { + "$ref": "./paths/nginx/proxy-hosts/post.json" + } + }, + "/nginx/proxy-hosts/{hostID}": { + "get": { + "$ref": "./paths/nginx/proxy-hosts/hostID/get.json" + }, + "put": { + "$ref": "./paths/nginx/proxy-hosts/hostID/put.json" + }, + "delete": { + "$ref": "./paths/nginx/proxy-hosts/hostID/delete.json" + } + }, + "/nginx/proxy-hosts/{hostID}/enable": { + "post": { + "$ref": "./paths/nginx/proxy-hosts/hostID/enable/post.json" + } + }, + "/nginx/proxy-hosts/{hostID}/disable": { + "post": { + "$ref": "./paths/nginx/proxy-hosts/hostID/disable/post.json" + } + }, + "/nginx/redirection-hosts": { + "get": { + "$ref": "./paths/nginx/redirection-hosts/get.json" + }, + "post": { + "$ref": "./paths/nginx/redirection-hosts/post.json" + } + }, + "/nginx/redirection-hosts/{hostID}": { + "get": { + "$ref": "./paths/nginx/redirection-hosts/hostID/get.json" + }, + "put": { + "$ref": "./paths/nginx/redirection-hosts/hostID/put.json" + }, + "delete": { + "$ref": "./paths/nginx/redirection-hosts/hostID/delete.json" + } + }, + "/nginx/redirection-hosts/{hostID}/enable": { + "post": { + "$ref": "./paths/nginx/redirection-hosts/hostID/enable/post.json" + } + }, + "/nginx/redirection-hosts/{hostID}/disable": { + "post": { + "$ref": "./paths/nginx/redirection-hosts/hostID/disable/post.json" + } + }, + "/nginx/dead-hosts": { + "get": { + "$ref": "./paths/nginx/dead-hosts/get.json" + }, + "post": { + "$ref": "./paths/nginx/dead-hosts/post.json" + } + }, + "/nginx/dead-hosts/{hostID}": { + "get": { + "$ref": "./paths/nginx/dead-hosts/hostID/get.json" + }, + "put": { + "$ref": "./paths/nginx/dead-hosts/hostID/put.json" + }, + "delete": { + "$ref": "./paths/nginx/dead-hosts/hostID/delete.json" + } + }, + "/nginx/dead-hosts/{hostID}/enable": { + "post": { + "$ref": "./paths/nginx/dead-hosts/hostID/enable/post.json" + } + }, + "/nginx/dead-hosts/{hostID}/disable": { + "post": { + "$ref": "./paths/nginx/dead-hosts/hostID/disable/post.json" + } + }, + "/nginx/streams": { + "get": { + "$ref": "./paths/nginx/streams/get.json" + }, + "post": { + "$ref": "./paths/nginx/streams/post.json" + } + }, + "/nginx/streams/{streamID}": { + "get": { + "$ref": "./paths/nginx/streams/streamID/get.json" + }, + "put": { + "$ref": "./paths/nginx/streams/streamID/put.json" + }, + "delete": { + "$ref": "./paths/nginx/streams/streamID/delete.json" + } + }, + "/nginx/streams/{streamID}/enable": { + "post": { + "$ref": "./paths/nginx/streams/streamID/enable/post.json" + } + }, + "/nginx/streams/{streamID}/disable": { + "post": { + "$ref": "./paths/nginx/streams/streamID/disable/post.json" + } + }, + "/reports/hosts": { + "get": { + "$ref": "./paths/reports/hosts/get.json" + } + }, + "/schema": { + "get": { + "$ref": "./paths/schema/get.json" + } + }, + "/settings": { + "get": { + "$ref": "./paths/settings/get.json" + } + }, + "/settings/{settingID}": { + "get": { + "$ref": "./paths/settings/settingID/get.json" + }, + "put": { + "$ref": "./paths/settings/settingID/put.json" + } + }, + "/tokens": { + "get": { + "$ref": "./paths/tokens/get.json" + }, + "post": { + "$ref": "./paths/tokens/post.json" + } + }, + "/users": { + "get": { + "$ref": "./paths/users/get.json" + }, + "post": { + "$ref": "./paths/users/post.json" + } + }, + "/users/{userID}": { + "get": { + "$ref": "./paths/users/userID/get.json" + }, + "put": { + "$ref": "./paths/users/userID/put.json" + }, + "delete": { + "$ref": "./paths/users/userID/delete.json" + } + }, + "/users/{userID}/auth": { + "put": { + "$ref": "./paths/users/userID/auth/put.json" + } + }, + "/users/{userID}/permissions": { + "put": { + "$ref": "./paths/users/userID/permissions/put.json" + } + }, + "/users/{userID}/login": { + "post": { + "$ref": "./paths/users/userID/login/post.json" + } + } + } +} diff --git a/backend/templates/_location.conf b/backend/templates/_location.conf index b75632278b..fcc7d12104 100644 --- a/backend/templates/_location.conf +++ b/backend/templates/_location.conf @@ -6,7 +6,12 @@ proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; - proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; + + set $proxy_forward_scheme {{ forward_scheme }}; + set $proxy_server "{{ forward_host }}"; + set $proxy_port {{ forward_port }}; + + proxy_pass $proxy_forward_scheme://$proxy_server:$proxy_port{{ forward_path }}; {% include "_access.conf" %} {% include "_assets.conf" %} diff --git a/backend/validate-schema.js b/backend/validate-schema.js new file mode 100644 index 0000000000..71a05c8184 --- /dev/null +++ b/backend/validate-schema.js @@ -0,0 +1,16 @@ +const SwaggerParser = require('@apidevtools/swagger-parser'); +const chalk = require('chalk'); +const schema = require('./schema'); +const log = console.log; + +schema.getCompiledSchema().then(async (swaggerJSON) => { + try { + const api = await SwaggerParser.validate(swaggerJSON); + console.log('API name: %s, Version: %s', api.info.title, api.info.version); + log(chalk.green('❯ Schema is valid')); + } catch (e) { + console.error(e); + log(chalk.red('❯', e.message), '\n'); + process.exit(1); + } +}); diff --git a/backend/yarn.lock b/backend/yarn.lock index af20954969..5441a511c0 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -2,15 +2,47 @@ # yarn lockfile v1 -"@apidevtools/json-schema-ref-parser@8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-8.0.0.tgz#9eb749499b3f8d919e90bb141e4b6f67aee4692d" - integrity sha512-n4YBtwQhdpLto1BaUCyAeflizmIbaloGShsPyRtFf5qdFJxfssj+GgLavczgKJFa3Bq+3St2CKcpRJdjtB4EBw== +"@apidevtools/json-schema-ref-parser@9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#5d9000a3ac1fd25404da886da6b266adcd99cf1c" + integrity sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg== dependencies: - "@jsdevtools/ono" "^7.1.0" + "@jsdevtools/ono" "^7.1.3" call-me-maybe "^1.0.1" js-yaml "^3.13.1" +"@apidevtools/json-schema-ref-parser@^11.7.0": + version "11.7.0" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz#228d72018a0e7cbee744b677eaa01a8968f302d9" + integrity sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog== + dependencies: + "@jsdevtools/ono" "^7.1.3" + "@types/json-schema" "^7.0.15" + js-yaml "^4.1.0" + +"@apidevtools/openapi-schemas@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz#9fa08017fb59d80538812f03fc7cac5992caaa17" + integrity sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ== + +"@apidevtools/swagger-methods@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz#b789a362e055b0340d04712eafe7027ddc1ac267" + integrity sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg== + +"@apidevtools/swagger-parser@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@apidevtools/swagger-parser/-/swagger-parser-10.1.0.tgz#a987d71e5be61feb623203be0c96e5985b192ab6" + integrity sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw== + dependencies: + "@apidevtools/json-schema-ref-parser" "9.0.6" + "@apidevtools/openapi-schemas" "^2.1.0" + "@apidevtools/swagger-methods" "^3.0.2" + "@jsdevtools/ono" "^7.1.3" + ajv "^8.6.3" + ajv-draft-04 "^1.0.0" + call-me-maybe "^1.0.1" + "@eslint-community/eslint-utils@^4.2.0": version "4.3.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz#a556790523a351b4e47e9d385f47265eaaf9780a" @@ -67,7 +99,7 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@jsdevtools/ono@^7.1.0": +"@jsdevtools/ono@^7.1.3": version "7.1.3" resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== @@ -146,6 +178,11 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -193,7 +230,12 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.4: +ajv-draft-04@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz#3b64761b268ba0b9e668f0b41ba53fce0ad77fc8" + integrity sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw== + +ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -203,6 +245,16 @@ ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.17.1, ajv@^8.6.3: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + ajv@^8.6.2: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" @@ -360,6 +412,11 @@ async@^3.2.0: resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== +aws-ssl-profiles@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz#157dd77e9f19b1d123678e93f120e6f193022641" + integrity sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -383,11 +440,6 @@ bcrypt@^5.0.0: node-addon-api "^3.0.0" node-pre-gyp "0.15.0" -bignumber.js@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - binary-extensions@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" @@ -407,10 +459,10 @@ blueimp-md5@^2.16.0: resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.17.0.tgz#f4fcac088b115f7b4045f19f5da59e9d01b1bb96" integrity sha512-x5PKJHY5rHQYaADj6NwPUR2QRCUVSggPzrUKkeENpj871o9l9IefJbO2jkT5UvYykeOK9dx0VmkIo6dZ+vThYw== -body-parser@1.20.2, body-parser@^1.19.0: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== +body-parser@1.20.3, body-parser@^1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== dependencies: bytes "3.1.2" content-type "~1.0.5" @@ -420,7 +472,7 @@ body-parser@1.20.2, body-parser@^1.19.0: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.11.0" + qs "6.13.0" raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -552,6 +604,14 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +chalk@4.1.2, chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^2.3.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -569,14 +629,6 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chokidar@^3.2.2: version "3.4.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1" @@ -858,6 +910,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -936,6 +993,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -1133,37 +1195,37 @@ express-fileupload@^1.1.9: dependencies: busboy "^0.3.1" -express@^4.19.2: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== +express@^4.20.0: + version "4.20.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.20.0.tgz#f1d08e591fcec770c07be4767af8eb9bcfd67c48" + integrity sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" + body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" finalhandler "1.2.0" fresh "0.5.2" http-errors "2.0.0" - merge-descriptors "1.0.1" + merge-descriptors "1.0.3" methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "0.1.10" proxy-addr "~2.0.7" qs "6.11.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "0.19.0" + serve-static "1.16.0" setprototypeof "1.2.0" statuses "2.0.1" type-is "~1.6.18" @@ -1185,6 +1247,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-uri@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.2.tgz#d78b298cf70fd3b752fd951175a3da6a7b48f024" + integrity sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row== + fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -1354,6 +1421,13 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +generate-function@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1598,7 +1672,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -1801,6 +1875,11 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" @@ -1856,13 +1935,6 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-schema-ref-parser@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-8.0.0.tgz#7c758fac2cf822c05e837abd0a13f8fa2c15ffd4" - integrity sha512-2P4icmNkZLrBr6oa5gSZaDSol/oaBHYkoP/8dsw63E54NnHGRhhiFuy9yFoxPuSm+uHKmeGxAAWMDF16SCHhcQ== - dependencies: - "@apidevtools/json-schema-ref-parser" "8.0.0" - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -2028,6 +2100,11 @@ lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +long@^5.2.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -2045,6 +2122,16 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^8.0.0: + version "8.0.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-8.0.5.tgz#983fe337f3e176667f8e567cfcce7cb064ea214e" + integrity sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA== + make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -2079,10 +2166,10 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== methods@~1.1.2: version "1.1.2" @@ -2248,15 +2335,27 @@ ms@2.1.3, ms@^2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mysql@^2.18.1: - version "2.18.1" - resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.18.1.tgz#2254143855c5a8c73825e4522baf2ea021766717" - integrity sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig== +mysql2@^3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.11.1.tgz#edfb856e2176fcf43d2cc066dd4959e9fc76ea85" + integrity sha512-Oc8Zffd0gpIJnJ/NOMp6IiiJJDdWc7nmWpS+UE3K9feTpYia8XkbgL6EaOJYz52f6+2pAoC0eAQqUzal4lnNGQ== + dependencies: + aws-ssl-profiles "^1.1.1" + denque "^2.1.0" + generate-function "^2.3.1" + iconv-lite "^0.6.3" + long "^5.2.1" + lru-cache "^8.0.0" + named-placeholders "^1.1.3" + seq-queue "^0.0.5" + sqlstring "^2.3.2" + +named-placeholders@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" + integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w== dependencies: - bignumber.js "9.0.0" - readable-stream "2.3.7" - safe-buffer "5.1.2" - sqlstring "2.3.1" + lru-cache "^7.14.1" natural-compare@^1.4.0: version "1.4.0" @@ -2623,10 +2722,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path@^0.12.7: version "0.12.7" @@ -2742,6 +2841,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -2777,7 +2883,7 @@ rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6: +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.0.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -2969,10 +3075,34 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +seq-queue@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" + integrity sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q== + +serve-static@1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.0.tgz#2bf4ed49f8af311b519c46f272bf6ac3baf38a92" + integrity sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" @@ -3013,7 +3143,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4: +side-channel@^1.0.4, side-channel@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== @@ -3080,10 +3210,10 @@ sqlite3@5.1.6: optionalDependencies: node-gyp "8.x" -sqlstring@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40" - integrity sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A= +sqlstring@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" + integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" diff --git a/docker/Dockerfile b/docker/Dockerfile index 799ee2a63a..0603e2ded8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,6 +3,8 @@ # This file assumes that the frontend has been built using ./scripts/frontend-build +FROM nginxproxymanager/testca AS testca +FROM letsencrypt/pebble AS pebbleca FROM nginxproxymanager/nginx-full:certbot-node ARG TARGETPLATFORM @@ -45,6 +47,8 @@ RUN yarn install \ # add late to limit cache-busting by modifications COPY docker/rootfs / +COPY --from=pebbleca /test/certs/pebble.minica.pem /etc/ssl/certs/pebble.minica.pem +COPY --from=testca /home/step/certs/root_ca.crt /etc/ssl/certs/NginxProxyManager.crt # Remove frontend service not required for prod, dev nginx config as well RUN rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/frontend /etc/nginx/conf.d/dev.conf \ diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 3c21849cdb..bb4ac6d441 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,7 +1,10 @@ +FROM nginxproxymanager/testca AS testca +FROM letsencrypt/pebble AS pebbleca FROM nginxproxymanager/nginx-full:certbot-node LABEL maintainer="Jamie Curnow " -# See: https://github.com/just-containers/s6-overlay/blob/master/README.md +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + ENV SUPPRESS_NO_CONFIG_WARNING=1 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ @@ -17,17 +20,20 @@ RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ && rm -rf /var/lib/apt/lists/* # Task -RUN cd /usr \ - && curl -sL https://taskfile.dev/install.sh | sh \ - && cd /root +WORKDIR /usr +RUN curl -sL https://taskfile.dev/install.sh | sh +WORKDIR /root COPY rootfs / -RUN rm -f /etc/nginx/conf.d/production.conf -RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager - -# s6 overlay COPY scripts/install-s6 /tmp/install-s6 -RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6 +RUN rm -f /etc/nginx/conf.d/production.conf \ + && chmod 644 /etc/logrotate.d/nginx-proxy-manager \ + && /tmp/install-s6 "${TARGETPLATFORM}" \ + && rm -f /tmp/install-s6 + +# Certs for testing purposes +COPY --from=pebbleca /test/certs/pebble.minica.pem /etc/ssl/certs/pebble.minica.pem +COPY --from=testca /home/step/certs/root_ca.crt /etc/ssl/certs/NginxProxyManager.crt EXPOSE 80 81 443 ENTRYPOINT [ "/init" ] diff --git a/docker/dev/squid.conf b/docker/dev/squid.conf new file mode 100644 index 0000000000..cdd749f582 --- /dev/null +++ b/docker/dev/squid.conf @@ -0,0 +1,92 @@ +# WELCOME TO SQUID 6.6 +# ---------------------------- +# +# This is the documentation for the Squid configuration file. +# This documentation can also be found online at: +# http://www.squid-cache.org/Doc/config/ +# +# You may wish to look at the Squid home page and wiki for the +# FAQ and other documentation: +# http://www.squid-cache.org/ +# https://wiki.squid-cache.org/SquidFaq +# https://wiki.squid-cache.org/ConfigExamples +# + +# Example rule allowing access from your local networks. +# Adapt to list your (internal) IP networks from where browsing +# should be allowed +acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN) +acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN) +acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN) +acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines +acl localnet src 172.0.0.0/8 +acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN) +acl localnet src fc00::/7 # RFC 4193 local private network range +acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + +acl SSL_ports port 443 +acl Safe_ports port 80 # http +acl Safe_ports port 81 +acl Safe_ports port 443 # https + +# +# Recommended minimum Access Permission configuration: +# +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +http_access deny CONNECT !SSL_ports + +# Only allow cachemgr access from localhost +http_access allow localhost manager +http_access deny manager + +# This default configuration only allows localhost requests because a more +# permissive Squid installation could introduce new attack vectors into the +# network by proxying external TCP connections to unprotected services. +http_access allow localhost + +# The two deny rules below are unnecessary in this default configuration +# because they are followed by a "deny all" rule. However, they may become +# critically important when you start allowing external requests below them. + +# Protect web applications running on the same server as Squid. They often +# assume that only local users can access them at "localhost" ports. +http_access deny to_localhost + +# Protect cloud servers that provide local users with sensitive info about +# their server via certain well-known link-local (a.k.a. APIPA) addresses. +http_access deny to_linklocal + +# +# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS +# +include /etc/squid/conf.d/*.conf + +# For example, to allow access from your local networks, you may uncomment the +# following rule (and/or add rules that match your definition of "local"): +# http_access allow localnet + +# And finally deny all other access to this proxy +http_access deny all + +# Squid normally listens to port 3128 +http_port 3128 + +# Leave coredumps in the first cache dir +coredump_dir /var/spool/squid + +# +# Add any of your own refresh_pattern entries above these. +# +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims +refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims +refresh_pattern \/InRelease$ 0 0% 0 refresh-ims +refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims +# example pattern for deb packages +#refresh_pattern (\.deb|\.udeb)$ 129600 100% 129600 +refresh_pattern . 0 20% 4320 + diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index b4a4480637..bb68858f99 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -9,6 +9,9 @@ services: environment: DEBUG: 'true' FORCE_COLOR: 1 + # Required for DNS Certificate provisioning in CI + LE_SERVER: 'https://ca.internal/acme/acme/directory' + REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt' volumes: - 'npm_data_ci:/data' - 'npm_le_ci:/etc/letsencrypt' @@ -91,14 +94,25 @@ services: context: ../ dockerfile: test/cypress/Dockerfile environment: - CYPRESS_baseUrl: 'http://fullstack:81' + HTTP_PROXY: 'squid:3128' + HTTPS_PROXY: 'squid:3128' volumes: - 'cypress_logs:/results' - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' command: cypress run --browser chrome --config-file=cypress/config/ci.js networks: - fulltest + squid: + image: ubuntu/squid + volumes: + - './dev/squid.conf:/etc/squid/squid.conf:ro' + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + networks: + - fulltest + volumes: cypress_logs: npm_data_ci: diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 14ca2f7a74..2bfa2b7985 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -1,7 +1,7 @@ # WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. services: - npm: + fullstack: image: nginxproxymanager:dev container_name: npm_core build: @@ -12,7 +12,11 @@ services: - 3081:81 - 3443:443 networks: - - nginx_proxy_manager + nginx_proxy_manager: + aliases: + - website1.example.com + - website2.example.com + - website3.example.com environment: PUID: 1000 PGID: 1000 @@ -29,12 +33,20 @@ services: DB_MYSQL_NAME: 'npm' # DB_SQLITE_FILE: "/data/database.sqlite" # DISABLE_IPV6: "true" + # Required for DNS Certificate provisioning testing: + LE_SERVER: 'https://ca.internal/acme/acme/directory' + REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt' volumes: - npm_data:/data - le_data:/etc/letsencrypt + - './dev/resolv.conf:/etc/resolv.conf:ro' - ../backend:/app - ../frontend:/app/frontend - ../global:/app/global + healthcheck: + test: ["CMD", "/usr/bin/check-health"] + interval: 10s + timeout: 3s depends_on: - db working_dir: /app @@ -54,6 +66,104 @@ services: volumes: - db_data:/var/lib/mysql + stepca: + image: jc21/testca + volumes: + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + networks: + nginx_proxy_manager: + aliases: + - ca.internal + + dnsrouter: + image: jc21/dnsrouter + volumes: + - ./dev/dnsrouter-config.json.tmp:/dnsrouter-config.json:ro + networks: + - nginx_proxy_manager + + swagger: + image: swaggerapi/swagger-ui:latest + container_name: npm_swagger + ports: + - 3082:80 + environment: + URL: "http://npm:81/api/schema" + PORT: '80' + depends_on: + - fullstack + + squid: + image: ubuntu/squid + container_name: npm_squid + volumes: + - './dev/squid.conf:/etc/squid/squid.conf:ro' + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + networks: + - nginx_proxy_manager + ports: + - 8128:3128 + + pdns: + image: pschiffe/pdns-mysql + volumes: + - '/etc/localtime:/etc/localtime:ro' + environment: + PDNS_master: 'yes' + PDNS_api: 'yes' + PDNS_api_key: 'npm' + PDNS_webserver: 'yes' + PDNS_webserver_address: '0.0.0.0' + PDNS_webserver_password: 'npm' + PDNS_webserver-allow-from: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8' + PDNS_version_string: 'anonymous' + PDNS_default_ttl: 1500 + PDNS_allow_axfr_ips: '127.0.0.0/8,192.0.0.0/8,10.0.0.0/8,172.0.0.0/8' + PDNS_gmysql_host: pdns-db + PDNS_gmysql_port: 3306 + PDNS_gmysql_user: pdns + PDNS_gmysql_password: pdns + PDNS_gmysql_dbname: pdns + depends_on: + - pdns-db + networks: + nginx_proxy_manager: + aliases: + - ns1.pdns + - ns2.pdns + + pdns-db: + image: mariadb + environment: + MYSQL_ROOT_PASSWORD: 'pdns' + MYSQL_DATABASE: 'pdns' + MYSQL_USER: 'pdns' + MYSQL_PASSWORD: 'pdns' + volumes: + - 'pdns_mysql:/var/lib/mysql' + - '/etc/localtime:/etc/localtime:ro' + - './dev/pdns-db.sql:/docker-entrypoint-initdb.d/01_init.sql:ro' + networks: + - nginx_proxy_manager + + cypress: + image: "npm_dev_cypress" + build: + context: ../ + dockerfile: test/cypress/Dockerfile + environment: + HTTP_PROXY: 'squid:3128' + HTTPS_PROXY: 'squid:3128' + volumes: + - '../test/results:/results' + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + command: cypress run --browser chrome --config-file=cypress/config/ci.js + networks: + - nginx_proxy_manager + volumes: npm_data: name: npm_core_data @@ -61,6 +171,8 @@ volumes: name: npm_le_data db_data: name: npm_db_data + pdns_mysql: + name: npm_pdns_mysql networks: nginx_proxy_manager: diff --git a/docker/rootfs/etc/logrotate.d/nginx-proxy-manager b/docker/rootfs/etc/logrotate.d/nginx-proxy-manager index 275b0aa6af..de9772971e 100644 --- a/docker/rootfs/etc/logrotate.d/nginx-proxy-manager +++ b/docker/rootfs/etc/logrotate.d/nginx-proxy-manager @@ -8,7 +8,7 @@ compress sharedscripts postrotate - /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true + kill -USR1 `cat /run/nginx/nginx.pid 2>/dev/null` 2>/dev/null || true endscript } @@ -22,6 +22,6 @@ compress sharedscripts postrotate - /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true + kill -USR1 `cat /run/nginx/nginx.pid 2>/dev/null` 2>/dev/null || true endscript -} \ No newline at end of file +} diff --git a/docker/rootfs/var/www/html/index.html b/docker/rootfs/var/www/html/index.html index 8478b47f13..703db883d7 100644 --- a/docker/rootfs/var/www/html/index.html +++ b/docker/rootfs/var/www/html/index.html @@ -5,7 +5,7 @@ Default Site - + diff --git a/docs/package.json b/docs/package.json index cc3d08c1c5..3e3dcba252 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,7 @@ "preview": "vitepress preview" }, "devDependencies": { - "vitepress": "^1.1.4" + "vitepress": "^1.4.0" }, "dependencies": {} } diff --git a/docs/src/guide/index.md b/docs/src/guide/index.md index ad350b3b93..fcf176fa94 100644 --- a/docs/src/guide/index.md +++ b/docs/src/guide/index.md @@ -62,7 +62,6 @@ I won't go in to too much detail here but here are the basics for someone new to 2. Create a docker-compose.yml file similar to this: ```yml -version: '3.8' services: app: image: 'jc21/nginx-proxy-manager:latest' diff --git a/docs/yarn.lock b/docs/yarn.lock index 9249476a3d..01fe299628 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -150,413 +150,498 @@ "@algolia/logger-common" "4.23.3" "@algolia/requester-common" "4.23.3" -"@babel/parser@^7.24.4": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" - integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== - -"@docsearch/css@3.6.0", "@docsearch/css@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.0.tgz#0e9f56f704b3a34d044d15fd9962ebc1536ba4fb" - integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ== - -"@docsearch/js@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.6.0.tgz#f9e46943449b9092d874944f7a80bcc071004cfb" - integrity sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ== - dependencies: - "@docsearch/react" "3.6.0" +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== + +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== + +"@babel/parser@^7.25.3": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" + integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== + dependencies: + "@babel/types" "^7.25.8" + +"@babel/types@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" + integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== + dependencies: + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" + +"@docsearch/css@3.6.2", "@docsearch/css@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.2.tgz#ccd9c83dbfeaf34efe4e3547ee596714ae7e5891" + integrity sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw== + +"@docsearch/js@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.6.2.tgz#000d7d255e8387e7c5b82c7b87d3060398e1605d" + integrity sha512-pS4YZF+VzUogYrkblCucQ0Oy2m8Wggk8Kk7lECmZM60hTbaydSIhJTTiCrmoxtBqV8wxORnOqcqqOfbmkkQEcA== + dependencies: + "@docsearch/react" "3.6.2" preact "^10.0.0" -"@docsearch/react@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.0.tgz#b4f25228ecb7fc473741aefac592121e86dd2958" - integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w== +"@docsearch/react@3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.2.tgz#32b16dd7d5614f0d39e6bc018549816b68d171b8" + integrity sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA== dependencies: "@algolia/autocomplete-core" "1.9.3" "@algolia/autocomplete-preset-algolia" "1.9.3" - "@docsearch/css" "3.6.0" + "@docsearch/css" "3.6.2" algoliasearch "^4.19.1" -"@esbuild/aix-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" - integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== - -"@esbuild/android-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" - integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== - -"@esbuild/android-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" - integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== - -"@esbuild/android-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" - integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== - -"@esbuild/darwin-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" - integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== - -"@esbuild/darwin-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" - integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== - -"@esbuild/freebsd-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" - integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== - -"@esbuild/freebsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" - integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== - -"@esbuild/linux-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" - integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== - -"@esbuild/linux-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" - integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== - -"@esbuild/linux-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" - integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== - -"@esbuild/linux-loong64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" - integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== - -"@esbuild/linux-mips64el@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" - integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== - -"@esbuild/linux-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" - integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== - -"@esbuild/linux-riscv64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" - integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== - -"@esbuild/linux-s390x@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" - integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== - -"@esbuild/linux-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" - integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== - -"@esbuild/netbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" - integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== - -"@esbuild/openbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" - integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== - -"@esbuild/sunos-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" - integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== - -"@esbuild/win32-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" - integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== - -"@esbuild/win32-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" - integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== - -"@esbuild/win32-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" - integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== - -"@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@rollup/rollup-android-arm-eabi@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz#1a32112822660ee104c5dd3a7c595e26100d4c2d" - integrity sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ== - -"@rollup/rollup-android-arm64@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz#5aeef206d65ff4db423f3a93f71af91b28662c5b" - integrity sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw== - -"@rollup/rollup-darwin-arm64@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz#6b66aaf003c70454c292cd5f0236ebdc6ffbdf1a" - integrity sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw== - -"@rollup/rollup-darwin-x64@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz#f64fc51ed12b19f883131ccbcea59fc68cbd6c0b" - integrity sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ== - -"@rollup/rollup-linux-arm-gnueabihf@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz#1a7641111be67c10111f7122d1e375d1226cbf14" - integrity sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A== - -"@rollup/rollup-linux-arm-musleabihf@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz#c93fd632923e0fee25aacd2ae414288d0b7455bb" - integrity sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg== - -"@rollup/rollup-linux-arm64-gnu@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz#fa531425dd21d058a630947527b4612d9d0b4a4a" - integrity sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A== - -"@rollup/rollup-linux-arm64-musl@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz#8acc16f095ceea5854caf7b07e73f7d1802ac5af" - integrity sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA== - -"@rollup/rollup-linux-powerpc64le-gnu@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz#94e69a8499b5cf368911b83a44bb230782aeb571" - integrity sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ== - -"@rollup/rollup-linux-riscv64-gnu@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz#7ef1c781c7e59e85a6ce261cc95d7f1e0b56db0f" - integrity sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg== - -"@rollup/rollup-linux-s390x-gnu@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz#f15775841c3232fca9b78cd25a7a0512c694b354" - integrity sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g== - -"@rollup/rollup-linux-x64-gnu@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz#b521d271798d037ad70c9f85dd97d25f8a52e811" - integrity sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ== - -"@rollup/rollup-linux-x64-musl@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz#9254019cc4baac35800991315d133cc9fd1bf385" - integrity sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q== - -"@rollup/rollup-win32-arm64-msvc@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz#27f65a89f6f52ee9426ec11e3571038e4671790f" - integrity sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA== - -"@rollup/rollup-win32-ia32-msvc@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz#a2fbf8246ed0bb014f078ca34ae6b377a90cb411" - integrity sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ== - -"@rollup/rollup-win32-x64-msvc@4.17.2": - version "4.17.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz#5a2d08b81e8064b34242d5cc9973ef8dd1e60503" - integrity sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w== - -"@shikijs/core@1.5.0", "@shikijs/core@^1.3.0": +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@jridgewell/sourcemap-codec@^1.5.0": version "1.5.0" - resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.5.0.tgz#8d594a6d6eb8cfdb9f2de457893e384257f2e0a2" - integrity sha512-tdYjQu+jnvlPbJg4OjgCQ16zAfHlLk+RzA9o025aeaIyUww6W/Vd9TQ2t+gdZgK1fox29/L2yyqXLU6ErzYA0w== + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@rollup/rollup-android-arm-eabi@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54" + integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA== + +"@rollup/rollup-android-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e" + integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA== + +"@rollup/rollup-darwin-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f" + integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA== + +"@rollup/rollup-darwin-x64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724" + integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb" + integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA== + +"@rollup/rollup-linux-arm-musleabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3" + integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw== + +"@rollup/rollup-linux-arm64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496" + integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA== + +"@rollup/rollup-linux-arm64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065" + integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d" + integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw== + +"@rollup/rollup-linux-riscv64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983" + integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg== + +"@rollup/rollup-linux-s390x-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58" + integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g== + +"@rollup/rollup-linux-x64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b" + integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== + +"@rollup/rollup-linux-x64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127" + integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== + +"@rollup/rollup-win32-arm64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5" + integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ== + +"@rollup/rollup-win32-ia32-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2" + integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ== + +"@rollup/rollup-win32-x64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818" + integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== + +"@shikijs/core@1.22.0", "@shikijs/core@^1.22.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.22.0.tgz#74e5d4485e5f7afa85109e322b42e400686f92bb" + integrity sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q== + dependencies: + "@shikijs/engine-javascript" "1.22.0" + "@shikijs/engine-oniguruma" "1.22.0" + "@shikijs/types" "1.22.0" + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.3" + +"@shikijs/engine-javascript@1.22.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-1.22.0.tgz#2e5db29f0421755492f5279f8224ef7a7f907a29" + integrity sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw== + dependencies: + "@shikijs/types" "1.22.0" + "@shikijs/vscode-textmate" "^9.3.0" + oniguruma-to-js "0.4.3" + +"@shikijs/engine-oniguruma@1.22.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.0.tgz#74c661fac4cd1f08f2c09b5d6e2fd2a6720d0401" + integrity sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw== + dependencies: + "@shikijs/types" "1.22.0" + "@shikijs/vscode-textmate" "^9.3.0" -"@shikijs/transformers@^1.3.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.5.0.tgz#7d091152eca97bfddceb26e12234944a217e9b50" - integrity sha512-WYCLJ4MhW1LmVqfVjUZny9XLh32kk/mo/y5sCXt5sc5rU21K6LA+yLWHdb0eYhmSc4n+FWTxW3ZNiZs57uwyOA== +"@shikijs/transformers@^1.22.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.22.0.tgz#f36fa4d769e36db9a91e09877cf48b3a04d26aba" + integrity sha512-k7iMOYuGQA62KwAuJOQBgH2IQb5vP8uiB3lMvAMGUgAMMurePOx3Z7oNqJdcpxqZP6I9cc7nc4DNqSKduCxmdg== dependencies: - shiki "1.5.0" + shiki "1.22.0" -"@types/estree@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@shikijs/types@1.22.0", "@shikijs/types@^1.22.0": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.22.0.tgz#d2a572381395c9308b472c8199b8e0289753b9ad" + integrity sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww== + dependencies: + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz#b2f1776e488c1d6c2b6cd129bab62f71bbc9c7ab" + integrity sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA== + +"@types/estree@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/hast@^3.0.0", "@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" "@types/linkify-it@^5": version "5.0.0" resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== -"@types/markdown-it@^14.0.1": - version "14.1.1" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.1.tgz#06bafb7a4e3f77b62b1f308acf7df76687887e0b" - integrity sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg== +"@types/markdown-it@^14.1.2": + version "14.1.2" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.2.tgz#57f2532a0800067d9b934f3521429a2e8bfb4c61" + integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog== dependencies: "@types/linkify-it" "^5" "@types/mdurl" "^2" +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + "@types/mdurl@^2": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== + "@types/web-bluetooth@^0.0.20": version "0.0.20" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow== -"@vitejs/plugin-vue@^5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz#508d6a0f2440f86945835d903fcc0d95d1bb8a37" - integrity sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ== - -"@vue/compiler-core@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.27.tgz#e69060f4b61429fe57976aa5872cfa21389e4d91" - integrity sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg== +"@ungap/structured-clone@^1.0.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vitejs/plugin-vue@^5.1.4": + version "5.1.4" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz#72b8b705cfce36b00b59af196195146e356500c4" + integrity sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A== + +"@vue/compiler-core@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.11.tgz#3dcd0c1bab10732f44ab1790735afb03a4b69edc" + integrity sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg== dependencies: - "@babel/parser" "^7.24.4" - "@vue/shared" "3.4.27" + "@babel/parser" "^7.25.3" + "@vue/shared" "3.5.11" entities "^4.5.0" estree-walker "^2.0.2" source-map-js "^1.2.0" -"@vue/compiler-dom@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz#d51d35f40d00ce235d7afc6ad8b09dfd92b1cc1c" - integrity sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw== +"@vue/compiler-dom@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz#950f8fc610e26326fed008b8d102cc8ee78a6ce5" + integrity sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew== dependencies: - "@vue/compiler-core" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-core" "3.5.11" + "@vue/shared" "3.5.11" -"@vue/compiler-sfc@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz#399cac1b75c6737bf5440dc9cf3c385bb2959701" - integrity sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA== +"@vue/compiler-sfc@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz#68ba7bc6fed4fec6892aed118cb3ee8e4b180d06" + integrity sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw== dependencies: - "@babel/parser" "^7.24.4" - "@vue/compiler-core" "3.4.27" - "@vue/compiler-dom" "3.4.27" - "@vue/compiler-ssr" "3.4.27" - "@vue/shared" "3.4.27" + "@babel/parser" "^7.25.3" + "@vue/compiler-core" "3.5.11" + "@vue/compiler-dom" "3.5.11" + "@vue/compiler-ssr" "3.5.11" + "@vue/shared" "3.5.11" estree-walker "^2.0.2" - magic-string "^0.30.10" - postcss "^8.4.38" + magic-string "^0.30.11" + postcss "^8.4.47" source-map-js "^1.2.0" -"@vue/compiler-ssr@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz#2a8ecfef1cf448b09be633901a9c020360472e3d" - integrity sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw== +"@vue/compiler-ssr@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz#02d9891c7a649bbf06490ecd8d24dd1575d53e60" + integrity sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA== dependencies: - "@vue/compiler-dom" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/compiler-dom" "3.5.11" + "@vue/shared" "3.5.11" -"@vue/devtools-api@^7.0.27": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.1.3.tgz#b1cc9050025022193204ad804a9669e384fee8b0" - integrity sha512-W8IwFJ/o5iUk78jpqhvScbgCsPiOp2uileDVC0NDtW38gCWhsnu9SeBTjcdu3lbwLdsjc+H1c5Msd/x9ApbcFA== +"@vue/devtools-api@^7.4.6": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.4.6.tgz#5e9249d6de3cee58624e511fdc727837b1f2d273" + integrity sha512-XipBV5k0/IfTr0sNBDTg7OBUCp51cYMMXyPxLXJZ4K/wmUeMqt8cVdr2ZZGOFq+si/jTyCYnNxeKoyev5DOUUA== dependencies: - "@vue/devtools-kit" "^7.1.3" + "@vue/devtools-kit" "^7.4.6" -"@vue/devtools-kit@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.1.3.tgz#0344fd1a926ff535d3be3378e1da8bb71d8430b9" - integrity sha512-NFskFSJMVCBXTkByuk2llzI3KD3Blcm7WqiRorWjD6nClHPgkH5BobDH08rfulqq5ocRt5xV+3qOT1Q9FXJrwQ== +"@vue/devtools-kit@^7.4.6": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.4.6.tgz#80aa30db65bf5b2b0eda4e818749d3c37d80f709" + integrity sha512-NbYBwPWgEic1AOd9bWExz9weBzFdjiIfov0yRn4DrRfR+EQJCI9dn4I0XS7IxYGdkmUJi8mFW42LLk18WsGqew== dependencies: - "@vue/devtools-shared" "^7.1.3" + "@vue/devtools-shared" "^7.4.6" + birpc "^0.2.17" hookable "^5.5.3" mitt "^3.0.1" perfect-debounce "^1.0.0" speakingurl "^14.0.1" + superjson "^2.2.1" -"@vue/devtools-shared@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.1.3.tgz#f570bba72d53a0c84d1faa19f4d1a29a339c1dc7" - integrity sha512-KJ3AfgjTn3tJz/XKF+BlVShNPecim3G21oHRue+YQOsooW+0s+qXvm09U09aO7yBza5SivL1QgxSrzAbiKWjhQ== +"@vue/devtools-shared@^7.4.6": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.4.6.tgz#492c2301caacc83a32542dd95dfcae3980621417" + integrity sha512-rPeSBzElnHYMB05Cc056BQiJpgocQjY8XVulgni+O9a9Gr9tNXgPteSzFFD+fT/iWMxNuUgGKs9CuW5DZewfIg== dependencies: - rfdc "^1.3.1" + rfdc "^1.4.1" -"@vue/reactivity@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.27.tgz#6ece72331bf719953f5eaa95ec60b2b8d49e3791" - integrity sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA== +"@vue/reactivity@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.11.tgz#d27df4fba10c2de1c7234701f18247a775b7a391" + integrity sha512-Nqo5VZEn8MJWlCce8XoyVqHZbd5P2NH+yuAaFzuNSR96I+y1cnuUiq7xfSG+kyvLSiWmaHTKP1r3OZY4mMD50w== dependencies: - "@vue/shared" "3.4.27" + "@vue/shared" "3.5.11" -"@vue/runtime-core@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.27.tgz#1b6e1d71e4604ba7442dd25ed22e4a1fc6adbbda" - integrity sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA== +"@vue/runtime-core@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.11.tgz#7beccd013efe5d33981ffd6b6e05d0a5b9058316" + integrity sha512-7PsxFGqwfDhfhh0OcDWBG1DaIQIVOLgkwA5q6MtkPiDFjp5gohVnJEahSktwSFLq7R5PtxDKy6WKURVN1UDbzA== dependencies: - "@vue/reactivity" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/reactivity" "3.5.11" + "@vue/shared" "3.5.11" -"@vue/runtime-dom@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz#fe8d1ce9bbe8921d5dd0ad5c10df0e04ef7a5ee7" - integrity sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q== +"@vue/runtime-dom@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.11.tgz#14a3181ab7057de41b345b4b3d37b744b3ff8ff5" + integrity sha512-GNghjecT6IrGf0UhuYmpgaOlN7kxzQBhxWEn08c/SQDxv1yy4IXI1bn81JgEpQ4IXjRxWtPyI8x0/7TF5rPfYQ== dependencies: - "@vue/runtime-core" "3.4.27" - "@vue/shared" "3.4.27" + "@vue/reactivity" "3.5.11" + "@vue/runtime-core" "3.5.11" + "@vue/shared" "3.5.11" csstype "^3.1.3" -"@vue/server-renderer@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.27.tgz#3306176f37e648ba665f97dda3ce705687be63d2" - integrity sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA== +"@vue/server-renderer@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.11.tgz#74f558371dfc39f3b0f26f95d089a1a4d1676027" + integrity sha512-cVOwYBxR7Wb1B1FoxYvtjJD8X/9E5nlH4VSkJy2uMA1MzYNdzAAB//l8nrmN9py/4aP+3NjWukf9PZ3TeWULaA== dependencies: - "@vue/compiler-ssr" "3.4.27" - "@vue/shared" "3.4.27" - -"@vue/shared@3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.27.tgz#f05e3cd107d157354bb4ae7a7b5fc9cf73c63b50" - integrity sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA== - -"@vueuse/core@10.9.0", "@vueuse/core@^10.9.0": - version "10.9.0" - resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.9.0.tgz#7d779a95cf0189de176fee63cee4ba44b3c85d64" - integrity sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg== + "@vue/compiler-ssr" "3.5.11" + "@vue/shared" "3.5.11" + +"@vue/shared@3.5.11", "@vue/shared@^3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.11.tgz#464b840afc89be9373addff9eeb9dfc98bf3fe2e" + integrity sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ== + +"@vueuse/core@11.1.0", "@vueuse/core@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-11.1.0.tgz#a104f33c899a15f3b28d3eb7b20738501a3a5035" + integrity sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg== dependencies: "@types/web-bluetooth" "^0.0.20" - "@vueuse/metadata" "10.9.0" - "@vueuse/shared" "10.9.0" - vue-demi ">=0.14.7" - -"@vueuse/integrations@^10.9.0": - version "10.9.0" - resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.9.0.tgz#2b1a9556215ad3c1f96d39cbfbef102cf6e0ec05" - integrity sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q== + "@vueuse/metadata" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" + +"@vueuse/integrations@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-11.1.0.tgz#1e2c1d43b2d389fc4b4d0a7ee08091665698b9ad" + integrity sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA== dependencies: - "@vueuse/core" "10.9.0" - "@vueuse/shared" "10.9.0" - vue-demi ">=0.14.7" - -"@vueuse/metadata@10.9.0": - version "10.9.0" - resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.9.0.tgz#769a1a9db65daac15cf98084cbf7819ed3758620" - integrity sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA== - -"@vueuse/shared@10.9.0": - version "10.9.0" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.9.0.tgz#13af2a348de15d07b7be2fd0c7fc9853a69d8fe0" - integrity sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw== + "@vueuse/core" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" + +"@vueuse/metadata@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-11.1.0.tgz#ad367d2a51d985129724425923b3cf95f0faf27b" + integrity sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg== + +"@vueuse/shared@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-11.1.0.tgz#3bfc3aa555c2a456c21945ec7f127d71938d12e8" + integrity sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w== dependencies: - vue-demi ">=0.14.7" + vue-demi ">=0.14.10" algoliasearch@^4.19.1: version "4.23.3" @@ -579,54 +664,98 @@ algoliasearch@^4.19.1: "@algolia/requester-node-http" "4.23.3" "@algolia/transporter" "4.23.3" +birpc@^0.2.17: + version "0.2.19" + resolved "https://registry.yarnpkg.com/birpc/-/birpc-0.2.19.tgz#cdd183a4a70ba103127d49765b4a71349da5a0ca" + integrity sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + +copy-anything@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.5.tgz#2d92dce8c498f790fa7ad16b01a1ae5a45b020a0" + integrity sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w== + dependencies: + is-what "^4.1.8" + csstype@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + entities@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -esbuild@^0.20.1: - version "0.20.2" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" - integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.2" - "@esbuild/android-arm" "0.20.2" - "@esbuild/android-arm64" "0.20.2" - "@esbuild/android-x64" "0.20.2" - "@esbuild/darwin-arm64" "0.20.2" - "@esbuild/darwin-x64" "0.20.2" - "@esbuild/freebsd-arm64" "0.20.2" - "@esbuild/freebsd-x64" "0.20.2" - "@esbuild/linux-arm" "0.20.2" - "@esbuild/linux-arm64" "0.20.2" - "@esbuild/linux-ia32" "0.20.2" - "@esbuild/linux-loong64" "0.20.2" - "@esbuild/linux-mips64el" "0.20.2" - "@esbuild/linux-ppc64" "0.20.2" - "@esbuild/linux-riscv64" "0.20.2" - "@esbuild/linux-s390x" "0.20.2" - "@esbuild/linux-x64" "0.20.2" - "@esbuild/netbsd-x64" "0.20.2" - "@esbuild/openbsd-x64" "0.20.2" - "@esbuild/sunos-x64" "0.20.2" - "@esbuild/win32-arm64" "0.20.2" - "@esbuild/win32-ia32" "0.20.2" - "@esbuild/win32-x64" "0.20.2" + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -focus-trap@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2" - integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w== +focus-trap@^7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.6.0.tgz#7f3edab8135eaca92ab59b6e963eb5cc42ded715" + integrity sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ== dependencies: tabbable "^6.2.0" @@ -635,27 +764,108 @@ fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +hast-util-to-html@^9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz#a9999a0ba6b4919576a9105129fead85d37f302b" + integrity sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + hookable@^5.5.3: version "5.5.3" resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d" integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ== -magic-string@^0.30.10: - version "0.30.10" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" - integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +is-what@^4.1.8: + version "4.1.16" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.16.tgz#1ad860a19da8b4895ad5495da3182ce2acdd7a6f" + integrity sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A== + +magic-string@^0.30.11: + version "0.30.11" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" + "@jridgewell/sourcemap-codec" "^1.5.0" mark.js@8.11.1: version "8.11.1" resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5" integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ== -minisearch@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.3.0.tgz#985a2f1ca3c73c2d65af94f0616bfe57164b0b6b" - integrity sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ== +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +micromark-util-character@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" + integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" + integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" + integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" + integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + +micromark-util-types@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" + integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + +minisearch@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-7.1.0.tgz#f5830e9109b5919ee7b291c29a304f381aa68770" + integrity sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA== mitt@^3.0.1: version "3.0.1" @@ -667,126 +877,244 @@ nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +oniguruma-to-js@0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz#8d899714c21f5c7d59a3c0008ca50e848086d740" + integrity sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ== + dependencies: + regex "^4.3.2" + perfect-debounce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== -postcss@^8.4.38: - version "8.4.38" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== +postcss@^8.4.43, postcss@^8.4.47: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== dependencies: nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.2.0" + picocolors "^1.1.0" + source-map-js "^1.2.1" preact@^10.0.0: version "10.21.0" resolved "https://registry.yarnpkg.com/preact/-/preact-10.21.0.tgz#5b0335c873a1724deb66e517830db4fd310c24f6" integrity sha512-aQAIxtzWEwH8ou+OovWVSVNlFImL7xUCwJX3YMqA3U8iKCNC34999fFOnWjYNsylgfPgMexpbk7WYOLtKr/mxg== -rfdc@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" - integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== - -rollup@^4.13.0: - version "4.17.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.17.2.tgz#26d1785d0144122277fdb20ab3a24729ae68301f" - integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== +property-information@^6.0.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec" + integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== + +regex@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/regex/-/regex-4.3.3.tgz#8cda73ccbdfa7c5691881d02f9bb142dba9daa6a" + integrity sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg== + +rfdc@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + +rollup@^4.20.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05" + integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg== dependencies: - "@types/estree" "1.0.5" + "@types/estree" "1.0.6" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.17.2" - "@rollup/rollup-android-arm64" "4.17.2" - "@rollup/rollup-darwin-arm64" "4.17.2" - "@rollup/rollup-darwin-x64" "4.17.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.17.2" - "@rollup/rollup-linux-arm-musleabihf" "4.17.2" - "@rollup/rollup-linux-arm64-gnu" "4.17.2" - "@rollup/rollup-linux-arm64-musl" "4.17.2" - "@rollup/rollup-linux-powerpc64le-gnu" "4.17.2" - "@rollup/rollup-linux-riscv64-gnu" "4.17.2" - "@rollup/rollup-linux-s390x-gnu" "4.17.2" - "@rollup/rollup-linux-x64-gnu" "4.17.2" - "@rollup/rollup-linux-x64-musl" "4.17.2" - "@rollup/rollup-win32-arm64-msvc" "4.17.2" - "@rollup/rollup-win32-ia32-msvc" "4.17.2" - "@rollup/rollup-win32-x64-msvc" "4.17.2" + "@rollup/rollup-android-arm-eabi" "4.24.0" + "@rollup/rollup-android-arm64" "4.24.0" + "@rollup/rollup-darwin-arm64" "4.24.0" + "@rollup/rollup-darwin-x64" "4.24.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.24.0" + "@rollup/rollup-linux-arm-musleabihf" "4.24.0" + "@rollup/rollup-linux-arm64-gnu" "4.24.0" + "@rollup/rollup-linux-arm64-musl" "4.24.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0" + "@rollup/rollup-linux-riscv64-gnu" "4.24.0" + "@rollup/rollup-linux-s390x-gnu" "4.24.0" + "@rollup/rollup-linux-x64-gnu" "4.24.0" + "@rollup/rollup-linux-x64-musl" "4.24.0" + "@rollup/rollup-win32-arm64-msvc" "4.24.0" + "@rollup/rollup-win32-ia32-msvc" "4.24.0" + "@rollup/rollup-win32-x64-msvc" "4.24.0" fsevents "~2.3.2" -shiki@1.5.0, shiki@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.5.0.tgz#32c5f2f6233a84e8f798ee7a2762dbbee3a6d7c3" - integrity sha512-AMax9zrUW8u8bnvNhnmAD9mHzk244mWCDBZm+zh4Ir3lzncF/sGUcVd5gpy0IlWvOKBUUJ8uu/BFpusGJ/PdVw== +shiki@1.22.0, shiki@^1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.22.0.tgz#45d1dfff0e03a598af70e2ec8592f14ef07827b4" + integrity sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw== dependencies: - "@shikijs/core" "1.5.0" + "@shikijs/core" "1.22.0" + "@shikijs/engine-javascript" "1.22.0" + "@shikijs/engine-oniguruma" "1.22.0" + "@shikijs/types" "1.22.0" + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + speakingurl@^14.0.1: version "14.0.1" resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53" integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ== +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +superjson@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/superjson/-/superjson-2.2.1.tgz#9377a7fa80fedb10c851c9dbffd942d4bcf79733" + integrity sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA== + dependencies: + copy-anything "^3.0.2" + tabbable@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== -vite@^5.2.10: - version "5.2.11" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.11.tgz#726ec05555431735853417c3c0bfb36003ca0cbd" - integrity sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== dependencies: - esbuild "^0.20.1" - postcss "^8.4.38" - rollup "^4.13.0" + "@types/unist" "^3.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== + dependencies: + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" + +vite@^5.4.8: + version "5.4.8" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.8.tgz#af548ce1c211b2785478d3ba3e8da51e39a287e8" + integrity sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" optionalDependencies: fsevents "~2.3.3" -vitepress@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.1.4.tgz#f715acab50059e0c75d1414fa1b8f31762f43804" - integrity sha512-bWIzFZXpPB6NIDBuWnS20aMADH+FcFKDfQNYFvbOWij03PR29eImTceQHIzCKordjXYBhM/TjE5VKFTUJ3EheA== - dependencies: - "@docsearch/css" "^3.6.0" - "@docsearch/js" "^3.6.0" - "@shikijs/core" "^1.3.0" - "@shikijs/transformers" "^1.3.0" - "@types/markdown-it" "^14.0.1" - "@vitejs/plugin-vue" "^5.0.4" - "@vue/devtools-api" "^7.0.27" - "@vueuse/core" "^10.9.0" - "@vueuse/integrations" "^10.9.0" - focus-trap "^7.5.4" +vitepress@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.4.0.tgz#5e879230d98e5c4e5aec91daade6945bbc18934b" + integrity sha512-JXCv4EsKTDyAFb6C/UjZr7nsGAzZ6mafVk2rx7rG5o8N+B/4QstIk+iEOe/9dKoU6V624UIC6g1pZ+K63rxhlw== + dependencies: + "@docsearch/css" "^3.6.2" + "@docsearch/js" "^3.6.2" + "@shikijs/core" "^1.22.0" + "@shikijs/transformers" "^1.22.0" + "@shikijs/types" "^1.22.0" + "@types/markdown-it" "^14.1.2" + "@vitejs/plugin-vue" "^5.1.4" + "@vue/devtools-api" "^7.4.6" + "@vue/shared" "^3.5.11" + "@vueuse/core" "^11.1.0" + "@vueuse/integrations" "^11.1.0" + focus-trap "^7.6.0" mark.js "8.11.1" - minisearch "^6.3.0" - shiki "^1.3.0" - vite "^5.2.10" - vue "^3.4.25" - -vue-demi@>=0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2" - integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA== - -vue@^3.4.25: - version "3.4.27" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.27.tgz#40b7d929d3e53f427f7f5945386234d2854cc2a1" - integrity sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA== - dependencies: - "@vue/compiler-dom" "3.4.27" - "@vue/compiler-sfc" "3.4.27" - "@vue/runtime-dom" "3.4.27" - "@vue/server-renderer" "3.4.27" - "@vue/shared" "3.4.27" + minisearch "^7.1.0" + shiki "^1.22.0" + vite "^5.4.8" + vue "^3.5.11" + +vue-demi@>=0.14.10: + version "0.14.10" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04" + integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== + +vue@^3.5.11: + version "3.5.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.11.tgz#3e307183797629f701e303a0a008f517ae031483" + integrity sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg== + dependencies: + "@vue/compiler-dom" "3.5.11" + "@vue/compiler-sfc" "3.5.11" + "@vue/runtime-dom" "3.5.11" + "@vue/server-renderer" "3.5.11" + "@vue/shared" "3.5.11" + +zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 371f3c5f9f..c37fc95df4 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2648,9 +2648,9 @@ electron-to-chromium@^1.3.47: integrity sha512-67V62Z4CFOiAtox+o+tosGfVk0QX4DJgH609tjT8QymbJZVAI/jWnAthnr8c5hnRNziIRwkc9EMQYejiVz3/9Q== elliptic@^6.5.3, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== dependencies: bn.js "^4.11.9" brorand "^1.1.0" diff --git a/global/certbot-dns-plugins.json b/global/certbot-dns-plugins.json index 606e7083cb..6729842e87 100644 --- a/global/certbot-dns-plugins.json +++ b/global/certbot-dns-plugins.json @@ -7,6 +7,14 @@ "credentials": "dns_acmedns_api_url = http://acmedns-server/\ndns_acmedns_registration_file = /data/acme-registration.json", "full_plugin_name": "dns-acmedns" }, + "active24":{ + "name": "Active24", + "package_name": "certbot-dns-active24", + "version": "~=1.5.1", + "dependencies": "", + "credentials": "dns_active24_token=\"TOKEN\"", + "full_plugin_name": "dns-active24" + }, "aliyun": { "name": "Aliyun", "package_name": "certbot-dns-aliyun", @@ -319,6 +327,14 @@ "credentials": "dns_luadns_email = user@example.com\ndns_luadns_token = 0123456789abcdef0123456789abcdef", "full_plugin_name": "dns-luadns" }, + "mijnhost": { + "name": "mijn.host", + "package_name": "certbot-dns-mijn-host", + "version": "~=0.0.4", + "dependencies": "", + "credentials": "dns-mijn-host-credentials = /etc/letsencrypt/mijnhost-credentials.ini", + "full_plugin_name": "dns-mijn-host" + }, "namecheap": { "name": "Namecheap", "package_name": "certbot-dns-namecheap", @@ -407,6 +423,14 @@ "credentials": "# Target DNS server\ndns_rfc2136_server = 192.0.2.1\n# Target DNS port\ndns_rfc2136_port = 53\n# TSIG key name\ndns_rfc2136_name = keyname.\n# TSIG key secret\ndns_rfc2136_secret = 4q4wM/2I180UXoMyN4INVhJNi8V9BCV+jMw2mXgZw/CSuxUT8C7NKKFs AmKd7ak51vWKgSl12ib86oQRPkpDjg==\n# TSIG key algorithm\ndns_rfc2136_algorithm = HMAC-SHA512", "full_plugin_name": "dns-rfc2136" }, + "rockenstein": { + "name": "rockenstein AG", + "package_name": "certbot-dns-rockenstein", + "version": "~=1.0.0", + "dependencies": "", + "credentials": "dns_rockenstein_token=", + "full_plugin_name": "dns-rockenstein" + }, "route53": { "name": "Route 53 (Amazon)", "package_name": "certbot-dns-route53", @@ -468,7 +492,15 @@ "package_name": "certbot-dns-wedos", "version": "~=2.2", "dependencies": "", - "credentials": "dns_wedos_user = \ndns_wedos_auth = ", + "credentials": "dns_wedos_user = \ndns_wedos_auth = ", "full_plugin_name": "dns-wedos" + }, + "edgedns": { + "name": "Akamai Edge DNS", + "package_name": "certbot-plugin-edgedns", + "version": "~=0.1.0", + "dependencies": "", + "credentials": "edgedns_client_secret = as3d1asd5d1a32sdfsdfs2d1asd5=\nedgedns_host = sdflskjdf-dfsdfsdf-sdfsdfsdf.luna.akamaiapis.net\nedgedns_access_token = kjdsi3-34rfsdfsdf-234234fsdfsdf\nedgedns_client_token = dkfjdf-342fsdfsd-23fsdfsdfsdf", + "full_plugin_name": "edgedns" } } diff --git a/scripts/.common.sh b/scripts/.common.sh index 3cea091671..4111db3b5c 100644 --- a/scripts/.common.sh +++ b/scripts/.common.sh @@ -15,3 +15,13 @@ COMPOSE_PROJECT_NAME="npmdev" COMPOSE_FILE="docker/docker-compose.dev.yml" export COMPOSE_FILE COMPOSE_PROJECT_NAME + +# $1: container_name +get_container_ip () { + local container_name=$1 + local container + local ip + container=$(docker-compose ps --all -q "${container_name}" | tail -n1) + ip=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container") + echo "$ip" +} diff --git a/scripts/ci/fulltest-cypress b/scripts/ci/fulltest-cypress index 7e4469fecd..9101189c2c 100755 --- a/scripts/ci/fulltest-cypress +++ b/scripts/ci/fulltest-cypress @@ -65,7 +65,7 @@ rm -rf "${LOCAL_RESOLVE}" printf "nameserver %s\noptions ndots:0" "${DNSROUTER_IP}" > "${LOCAL_RESOLVE}" # bring up all remaining containers, except cypress! -docker-compose up -d --remove-orphans stepca +docker-compose up -d --remove-orphans stepca squid docker-compose pull db-mysql || true # ok to fail docker-compose up -d --remove-orphans --pull=never fullstack diff --git a/scripts/test-dev b/scripts/cypress-dev similarity index 68% rename from scripts/test-dev rename to scripts/cypress-dev index f75527b7e0..a0c64ad969 100755 --- a/scripts/test-dev +++ b/scripts/cypress-dev @@ -6,8 +6,8 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Ensure docker-compose exists if hash docker-compose 2>/dev/null; then cd "${DIR}/.." - echo -e "${BLUE}❯ ${CYAN}Testing Dev Stack ...${RESET}" - docker-compose exec -T npm bash -c "cd /app && task test" + rm -rf "$DIR/../test/results" + docker-compose up --build cypress else echo -e "${RED}❯ docker-compose command is not available${RESET}" fi diff --git a/scripts/start-dev b/scripts/start-dev index f064a4bdfe..9da6ed4508 100755 --- a/scripts/start-dev +++ b/scripts/start-dev @@ -7,8 +7,43 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if hash docker-compose 2>/dev/null; then cd "${DIR}/.." echo -e "${BLUE}❯ ${CYAN}Starting Dev Stack ...${RESET}" + echo -e "${BLUE}❯ $(docker-compose config)${RESET}" - docker-compose up -d --remove-orphans --force-recreate --build + # Bring up a stack, in steps so we can inject IPs everywhere + docker-compose up -d pdns pdns-db + PDNS_IP=$(get_container_ip "pdns") + echo -e "${BLUE}❯ ${YELLOW}PDNS IP is ${PDNS_IP}${RESET}" + + # adjust the dnsrouter config + LOCAL_DNSROUTER_CONFIG="$DIR/../docker/dev/dnsrouter-config.json" + rm -rf "$LOCAL_DNSROUTER_CONFIG.tmp" + # IMPORTANT: changes to dnsrouter-config.json will affect this line: + jq --arg a "$PDNS_IP" '.servers[0].upstreams[1].upstream = $a' "$LOCAL_DNSROUTER_CONFIG" > "$LOCAL_DNSROUTER_CONFIG.tmp" + + docker-compose up -d dnsrouter + DNSROUTER_IP=$(get_container_ip "dnsrouter") + echo -e "${BLUE}❯ ${YELLOW}DNS Router IP is ${DNSROUTER_IP}" + + if [ "${DNSROUTER_IP:-}" = "" ]; then + echo -e "${RED}❯ ERROR: DNS Router IP is not set${RESET}" + exit 1 + fi + + # mount the resolver + LOCAL_RESOLVE="$DIR/../docker/dev/resolv.conf" + rm -rf "${LOCAL_RESOLVE}" + printf "nameserver %s\noptions ndots:0" "${DNSROUTER_IP}" > "${LOCAL_RESOLVE}" + + # bring up all remaining containers, except cypress! + docker-compose up -d --remove-orphans stepca squid + docker-compose pull db + docker-compose up -d --remove-orphans --pull=never fullstack + docker-compose up -d --remove-orphans swagger + + # docker-compose up -d --remove-orphans --force-recreate --build + + # wait for main container to be healthy + bash "$DIR/wait-healthy" "$(docker-compose ps --all -q fullstack)" 120 echo "" echo -e "${CYAN}Admin UI: http://127.0.0.1:3081${RESET}" diff --git a/test/cypress/config/ci.js b/test/cypress/config/ci.js index 2b50db1e85..dc968dbd37 100644 --- a/test/cypress/config/ci.js +++ b/test/cypress/config/ci.js @@ -15,8 +15,8 @@ module.exports = defineConfig({ return require("../plugins/index.js")(on, config); }, env: { - swaggerBase: '{{baseUrl}}/api/schema', + swaggerBase: '{{baseUrl}}/api/schema?ts=' + Date.now(), }, - baseUrl: 'http://localhost:1234', + baseUrl: 'http://fullstack:81', } }); diff --git a/test/cypress/config/dev.js b/test/cypress/config/dev.js deleted file mode 100644 index 90ae943bc9..0000000000 --- a/test/cypress/config/dev.js +++ /dev/null @@ -1,22 +0,0 @@ -const { defineConfig } = require('cypress'); - -module.exports = defineConfig({ - requestTimeout: 30000, - defaultCommandTimeout: 20000, - reporter: 'cypress-multi-reporters', - reporterOptions: { - configFile: 'multi-reporter.json' - }, - video: false, - videosFolder: 'results/videos', - screenshotsFolder: 'results/screenshots', - e2e: { - setupNodeEvents(on, config) { - return require("../plugins/index.js")(on, config); - }, - env: { - swaggerBase: '{{baseUrl}}/api/schema', - }, - baseUrl: 'http://localhost:1234', - } -}); diff --git a/test/cypress/e2e/api/Certificates.cy.js b/test/cypress/e2e/api/Certificates.cy.js new file mode 100644 index 0000000000..1e8a6fed44 --- /dev/null +++ b/test/cypress/e2e/api/Certificates.cy.js @@ -0,0 +1,99 @@ +/// + +describe('Certificates endpoints', () => { + let token; + let certID; + + before(() => { + cy.getToken().then((tok) => { + token = tok; + }); + }); + + it('Validate custom certificate', function() { + cy.task('backendApiPostFiles', { + token: token, + path: '/api/nginx/certificates/validate', + files: { + certificate: 'test.example.com.pem', + certificate_key: 'test.example.com-key.pem', + }, + }).then((data) => { + cy.validateSwaggerSchema('post', 200, '/nginx/certificates/validate', data); + expect(data).to.have.property('certificate'); + expect(data).to.have.property('certificate_key'); + }); + }); + + it('Custom certificate lifecycle', function() { + // Create custom cert + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/certificates', + data: { + provider: "other", + nice_name: "Test Certificate", + }, + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data); + expect(data).to.have.property('id'); + certID = data.id; + + // Upload files + cy.task('backendApiPostFiles', { + token: token, + path: `/api/nginx/certificates/${certID}/upload`, + files: { + certificate: 'test.example.com.pem', + certificate_key: 'test.example.com-key.pem', + }, + }).then((data) => { + cy.validateSwaggerSchema('post', 200, '/nginx/certificates/{certID}/upload', data); + expect(data).to.have.property('certificate'); + expect(data).to.have.property('certificate_key'); + + // Get all certs + cy.task('backendApiGet', { + token: token, + path: '/api/nginx/certificates?expand=owner' + }).then((data) => { + cy.validateSwaggerSchema('get', 200, '/nginx/certificates', data); + expect(data.length).to.be.greaterThan(0); + + // Delete cert + cy.task('backendApiDelete', { + token: token, + path: `/api/nginx/certificates/${certID}` + }).then((data) => { + cy.validateSwaggerSchema('delete', 200, '/nginx/certificates/{certID}', data); + expect(data).to.be.equal(true); + }); + }); + }); + }); + }); + + it('Request Certificate - CVE-2024-46256/CVE-2024-46257', function() { + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/certificates', + data: { + domain_names: ['test.com"||echo hello-world||\\\\n test.com"'], + meta: { + dns_challenge: false, + letsencrypt_agree: true, + letsencrypt_email: 'admin@example.com', + }, + provider: 'letsencrypt', + }, + returnOnError: true, + }).then((data) => { + cy.validateSwaggerSchema('post', 400, '/nginx/certificates', data); + expect(data).to.have.property('error'); + expect(data.error).to.have.property('message'); + expect(data.error).to.have.property('code'); + expect(data.error.code).to.equal(400); + expect(data.error.message).to.contain('data/domain_names/0 must match pattern'); + }); + }); +}); diff --git a/test/cypress/e2e/api/FullCertProvision.cy.js b/test/cypress/e2e/api/FullCertProvision.cy.js new file mode 100644 index 0000000000..5ca5692cdf --- /dev/null +++ b/test/cypress/e2e/api/FullCertProvision.cy.js @@ -0,0 +1,62 @@ +/// + +describe('Full Certificate Provisions', () => { + let token; + + before(() => { + cy.getToken().then((tok) => { + token = tok; + }); + }); + + it('Should be able to create new http certificate', function() { + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/certificates', + data: { + domain_names: [ + 'website1.example.com' + ], + meta: { + letsencrypt_email: 'admin@example.com', + letsencrypt_agree: true, + dns_challenge: false + }, + provider: 'letsencrypt' + } + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.greaterThan(0); + expect(data.provider).to.be.equal('letsencrypt'); + }); + }); + + it('Should be able to create new DNS certificate with Powerdns', function() { + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/certificates', + data: { + domain_names: [ + 'website2.example.com' + ], + meta: { + letsencrypt_email: "admin@example.com", + dns_challenge: true, + dns_provider: 'powerdns', + dns_provider_credentials: 'dns_powerdns_api_url = http://ns1.pdns:8081\r\ndns_powerdns_api_key = npm', + letsencrypt_agree: true, + propagation_seconds: 5, + }, + provider: 'letsencrypt' + } + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/certificates', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.greaterThan(0); + expect(data.provider).to.be.equal('letsencrypt'); + expect(data.meta.dns_provider).to.be.equal('powerdns'); + }); + }); + +}); diff --git a/test/cypress/e2e/api/Health.cy.js b/test/cypress/e2e/api/Health.cy.js index 5538916cb2..49881e97b4 100644 --- a/test/cypress/e2e/api/Health.cy.js +++ b/test/cypress/e2e/api/Health.cy.js @@ -1,4 +1,4 @@ -/// +/// describe('Basic API checks', () => { it('Should return a valid health payload', function () { @@ -12,9 +12,9 @@ describe('Basic API checks', () => { it('Should return a valid schema payload', function () { cy.task('backendApiGet', { - path: '/api/schema', + path: '/api/schema?ts=' + Date.now(), }).then((data) => { - expect(data.openapi).to.be.equal('3.0.0'); + expect(data.openapi).to.be.equal('3.1.0'); }); }); }); diff --git a/test/cypress/e2e/api/Hosts.cy.js b/test/cypress/e2e/api/ProxyHosts.cy.js similarity index 90% rename from test/cypress/e2e/api/Hosts.cy.js rename to test/cypress/e2e/api/ProxyHosts.cy.js index 4652c8e081..5bc6458005 100644 --- a/test/cypress/e2e/api/Hosts.cy.js +++ b/test/cypress/e2e/api/ProxyHosts.cy.js @@ -1,6 +1,6 @@ -/// +/// -describe('Hosts endpoints', () => { +describe('Proxy Hosts endpoints', () => { let token; before(() => { @@ -39,7 +39,7 @@ describe('Hosts endpoints', () => { expect(data).to.have.property('id'); expect(data.id).to.be.greaterThan(0); expect(data).to.have.property('enabled'); - expect(data.enabled).to.be.greaterThan(0); + expect(data).to.have.property("enabled", true); expect(data).to.have.property('meta'); expect(typeof data.meta.nginx_online).to.be.equal('undefined'); }); diff --git a/test/cypress/e2e/api/Settings.cy.js b/test/cypress/e2e/api/Settings.cy.js new file mode 100644 index 0000000000..6942760c77 --- /dev/null +++ b/test/cypress/e2e/api/Settings.cy.js @@ -0,0 +1,124 @@ +/// + +describe('Settings endpoints', () => { + let token; + + before(() => { + cy.getToken().then((tok) => { + token = tok; + }); + }); + + it('Get all settings', function() { + cy.task('backendApiGet', { + token: token, + path: '/api/settings', + }).then((data) => { + cy.validateSwaggerSchema('get', 200, '/settings', data); + expect(data.length).to.be.greaterThan(0); + }); + }); + + it('Get default-site setting', function() { + cy.task('backendApiGet', { + token: token, + path: '/api/settings/default-site', + }).then((data) => { + cy.validateSwaggerSchema('get', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + }); + }); + + it('Default Site congratulations', function() { + cy.task('backendApiPut', { + token: token, + path: '/api/settings/default-site', + data: { + value: 'congratulations', + }, + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + expect(data).to.have.property('value'); + expect(data.value).to.be.equal('congratulations'); + }); + }); + + it('Default Site 404', function() { + cy.task('backendApiPut', { + token: token, + path: '/api/settings/default-site', + data: { + value: '404', + }, + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + expect(data).to.have.property('value'); + expect(data.value).to.be.equal('404'); + }); + }); + + it('Default Site 444', function() { + cy.task('backendApiPut', { + token: token, + path: '/api/settings/default-site', + data: { + value: '444', + }, + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + expect(data).to.have.property('value'); + expect(data.value).to.be.equal('444'); + }); + }); + + it('Default Site redirect', function() { + cy.task('backendApiPut', { + token: token, + path: '/api/settings/default-site', + data: { + value: 'redirect', + meta: { + redirect: 'https://www.google.com', + }, + }, + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + expect(data).to.have.property('value'); + expect(data.value).to.be.equal('redirect'); + expect(data).to.have.property('meta'); + expect(data.meta).to.have.property('redirect'); + expect(data.meta.redirect).to.be.equal('https://www.google.com'); + }); + }); + + it('Default Site html', function() { + cy.task('backendApiPut', { + token: token, + path: '/api/settings/default-site', + data: { + value: 'html', + meta: { + html: '

hello world

' + }, + }, + }).then((data) => { + cy.validateSwaggerSchema('put', 200, '/settings/{settingID}', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.equal('default-site'); + expect(data).to.have.property('value'); + expect(data.value).to.be.equal('html'); + expect(data).to.have.property('meta'); + expect(data.meta).to.have.property('html'); + expect(data.meta.html).to.be.equal('

hello world

'); + }); + }); +}); diff --git a/test/cypress/e2e/api/Users.cy.js b/test/cypress/e2e/api/Users.cy.js index 43303d431b..06b1831760 100644 --- a/test/cypress/e2e/api/Users.cy.js +++ b/test/cypress/e2e/api/Users.cy.js @@ -1,4 +1,4 @@ -/// +/// describe('Users endpoints', () => { let token; diff --git a/test/cypress/fixtures/test.example.com-key.pem b/test/cypress/fixtures/test.example.com-key.pem new file mode 100644 index 0000000000..307cdc307b --- /dev/null +++ b/test/cypress/fixtures/test.example.com-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1n9j9C5Bes1nd +qACDckERauxXVNKCnUlUM1buGBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2w +rbmvZvLuPmXePOKbIKS+XXh+2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHge +Yz6Cv/Si2/LJPCh/CoBfM4hUQJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQ +oxRAHiOR9081Xn1WeoKr7kVBIa5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7Z +Eo+nS8Wr/4QWicatIWZXpVaEOPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79X +zGONeH1PAgMBAAECggEAANb3Wtwl07pCjRrMvc7WbC0xYIn82yu8/g2qtjkYUJcU +ia5lQbYN7RGCS85Oc/tkq48xQEG5JQWNH8b918jDEMTrFab0aUEyYcru1q9L8PL6 +YHaNgZSrMrDcHcS8h0QOXNRJT5jeGkiHJaTR0irvB526tqF3knbK9yW22KTfycUe +a0Z9voKn5xRk1DCbHi/nk2EpT7xnjeQeLFaTIRXbS68omkr4YGhwWm5OizoyEGZu +W0Zum5BkQyMr6kor3wdxOTG97ske2rcyvvHi+ErnwL0xBv0qY0Dhe8DpuXpDezqw +o72yY8h31Fu84i7sAj24YuE5Df8DozItFXQpkgbQ6QKBgQDPrufhvIFm2S/MzBdW +H8JxY7CJlJPyxOvc1NIl9RczQGAQR90kx52cgIcuIGEG6/wJ/xnGfMmW40F0DnQ+ +N+oLgB9SFxeLkRb7s9Z/8N3uIN8JJFYcerEOiRQeN2BXEEWJ7bUThNtsVrAcKoUh +ELsDmnHW/3V+GKwhd0vpk842+wKBgQDf4PGLG9PTE5tlAoyHFodJRd2RhTJQkwsU +MDNjLJ+KecLv+Nl+QiJhoflG1ccqtSFlBSCG067CDQ5LV0xm3mLJ7pfJoMgjcq31 +qjEmX4Ls91GuVOPtbwst3yFKjsHaSoKB5fBvWRcKFpBUezM7Qcw2JP3+dQT+bQIq +cMTkRWDSvQKBgQDOdCQFDjxg/lR7NQOZ1PaZe61aBz5P3pxNqa7ClvMaOsuEQ7w9 +vMYcdtRq8TsjA2JImbSI0TIg8gb2FQxPcYwTJKl+FICOeIwtaSg5hTtJZpnxX5LO +utTaC0DZjNkTk5RdOdWA8tihyUdGqKoxJY2TVmwGe2rUEDjFB++J4inkEwKBgB6V +g0nmtkxanFrzOzFlMXwgEEHF+Xaqb9QFNa/xs6XeNnREAapO7JV75Cr6H2hFMFe1 +mJjyqCgYUoCWX3iaHtLJRnEkBtNY4kzyQB6m46LtsnnnXO/dwKA2oDyoPfFNRoDq +YatEd3JIXNU9s2T/+x7WdOBjKhh72dTkbPFmTPDdAoGAU6rlPBevqOFdObYxdPq8 +EQWu44xqky3Mf5sBpOwtu6rqCYuziLiN7K4sjN5GD5mb1cEU+oS92ZiNcUQ7MFXk +8yTYZ7U0VcXyAcpYreWwE8thmb0BohJBr+Mp3wLTx32x0HKdO6vpUa0d35LUTUmM +RrKmPK/msHKK/sVHiL+NFqo= +-----END PRIVATE KEY----- diff --git a/test/cypress/fixtures/test.example.com.pem b/test/cypress/fixtures/test.example.com.pem new file mode 100644 index 0000000000..16340cdfd2 --- /dev/null +++ b/test/cypress/fixtures/test.example.com.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEYDCCAsigAwIBAgIRAPoSC0hvitb26ODMlsH6YbowDQYJKoZIhvcNAQELBQAw +gZExHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTEzMDEGA1UECwwqamN1 +cm5vd0BKYW1pZXMtTGFwdG9wLmxvY2FsIChKYW1pZSBDdXJub3cpMTowOAYDVQQD +DDFta2NlcnQgamN1cm5vd0BKYW1pZXMtTGFwdG9wLmxvY2FsIChKYW1pZSBDdXJu +b3cpMB4XDTI0MTAwOTA3MjIxN1oXDTI3MDEwOTA3MjIxN1owXjEnMCUGA1UEChMe +bWtjZXJ0IGRldmVsb3BtZW50IGNlcnRpZmljYXRlMTMwMQYDVQQLDCpqY3Vybm93 +QEphbWllcy1MYXB0b3AubG9jYWwgKEphbWllIEN1cm5vdykwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC1n9j9C5Bes1ndqACDckERauxXVNKCnUlUM1bu +GBx1xc+j2e2Ar23wUJJuWBY18VfT8yqfqVDktO2wrbmvZvLuPmXePOKbIKS+XXh+ +2NG9L5bDG9rwGFCRXnbQj+GWCdMfzx14+CR1IHgeYz6Cv/Si2/LJPCh/CoBfM4hU +QJON3lxAWrWBpdbZnKYMrxuPBRfW9OuzTbCVXToQoxRAHiOR9081Xn1WeoKr7kVB +Ia5UphlvWXa12w1YmUwJu7YndnJGIavLWeNCVc7ZEo+nS8Wr/4QWicatIWZXpVaE +OPhRoeplQDxNWg5b/Q26rYoVd7PrCmRs7sVcH79XzGONeH1PAgMBAAGjZTBjMA4G +A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBSB +/vfmBUd4W7CvyEMl7YpMVQs8vTAbBgNVHREEFDASghB0ZXN0LmV4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBgQASwON/jPAHzcARSenY0ZGY1m5OVTYoQ/JWH0oy +l8SyFCQFEXt7UHDD/eTtLT0vMyc190nP57P8lTnZGf7hSinZz1B1d6V4cmzxpk0s +VXZT+irL6bJVJoMBHRpllKAhGULIo33baTrWFKA0oBuWx4AevSWKcLW5j87kEawn +ATCuMQ1I3ifR1mSlB7X8fb+vF+571q0NGuB3a42j6rdtXJ6SmH4+9B4qO0sfHDNt +IImpLCH/tycDpcYrGSCn1QrekFG1bSEh+Bb9i8rqMDSDsYrTFPZTuOQ3EtjGni9u +m+rEP3OyJg+md8c+0LVP7/UU4QWWnw3/Wolo5kSCxE8vNTFqi4GhVbdLnUtcIdTV +XxuR6cKyW87Snj1a0nG76ZLclt/akxDhtzqeV60BO0p8pmiev8frp+E94wFNYCmp +1cr3CnMEGRaficLSDFC6EBENzlZW2BQT6OMIV+g0NBgSyQe39s2zcdEl5+SzDVuw +hp8bJUp/QN7pnOVCDbjTQ+HVMXw= +-----END CERTIFICATE----- diff --git a/test/cypress/plugins/backendApi/client.js b/test/cypress/plugins/backendApi/client.js index 29684cfdc9..6f5f7661ea 100644 --- a/test/cypress/plugins/backendApi/client.js +++ b/test/cypress/plugins/backendApi/client.js @@ -1,9 +1,14 @@ const logger = require('./logger'); -const restler = require('@jc21/restler'); +const axios = require('axios').default; const BackendApi = function(config, token) { this.config = config; this.token = token; + + this.axios = axios.create({ + baseURL: config.baseUrl, + timeout: 90000, + }); }; /** @@ -14,128 +19,113 @@ BackendApi.prototype.setToken = function(token) { }; /** - * @param {string} path - * @param {bool} [returnOnError] - * @returns {Promise} + * @param {bool} returnOnError */ -BackendApi.prototype.get = function(path, returnOnError) { - return new Promise((resolve, reject) => { - let headers = { +BackendApi.prototype._prepareOptions = function(returnOnError) { + let options = { + headers: { Accept: 'application/json' - }; - if (this.token) { - headers.Authorization = 'Bearer ' + this.token; } - - logger('GET ', this.config.baseUrl + path); - - restler - .get(this.config.baseUrl + path, { - headers: headers, - }) - .on('complete', function(data, response) { - logger('Response data:', data); - if (!returnOnError && data instanceof Error) { - reject(data); - } else if (!returnOnError && response.statusCode != 200) { - if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') { - reject(new Error(data.error.code + ': ' + data.error.message)); - } else { - reject(new Error('Error ' + response.statusCode)); - } - } else { - resolve(data); - } - }); - }); + } + if (this.token) { + options.headers.Authorization = 'Bearer ' + this.token; + } + if (returnOnError) { + options.validateStatus = function () { + return true; + } + } + return options; }; /** - * @param {string} path - * @param {bool} [returnOnError] - * @returns {Promise} + * @param {*} response + * @param {function} resolve + * @param {function} reject + * @param {bool} returnOnError */ -BackendApi.prototype.delete = function(path, returnOnError) { - return new Promise((resolve, reject) => { - let headers = { - Accept: 'application/json' - }; - if (this.token) { - headers.Authorization = 'Bearer ' + this.token; +BackendApi.prototype._handleResponse = function(response, resolve, reject, returnOnError) { + logger('Response data:', response.data); + if (!returnOnError && typeof response.data === 'object' && typeof response.data.error === 'object') { + if (typeof response.data === 'object' && typeof response.data.error === 'object' && typeof response.data.error.message !== 'undefined') { + reject(new Error(response.data.error.code + ': ' + response.data.error.message)); + } else { + reject(new Error('Error ' + response.status)); } - - logger('DELETE ', this.config.baseUrl + path); - - restler - .del(this.config.baseUrl + path, { - headers: headers, - }) - .on('complete', function(data, response) { - logger('Response data:', data); - if (!returnOnError && data instanceof Error) { - reject(data); - } else if (!returnOnError && response.statusCode != 200) { - if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') { - reject(new Error(data.error.code + ': ' + data.error.message)); - } else { - reject(new Error('Error ' + response.statusCode)); - } - } else { - resolve(data); - } - }); - }); + } else { + resolve(response.data); + } }; /** - * @param {string} path - * @param {object} data - * @param {bool} [returnOnError] - * @returns {Promise} + * @param {*} err + * @param {function} resolve + * @param {function} reject + * @param {bool} returnOnError */ -BackendApi.prototype.postJson = function(path, data, returnOnError) { - logger('POST ', this.config.baseUrl + path); - return this._putPostJson('postJson', path, data, returnOnError); +BackendApi.prototype._handleError = function(err, resolve, reject, returnOnError) { + logger('Axios Error:', err); + if (returnOnError) { + resolve(typeof err.response.data !== 'undefined' ? err.response.data : err); + } else { + reject(err); + } }; /** + * @param {string} method * @param {string} path - * @param {object} data * @param {bool} [returnOnError] + * @param {*} [data] * @returns {Promise} */ -BackendApi.prototype.putJson = function(path, data, returnOnError) { - logger('PUT ', this.config.baseUrl + path); - return this._putPostJson('putJson', path, data, returnOnError); +BackendApi.prototype.request = function (method, path, returnOnError, data) { + logger(method.toUpperCase(), path); + const options = this._prepareOptions(returnOnError); + + return new Promise((resolve, reject) => { + let opts = { + method: method, + url: path, + ...options + } + if (data !== undefined && data !== null) { + opts.data = data; + } + + this.axios(opts) + .then((response) => { + this._handleResponse(response, resolve, reject, returnOnError); + }) + .catch((err) => { + this._handleError(err, resolve, reject, returnOnError); + }); + }); }; /** * @param {string} path - * @param {object} data + * @param {form} form * @param {bool} [returnOnError] * @returns {Promise} */ -BackendApi.prototype._putPostJson = function(fn, path, data, returnOnError) { +BackendApi.prototype.postForm = function (path, form, returnOnError) { + logger('POST', this.config.baseUrl + path); + const options = this._prepareOptions(returnOnError); + return new Promise((resolve, reject) => { - restler[fn](this.config.baseUrl + path, data, { - headers: { - Accept: 'application/json', - Authorization: 'Bearer ' + this.token, - }, - }).on('complete', function(data, response) { - logger('Response data:', data); - if (!returnOnError && data instanceof Error) { - reject(data); - } else if (!returnOnError && (response.statusCode < 200 || response.statusCode >= 300)) { - if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') { - reject(new Error(data.error.code + ': ' + data.error.message)); - } else { - reject(new Error('Error ' + response.statusCode)); - } - } else { - resolve(data); - } - }); + const opts = { + ...options, + ...form.getHeaders(), + } + + this.axios.post(path, form, opts) + .then((response) => { + this._handleResponse(response, resolve, reject, returnOnError); + }) + .catch((err) => { + this._handleError(err, resolve, reject, returnOnError); + }); }); }; diff --git a/test/cypress/plugins/backendApi/logger.js b/test/cypress/plugins/backendApi/logger.js index 98efa260ed..8920b86929 100644 --- a/test/cypress/plugins/backendApi/logger.js +++ b/test/cypress/plugins/backendApi/logger.js @@ -1,12 +1,7 @@ const _ = require("lodash"); -const chalk = require("chalk"); module.exports = function() { - var arr = _.values(arguments); - arr.unshift( - chalk.blue.bold("[") + - chalk.yellow.bold("Backend API") + - chalk.blue.bold("]"), - ); + let arr = _.values(arguments); + arr.unshift('[Backend API]'); console.log.apply(null, arr); }; diff --git a/test/cypress/plugins/backendApi/task.js b/test/cypress/plugins/backendApi/task.js index 2f67902d5d..ab9704f4a6 100644 --- a/test/cypress/plugins/backendApi/task.js +++ b/test/cypress/plugins/backendApi/task.js @@ -1,8 +1,9 @@ +const fs = require('fs'); +const FormData = require('form-data'); const logger = require('./logger'); const Client = require('./client'); module.exports = function (config) { - logger('Client Ready using', config.baseUrl); return { @@ -17,7 +18,7 @@ module.exports = function (config) { backendApiGet: (options) => { const api = new Client(config); api.setToken(options.token); - return api.get(options.path, options.returnOnError || false); + return api.request('get', options.path, options.returnOnError || false); }, /** @@ -31,7 +32,26 @@ module.exports = function (config) { backendApiPost: (options) => { const api = new Client(config); api.setToken(options.token); - return api.postJson(options.path, options.data, options.returnOnError || false); + return api.request('post', options.path, options.returnOnError || false, options.data); + }, + + /** + * @param {object} options + * @param {string} options.token JWT + * @param {string} options.path API path + * @param {object} options.files + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiPostFiles: (options) => { + const api = new Client(config); + api.setToken(options.token); + + const form = new FormData(); + for (let [key, value] of Object.entries(options.files)) { + form.append(key, fs.createReadStream(config.fixturesFolder + '/' + value)); + } + return api.postForm(options.path, form, options.returnOnError || false); }, /** @@ -45,7 +65,7 @@ module.exports = function (config) { backendApiPut: (options) => { const api = new Client(config); api.setToken(options.token); - return api.putJson(options.path, options.data, options.returnOnError || false); + return api.request('put', options.path, options.returnOnError || false, options.data); }, /** @@ -58,7 +78,7 @@ module.exports = function (config) { backendApiDelete: (options) => { const api = new Client(config); api.setToken(options.token); - return api.delete(options.path, options.returnOnError || false); + return api.request('delete', options.path, options.returnOnError || false); } }; -}; \ No newline at end of file +}; diff --git a/test/cypress/plugins/index.js b/test/cypress/plugins/index.js index 8cf6eef6c5..2f3e3c5af3 100644 --- a/test/cypress/plugins/index.js +++ b/test/cypress/plugins/index.js @@ -1,4 +1,4 @@ -const {SwaggerValidation} = require('@jc21/cypress-swagger-validation'); +const { SwaggerValidation } = require('@jc21/cypress-swagger-validation'); module.exports = (on, config) => { // Replace swaggerBase config var wildcard diff --git a/test/package.json b/test/package.json index b0f6ba79d4..b52ecfbd73 100644 --- a/test/package.json +++ b/test/package.json @@ -1,26 +1,26 @@ { - "name": "test", + "name": "npm-test", "version": "1.0.0", "description": "", "main": "index.js", "dependencies": { - "@jc21/cypress-swagger-validation": "^0.2.6", - "@jc21/restler": "^3.4.0", - "chalk": "^4.1.0", - "cypress": "^13.9.0", + "@jc21/cypress-swagger-validation": "^0.3.1", + "axios": "^1.7.7", + "cypress": "^13.15.0", "cypress-multi-reporters": "^1.6.4", - "cypress-wait-until": "^3.0.1", - "eslint": "^9.3.0", + "cypress-wait-until": "^3.0.2", + "eslint": "^9.12.0", "eslint-plugin-align-assignments": "^1.1.2", - "eslint-plugin-chai-friendly": "^0.7.4", - "eslint-plugin-cypress": "^3.2.0", + "eslint-plugin-chai-friendly": "^1.0.1", + "eslint-plugin-cypress": "^3.5.0", + "form-data": "^4.0.1", "lodash": "^4.17.21", - "mocha": "^10.4.0", + "mocha": "^10.7.3", "mocha-junit-reporter": "^2.2.1" }, "scripts": { - "cypress": "cypress open --config-file=cypress/config/dev.json --config baseUrl=${BASE_URL:-http://127.0.0.1:3081}", - "cypress:headless": "cypress run --config-file=cypress/config/dev.json --config baseUrl=${BASE_URL:-http://127.0.0.1:3081}" + "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" }, "author": "", "license": "ISC" diff --git a/test/yarn.lock b/test/yarn.lock index 943147b019..4fa9e51f98 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -11,14 +11,13 @@ call-me-maybe "^1.0.1" js-yaml "^3.13.1" -"@apidevtools/json-schema-ref-parser@9.0.9": - version "9.0.9" - resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b" - integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w== +"@apidevtools/json-schema-ref-parser@^11.7.2": + version "11.7.2" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz#cdf3e0aded21492364a70e193b45b7cf4177f031" + integrity sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA== dependencies: "@jsdevtools/ono" "^7.1.3" - "@types/json-schema" "^7.0.6" - call-me-maybe "^1.0.1" + "@types/json-schema" "^7.0.15" js-yaml "^4.1.0" "@apidevtools/openapi-schemas@^2.1.0": @@ -49,10 +48,10 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cypress/request@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960" - integrity sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ== +"@cypress/request@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.5.tgz#d893a6e68ce2636c085fcd8d7283c3186499ba63" + integrity sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -60,14 +59,14 @@ combined-stream "~1.0.6" extend "~3.0.2" forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" + form-data "~4.0.0" + http-signature "~1.4.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" mime-types "~2.1.19" performance-now "^2.1.0" - qs "6.10.4" + qs "6.13.0" safe-buffer "^5.1.2" tough-cookie "^4.1.3" tunnel-agent "^0.6.0" @@ -88,10 +87,24 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== +"@eslint-community/regexpp@^4.11.0": + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + +"@eslint/config-array@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" + integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== + dependencies: + "@eslint/object-schema" "^2.1.4" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.6.0.tgz#9930b5ba24c406d67a1760e94cdbac616a6eb674" + integrity sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg== "@eslint/eslintrc@^3.1.0": version "3.1.0" @@ -108,91 +121,82 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.3.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.3.0.tgz#2e8f65c9c55227abc4845b1513c69c32c679d8fe" - integrity sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw== +"@eslint/js@9.12.0": + version "9.12.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.12.0.tgz#69ca3ca9fab9a808ec6d67b8f6edb156cbac91e1" + integrity sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA== + +"@eslint/object-schema@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" + integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== +"@eslint/plugin-kit@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz#8712dccae365d24e9eeecb7b346f85e750ba343d" + integrity sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig== dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.1" - minimatch "^3.0.5" + levn "^0.4.1" + +"@humanfs/core@^0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.0.tgz#08db7a8c73bb07673d9ebd925f2dad746411fcec" + integrity sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw== + +"@humanfs/node@^0.16.5": + version "0.16.5" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.5.tgz#a9febb7e7ad2aff65890fdc630938f8d20aa84ba" + integrity sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg== + dependencies: + "@humanfs/core" "^0.19.0" + "@humanwhocodes/retry" "^0.3.0" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== - "@humanwhocodes/retry@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.0.tgz#6d86b8cb322660f03d3f0aa94b99bdd8e172d570" integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew== -"@jc21/cypress-swagger-validation@^0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.2.6.tgz#8b61f2413fa81cae6f8c2f33ecce5a6ded897030" - integrity sha512-8i8poTwi13e4BRKWpvmXFmqvEfQq3Kn9tunWhNYT7IQwiMeUVou+g1yh99QzuI501DBPtL2XEwjNukxTf5GiyQ== +"@humanwhocodes/retry@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@jc21/cypress-swagger-validation@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.3.1.tgz#1cdd49850a20f876ed62149623f99988264751be" + integrity sha512-Vdt1gLfj8p0tJhA42Cfn43XBbsKocNfVCEVSwkn7RmZgWUyRKjqhBBRTVa9cKZTozyg8Co/yhBMsNyjmHFVXtQ== dependencies: + "@apidevtools/json-schema-ref-parser" "^11.7.2" "@apidevtools/swagger-parser" "^10.1.0" - ajv "^8.12.0" + ajv "^8.17.1" + axios "^1.7.7" json-schema "^0.4.0" - json-schema-ref-parser "^9.0.6" jsonpath "^1.1.1" lodash "^4.17.21" openapi-types "^12.1.3" - picocolors "^1.0.0" - -"@jc21/restler@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@jc21/restler/-/restler-3.4.0.tgz#cfa214ddb9946a800c6fe472529f72b01e93c763" - integrity sha512-P1Nl2ifoQwqtxcqJKYHvxgPfckeIZWbVSYMlNAP+cL2KNk3U5eErPKt4xr5YLIQ+NarFsHMGH8+CBa00FKAGrw== - dependencies: - iconv-lite "0.2.11" - qs "1.2.0" - xml2js "0.4.0" - yaml "0.2.3" + picocolors "^1.1.0" "@jsdevtools/ono@^7.1.3": version "7.1.3" resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/json-schema@^7.0.6": +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -229,6 +233,11 @@ acorn@^8.11.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.12.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -252,7 +261,17 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.12.0, ajv@^8.6.3: +ajv@^8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ajv@^8.6.3: version "8.13.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== @@ -262,11 +281,16 @@ ajv@^8.12.0, ajv@^8.6.3: require-from-string "^2.0.2" uri-js "^4.4.1" -ansi-colors@4.1.1, ansi-colors@^4.1.1: +ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -366,6 +390,15 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -414,13 +447,13 @@ brace-expansion@^2.0.1: balanced-match "^1.0.0" braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" -browser-stdout@1.3.1: +browser-stdout@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== @@ -443,13 +476,16 @@ cachedir@^2.3.0: resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" call-me-maybe@^1.0.1: version "1.0.1" @@ -489,10 +525,10 @@ check-more-types@^2.24.0: resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -564,7 +600,7 @@ colorette@^2.0.16: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -613,17 +649,17 @@ cypress-multi-reporters@^1.6.4: debug "^4.3.4" lodash "^4.17.21" -cypress-wait-until@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cypress-wait-until/-/cypress-wait-until-3.0.1.tgz#6a697a600f4fb8cd2897489a15fda77c9857abec" - integrity sha512-kpoa8yL6Bi/JNsThGBbrrm7g4SNzYyBUv9M5pF6/NTVm/ClY0HnJzeuWnHiAUZKIZ5l86Oedb12wQyjx7/CWPg== +cypress-wait-until@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/cypress-wait-until/-/cypress-wait-until-3.0.2.tgz#c90dddfa4c46a2c422f5b91d486531c560bae46e" + integrity sha512-iemies796dD5CgjG5kV0MnpEmKSH+s7O83ZoJLVzuVbZmm4lheMsZqAVT73hlMx4QlkwhxbyUzhOBUOZwoOe0w== -cypress@^13.9.0: - version "13.9.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.9.0.tgz#b529cfa8f8c39ba163ed0501a25bb5b09c143652" - integrity sha512-atNjmYfHsvTuCaxTxLZr9xGoHz53LLui3266WWxXJHY7+N6OdwJdg/feEa3T+buez9dmUXHT1izCOklqG82uCQ== +cypress@^13.15.0: + version "13.15.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.15.0.tgz#5eca5387ef34b2e611cfa291967c69c2cd39381d" + integrity sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw== dependencies: - "@cypress/request" "^3.0.0" + "@cypress/request" "^3.0.4" "@cypress/xvfb" "^1.2.4" "@types/sinonjs__fake-timers" "8.1.1" "@types/sizzle" "^2.3.2" @@ -662,7 +698,7 @@ cypress@^13.9.0: request-progress "^3.0.0" semver "^7.5.3" supports-color "^8.1.1" - tmp "~0.2.1" + tmp "~0.2.3" untildify "^4.0.0" yauzl "^2.10.0" @@ -678,13 +714,6 @@ dayjs@^1.10.4: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== -debug@4.3.4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -699,6 +728,20 @@ debug@^4.1.1: dependencies: ms "^2.1.1" +debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^4.3.5: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -709,15 +752,24 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== ecc-jsbn@~0.1.1: version "0.1.2" @@ -746,21 +798,33 @@ enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + escalade@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.8.1: version "1.12.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" @@ -778,22 +842,22 @@ eslint-plugin-align-assignments@^1.1.2: resolved "https://registry.yarnpkg.com/eslint-plugin-align-assignments/-/eslint-plugin-align-assignments-1.1.2.tgz#83e1a8a826d4adf29e82b52d0bb39c88b301b576" integrity sha512-I1ZJgk9EjHfGVU9M2Ex8UkVkkjLL5Y9BS6VNnQHq79eHj2H4/Cgxf36lQSUTLgm2ntB03A2NtF+zg9fyi5vChg== -eslint-plugin-chai-friendly@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.4.tgz#eaf222b848673ef8a00b8e507f7c6fd83d036bf2" - integrity sha512-PGPjJ8diYgX1mjLxGJqRop2rrGwZRKImoEOwUOgoIhg0p80MkTaqvmFLe5TF7/iagZHggasvIfQlUyHIhK/PYg== +eslint-plugin-chai-friendly@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-1.0.1.tgz#c3290b5294c1145934cf9c07eaa4cec87921d18c" + integrity sha512-dxD/uz1YKJ8U4yah1i+V/p/u+kHRy3YxTPe2nJGqb5lCR+ucan/KIexfZ5+q4X+tkllyMe86EBbAkdlwxNy3oQ== -eslint-plugin-cypress@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-3.2.0.tgz#fe2dd9c99ed5dfed5c7be658801e75ed3d9c2265" - integrity sha512-HaxMz6BoU4ay+K4WrG9ZJC1NdX06FqSlAwtRDStjM0ORFT7zCNPNuRJ+kUPc17Rt2AMUBSqeD9L0zTR3uZhPpw== +eslint-plugin-cypress@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-3.5.0.tgz#380ef5049ad80ebeca923db69e4aa96e72fcd893" + integrity sha512-JZQ6XnBTNI8h1B9M7wJSFzc48SYbh7VMMKaNTQOFa3BQlnmXPrVc4PKen8R+fpv6VleiPeej6VxloGb42zdRvw== dependencies: globals "^13.20.0" -eslint-scope@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc" - integrity sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og== +eslint-scope@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.1.0.tgz#70214a174d4cbffbc3e8a26911d8bf51b9ae9d30" + integrity sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -808,28 +872,37 @@ eslint-visitor-keys@^4.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb" integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== -eslint@^9.3.0: - version "9.3.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.3.0.tgz#36a96db84592618d6ed9074d677e92f4e58c08b9" - integrity sha512-5Iv4CsZW030lpUqHBapdPo3MJetAPtejVW8B84GIcIIv8+ohFaddXsrn1Gn8uD9ijDb+kcYKFUVmC8qG8B2ORQ== +eslint-visitor-keys@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c" + integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg== + +eslint@^9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.12.0.tgz#54fcba2876c90528396da0fa44b6446329031e86" + integrity sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" + "@eslint-community/regexpp" "^4.11.0" + "@eslint/config-array" "^0.18.0" + "@eslint/core" "^0.6.0" "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.3.0" - "@humanwhocodes/config-array" "^0.13.0" + "@eslint/js" "9.12.0" + "@eslint/plugin-kit" "^0.2.0" + "@humanfs/node" "^0.16.5" "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.3.0" - "@nodelib/fs.walk" "^1.2.8" + "@humanwhocodes/retry" "^0.3.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" escape-string-regexp "^4.0.0" - eslint-scope "^8.0.1" - eslint-visitor-keys "^4.0.0" - espree "^10.0.1" - esquery "^1.4.2" + eslint-scope "^8.1.0" + eslint-visitor-keys "^4.1.0" + espree "^10.2.0" + esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^8.0.0" @@ -838,14 +911,11 @@ eslint@^9.3.0: ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - is-path-inside "^3.0.3" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" - strip-ansi "^6.0.1" text-table "^0.2.0" espree@^10.0.1: @@ -857,6 +927,15 @@ espree@^10.0.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.0.0" +espree@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6" + integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g== + dependencies: + acorn "^8.12.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.1.0" + esprima@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.2.tgz#76a0fd66fcfe154fd292667dc264019750b1657b" @@ -872,10 +951,10 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== +esquery@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -974,12 +1053,10 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fastq@^1.6.0: - version "1.17.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" - integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== - dependencies: - reusify "^1.0.4" +fast-uri@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.2.tgz#d78b298cf70fd3b752fd951175a3da6a7b48f024" + integrity sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row== fd-slicer@~1.1.0: version "1.1.0" @@ -1002,14 +1079,14 @@ file-entry-cache@^8.0.0: dependencies: flat-cache "^4.0.0" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" -find-up@5.0.0, find-up@^5.0.0: +find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -1035,18 +1112,32 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^4.0.0, form-data@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fs-extra@^9.1.0: @@ -1069,24 +1160,26 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" @@ -1123,7 +1216,7 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob@8.1.0: +glob@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -1134,18 +1227,6 @@ glob@8.1.0: minimatch "^5.0.1" once "^1.3.0" -glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" @@ -1165,6 +1246,13 @@ globals@^14.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" @@ -1175,42 +1263,49 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" -he@1.2.0: +he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -http-signature@~1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" - integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== +http-signature@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.4.0.tgz#dee5a9ba2bf49416abc544abd6d967f6a94c8c3f" + integrity sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg== dependencies: assert-plus "^1.0.0" jsprim "^2.0.2" - sshpk "^1.14.1" + sshpk "^1.18.0" human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -iconv-lite@0.2.11: - version "0.2.11" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8" - integrity sha1-HOYKOleGSiktEyH/RgnKS7llrcg= - ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -1313,7 +1408,7 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-inside@^3.0.2, is-path-inside@^3.0.3: +is-path-inside@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -1348,13 +1443,6 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" @@ -1363,6 +1451,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -1373,13 +1468,6 @@ json-buffer@3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-schema-ref-parser@^9.0.6: - version "9.0.9" - resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#66ea538e7450b12af342fa3d5b8458bc1e1e013f" - integrity sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q== - dependencies: - "@apidevtools/json-schema-ref-parser" "9.0.9" - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1497,7 +1585,7 @@ lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0, log-symbols@^4.0.0: +log-symbols@^4.0.0, log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -1546,28 +1634,14 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.5, minimatch@^3.1.2: +minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: +minimatch@^5.0.1, minimatch@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== @@ -1595,38 +1669,38 @@ mocha-junit-reporter@^2.2.1: strip-ansi "^6.0.1" xml "^1.0.1" -mocha@^10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261" - integrity sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "8.1.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" +mocha@^10.7.3: + version "10.7.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" + integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^8.1.0" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -1648,10 +1722,10 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" @@ -1734,11 +1808,6 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -1754,10 +1823,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picocolors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== picomatch@^2.0.4: version "2.2.2" @@ -1799,6 +1868,11 @@ proxy-from-env@1.0.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -1817,28 +1891,18 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.0.tgz#ed079be28682147e6fd9a34cc2b0c1e0ec6453ee" - integrity sha1-7Qeb4oaCFH5v2aNMwrDB4OxkU+4= - -qs@6.10.4: - version "6.10.4" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.4.tgz#6a3003755add91c0ec9eacdc5f878b034e73f9e7" - integrity sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g== +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -1888,30 +1952,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - rxjs@^7.5.1: version "7.8.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" @@ -1934,23 +1979,30 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@0.5.x: - version "0.5.8" - resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" - integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE= - semver@^7.5.3: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -1963,14 +2015,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.2: version "3.0.2" @@ -2005,10 +2058,10 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.14.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== +sshpk@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028" + integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -2064,18 +2117,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1, supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" @@ -2083,6 +2129,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -2098,12 +2151,10 @@ through@^2.3.8: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" +tmp@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== to-regex-range@^5.0.1: version "5.0.1" @@ -2236,10 +2287,10 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== wrap-ansi@^6.2.0: version "6.2.0" @@ -2264,45 +2315,22 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xml2js@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.0.tgz#124fc4114b4129c810800ecb2ac86cf25462cb9a" - integrity sha1-Ek/EEUtBKcgQgA7LKshs8lRiy5o= - dependencies: - sax "0.5.x" - xmlbuilder ">=0.4.2" - xml@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw== -xmlbuilder@>=0.4.2: - version "13.0.2" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7" - integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yaml@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-0.2.3.tgz#b5450e92e76ef36b5dd24e3660091ebaeef3e5c7" - integrity sha1-tUUOkudu82td0k42YAkeuu7z5cc= - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: +yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-unparser@2.0.0: +yargs-unparser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== @@ -2312,7 +2340,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0: +yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==