diff --git a/.gitignore b/.gitignore index 0846284..fbb8167 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ ._* .vscode certbot-help.txt +test/node_modules +*/node_modules +docker/dev/dnsrouter-config.json.tmp +docker/dev/resolv.conf diff --git a/.version b/.version index 9e5bb77..3cf561c 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.11.2 +2.12.1 diff --git a/README.md b/README.md index 740babe..9ac6a6c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@



- + @@ -56,7 +56,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: 'docker.io/jc21/nginx-proxy-manager:latest' diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json deleted file mode 100644 index 4e540ab..0000000 --- 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 e528a0b..59f7def 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 64ab577..154e66e 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 3fa19fc..0000000 --- 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 3d6d600..5513782 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 017fc73..72326be 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 6033704..34b8fdf 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); @@ -861,33 +865,33 @@ const internalCertificate = { logger.info(`Requesting Let'sEncrypt certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id; - // Escape single quotes and backslashes - const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\'); - const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\''; + fs.mkdirSync('/etc/letsencrypt/credentials', { recursive: true }); + fs.writeFileSync(credentialsLocation, certificate.meta.dns_provider_credentials, {mode: 0o600}); // Whether the plugin has a ---credentials argument 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') { @@ -898,17 +902,15 @@ const internalCertificate = { mainCmd = mainCmd + ' --dns-duckdns-no-txt-restore'; } - logger.info('Command:', `${credentialsCmd} && && ${mainCmd}`); + logger.info('Command:', mainCmd); try { - await utils.exec(credentialsCmd); const result = await utils.exec(mainCmd); logger.info(result); return result; } catch (err) { - // Don't fail if file does not exist - const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`; - await utils.exec(delete_credentialsCmd); + // Don't fail if file does not exist, so no need for action in the callback + fs.unlink(credentialsLocation, () => {}); throw err; } }, @@ -966,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); @@ -998,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') { @@ -1030,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 2a6258e..e672775 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 a92d23b..d278acf 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -182,7 +182,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 dbff114..61ac8b8 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 775d94f..41ff5b0 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 a159cfd..ee88d46 100644 --- a/backend/internal/stream.js +++ b/backend/internal/stream.js @@ -128,7 +128,7 @@ const internalStream = { return query.then(utils.omitRow(omissions())); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } // Custom omissions @@ -152,7 +152,7 @@ const internalStream = { return internalStream.get(access, {id: data.id}); }) .then((row) => { - if (!row) { + if (!row || !row.id) { throw new error.ItemNotFoundError(data.id); } @@ -200,7 +200,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('Host is already enabled'); @@ -246,7 +246,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('Host is already disabled'); diff --git a/backend/internal/user.js b/backend/internal/user.js index a1d9044..742ab65 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 391ca00..607552f 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 5b9ebc9..0e658a6 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 8480f9a..e7a82ec 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 16b33b5..c97313d 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 caa57fc..f7fbdca 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, @@ -93,7 +93,7 @@ const generateKeys = () => { try { fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2)); } catch (err) { - logger.error('Could not write JWT key pair to config file: ' + keysFile + ': ' . err.message); + logger.error('Could not write JWT key pair to config file: ' + keysFile + ': ' + err.message); process.exit(1); } logger.info('Wrote JWT key pair to config file: ' + keysFile); @@ -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 c9befee..6d5b8b5 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 e38be99..f7e98be 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 3f51b59..fb31e64 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 (typeof payload === 'undefined') { - reject(new error.ValidationError('Payload is undefined')); + if (schema === null) { + reject(new error.ValidationError('Schema is undefined')); + return; } - let validate = ajv.compile(schema); - let valid = validate(payload); + if (typeof payload === 'undefined') { + reject(new error.ValidationError('Payload is undefined')); + return; + } + + 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 d09c9be..c6d2409 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 fbf9bda..959df05 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 2ee4319..469e96b 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 4f0f2ef..534d927 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 2e31043..483da3b 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 d84181c..07aa5dd 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 c90a6de..556742f 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 7d84d2c..b96ca5a 100644 --- a/backend/models/stream.js +++ b/backend/models/stream.js @@ -1,13 +1,20 @@ // 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', + 'tcp_forwarding', + 'udp_forwarding', +]; + class Stream extends Model { $beforeInsert () { this.created_on = now(); @@ -23,6 +30,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 93489fe..78fd3dd 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 b938c9a..1bc3ef1 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 8a2490c..c68c7b3 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 33cbbc2..b97096d 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 d55c3ae..3837512 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 ffdfb51..bf47c03 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 08b58f2..83b3776 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 6f933c3..3be4582 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 4d44c11..a46feb8 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 5e3fc28..c033f2e 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 9e2c98c..98c6cf8 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 fc6bd5b..fc3e48b 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 d08b2bf..dac4c3d 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 a21f998..72d01d4 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 1c6bd0a..f8ce366 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 0000000..83de014 --- /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 0000000..cd0218d --- /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 0000000..3e5e859 --- /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 0000000..cec4db8 --- /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 0000000..b75dcf6 --- /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 0000000..56ff303 --- /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 0000000..792c2f8 --- /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 0000000..c2540cf --- /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 0000000..ceb3e14 --- /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 0000000..8d22341 --- /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 0000000..b852a01 --- /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 0000000..39789b4 --- /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 0000000..5098802 --- /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 0000000..716dcfa --- /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 0000000..e7a495f --- /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 0000000..82407be --- /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 0000000..c66f099 --- /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 0000000..b9c6a10 --- /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 0000000..39789b4 --- /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 0000000..516c7f8 --- /dev/null +++ b/backend/schema/components/stream-object.json @@ -0,0 +1,60 @@ +{ + "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" + }, + "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 0000000..a7044bc --- /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 0000000..c5c0f71 --- /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 0000000..180e8f1 --- /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 640093a..0000000 --- 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 404e323..0000000 --- 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 955ca75..0000000 --- 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 0c73c3b..0000000 --- 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 27a8ec2..0000000 --- a/backend/schema/endpoints/proxy-hosts.json +++ /dev/null @@ -1,415 +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" - }, - "enable_proxy_protocol": { - "description": "Enable PROXY Protocol support", - "example": true, - "type": "boolean" - }, - "load_balancer_ip": { - "type": "string", - "minLength": 0, - "maxLength": 255 - }, - "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" - }, - "enable_proxy_protocol": { - "$ref": "#/definitions/enable_proxy_protocol" - }, - "load_balancer_ip": { - "$ref": "#/definitions/load_balancer_ip" - }, - "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" - }, - "enable_proxy_protocol": { - "$ref": "#/definitions/enable_proxy_protocol" - }, - "load_balancer_ip": { - "$ref": "#/definitions/load_balancer_ip" - }, - "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" - }, - "enable_proxy_protocol": { - "$ref": "#/definitions/enable_proxy_protocol" - }, - "load_balancer_ip": { - "$ref": "#/definitions/load_balancer_ip" - }, - "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 14a4699..0000000 --- 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 29e2865..0000000 --- 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 159c803..0000000 --- a/backend/schema/endpoints/streams.json +++ /dev/null @@ -1,234 +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" - }, - "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" - }, - "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" - }, - "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" - }, - "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 920af63..0000000 --- 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 42f44ea..0000000 --- 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 37bc6c4..0000000 --- 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 0000000..87b75f2 --- /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 6e7d1c8..0000000 --- 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 0000000..bc43e29 --- /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 0000000..8c3a4e0 --- /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 0000000..a8b9adc --- /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 0000000..073585c --- /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 0000000..e67023f --- /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 0000000..3a69f85 --- /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 0000000..4c5a4ed --- /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 0000000..0d40bcb --- /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 0000000..4b858ca --- /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 0000000..22317b3 --- /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 0000000..ef4d20e --- /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 0000000..f38b810 --- /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 0000000..2f4b556 --- /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 0000000..5a3306c --- /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 0000000..2b9a8dd --- /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 0000000..21eb325 --- /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 0000000..8a11a3f --- /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 0000000..f3aa81a --- /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 0000000..2cdcecf --- /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 0000000..ca3ce9f --- /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 0000000..47e2f8b --- /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 0000000..f9505ed --- /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 0000000..c8bbb69 --- /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 0000000..1d9f633 --- /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 0000000..991ef0e --- /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 0000000..54ff8a6 --- /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 0000000..9f052de --- /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 0000000..5e10a9c --- /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 0000000..5cab6e7 --- /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 0000000..85455fb --- /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 0000000..0b35e0f --- /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 0000000..7330f36 --- /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 0000000..8433220 --- /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 0000000..bef5343 --- /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 0000000..d780f87 --- /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 0000000..fd97cbf --- /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 0000000..5bfde2c --- /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 0000000..596afc6 --- /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 0000000..9f3514e --- /dev/null +++ b/backend/schema/paths/nginx/streams/post.json @@ -0,0 +1,87 @@ +{ + "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" + }, + "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"] + } + } + } + }, + "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 0000000..3a96852 --- /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 0000000..d1c1b1c --- /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 0000000..dc914f5 --- /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 0000000..6547656 --- /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 0000000..fbfdc90 --- /dev/null +++ b/backend/schema/paths/nginx/streams/streamID/put.json @@ -0,0 +1,143 @@ +{ + "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": { + "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/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 0000000..a40ddc7 --- /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 0000000..d435b00 --- /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 0000000..5d148d8 --- /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 0000000..405b976 --- /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 0000000..4ca6242 --- /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 0000000..859bc61 --- /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 0000000..dece6b6 --- /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 0000000..3741530 --- /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 0000000..c0213fe --- /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 0000000..a72f561 --- /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 0000000..7d4f361 --- /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 0000000..cb8ac61 --- /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 0000000..6148d18 --- /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 0000000..2dcd2ae --- /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 0000000..60a6cd1 --- /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 0000000..5a0142b --- /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/setup.js b/backend/setup.js index 7a138fe..9a7b697 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -21,11 +21,14 @@ const setupDefaultUser = () => { .then((row) => { if (!row.count) { // Create a new user and set password - logger.info('Creating a new user: admin@example.com with password: changeme'); + let email = process.env.INITIAL_ADMIN_EMAIL || 'admin@example.com'; + let password = process.env.INITIAL_ADMIN_PASSWORD || 'changeme'; + + logger.info('Creating a new user: ' + email + ' with password: ' + password); let data = { is_deleted: 0, - email: 'admin@example.com', + email: email, name: 'Administrator', nickname: 'Admin', avatar: '', @@ -41,7 +44,7 @@ const setupDefaultUser = () => { .insert({ user_id: user.id, type: 'password', - secret: 'changeme', + secret: password, meta: {}, }) .then(() => { diff --git a/backend/templates/_location.conf b/backend/templates/_location.conf index 2ee0d31..fcc7d12 100644 --- a/backend/templates/_location.conf +++ b/backend/templates/_location.conf @@ -1,10 +1,17 @@ location {{ path }} { + {{ advanced_config }} + proxy_set_header Host $host; proxy_set_header X-Forwarded-Scheme $scheme; 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" %} @@ -17,8 +24,5 @@ proxy_set_header Connection $http_connection; proxy_http_version 1.1; {% endif %} - - - {{ advanced_config }} } diff --git a/backend/validate-schema.js b/backend/validate-schema.js new file mode 100644 index 0000000..71a05c8 --- /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 58a214c..5441a51 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" @@ -448,11 +500,11 @@ brace-expansion@^1.1.7: concat-map "0.0.1" 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" buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: version "0.2.13" @@ -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" @@ -1206,10 +1273,10 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -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" @@ -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" @@ -1402,9 +1476,9 @@ glob-parent@^6.0.2: is-glob "^4.0.3" glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" @@ -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: - bignumber.js "9.0.0" - readable-stream "2.3.7" - safe-buffer "5.1.2" - sqlstring "2.3.1" + 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: + 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 799ee2a..0603e2d 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 3c21849..bb4ac6d 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/dnsrouter-config.json b/docker/dev/dnsrouter-config.json new file mode 100644 index 0000000..a4e538d --- /dev/null +++ b/docker/dev/dnsrouter-config.json @@ -0,0 +1,28 @@ +{ + "log": { + "format": "nice", + "level": "debug" + }, + "servers": [ + { + "host": "0.0.0.0", + "port": 53, + "upstreams": [ + { + "regex": "website[0-9]+.example\\.com", + "upstream": "127.0.0.11" + }, + { + "regex": ".*\\.example\\.com", + "upstream": "1.1.1.1" + }, + { + "regex": "local", + "nxdomain": true + } + ], + "internal": null, + "default_upstream": "127.0.0.11" + } + ] +} diff --git a/docker/dev/letsencrypt.ini b/docker/dev/letsencrypt.ini new file mode 100644 index 0000000..93647b6 --- /dev/null +++ b/docker/dev/letsencrypt.ini @@ -0,0 +1,7 @@ +text = True +non-interactive = True +webroot-path = /data/letsencrypt-acme-challenge +key-type = ecdsa +elliptic-curve = secp384r1 +preferred-chain = ISRG Root X1 +server = diff --git a/docker/dev/pdns-db.sql b/docker/dev/pdns-db.sql new file mode 100644 index 0000000..c182cf7 --- /dev/null +++ b/docker/dev/pdns-db.sql @@ -0,0 +1,255 @@ +/* + +How this was generated: +1. bring up an empty pdns stack +2. use api to create a zone ... + +curl -X POST \ + 'http://npm.dev:8081/api/v1/servers/localhost/zones' \ + --header 'X-API-Key: npm' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "name": "example.com.", + "kind": "Native", + "masters": [], + "nameservers": [ + "ns1.pdns.", + "ns2.pdns." + ] +}' + +3. Dump sql: + +docker exec -ti npm.pdns.db mysqldump -u pdns -p pdns + +*/ + +---------------------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `comments` +-- + +DROP TABLE IF EXISTS `comments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `comments` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `type` varchar(10) NOT NULL, + `modified_at` int(11) NOT NULL, + `account` varchar(40) CHARACTER SET utf8mb3 DEFAULT NULL, + `comment` text CHARACTER SET utf8mb3 NOT NULL, + PRIMARY KEY (`id`), + KEY `comments_name_type_idx` (`name`,`type`), + KEY `comments_order_idx` (`domain_id`,`modified_at`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `comments` +-- + +LOCK TABLES `comments` WRITE; +/*!40000 ALTER TABLE `comments` DISABLE KEYS */; +/*!40000 ALTER TABLE `comments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `cryptokeys` +-- + +DROP TABLE IF EXISTS `cryptokeys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cryptokeys` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) NOT NULL, + `flags` int(11) NOT NULL, + `active` tinyint(1) DEFAULT NULL, + `published` tinyint(1) DEFAULT 1, + `content` text DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `domainidindex` (`domain_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cryptokeys` +-- + +LOCK TABLES `cryptokeys` WRITE; +/*!40000 ALTER TABLE `cryptokeys` DISABLE KEYS */; +/*!40000 ALTER TABLE `cryptokeys` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `domainmetadata` +-- + +DROP TABLE IF EXISTS `domainmetadata`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `domainmetadata` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) NOT NULL, + `kind` varchar(32) DEFAULT NULL, + `content` text DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `domainmetadata_idx` (`domain_id`,`kind`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `domainmetadata` +-- + +LOCK TABLES `domainmetadata` WRITE; +/*!40000 ALTER TABLE `domainmetadata` DISABLE KEYS */; +INSERT INTO `domainmetadata` VALUES +(1,1,'SOA-EDIT-API','DEFAULT'); +/*!40000 ALTER TABLE `domainmetadata` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `domains` +-- + +DROP TABLE IF EXISTS `domains`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `domains` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `master` varchar(128) DEFAULT NULL, + `last_check` int(11) DEFAULT NULL, + `type` varchar(8) NOT NULL, + `notified_serial` int(10) unsigned DEFAULT NULL, + `account` varchar(40) CHARACTER SET utf8mb3 DEFAULT NULL, + `options` varchar(64000) DEFAULT NULL, + `catalog` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name_index` (`name`), + KEY `catalog_idx` (`catalog`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `domains` +-- + +LOCK TABLES `domains` WRITE; +/*!40000 ALTER TABLE `domains` DISABLE KEYS */; +INSERT INTO `domains` VALUES +(1,'example.com','',NULL,'NATIVE',NULL,'',NULL,NULL); +/*!40000 ALTER TABLE `domains` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `records` +-- + +DROP TABLE IF EXISTS `records`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `records` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `type` varchar(10) DEFAULT NULL, + `content` varchar(64000) DEFAULT NULL, + `ttl` int(11) DEFAULT NULL, + `prio` int(11) DEFAULT NULL, + `disabled` tinyint(1) DEFAULT 0, + `ordername` varchar(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + `auth` tinyint(1) DEFAULT 1, + PRIMARY KEY (`id`), + KEY `nametype_index` (`name`,`type`), + KEY `domain_id` (`domain_id`), + KEY `ordername` (`ordername`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `records` +-- + +LOCK TABLES `records` WRITE; +/*!40000 ALTER TABLE `records` DISABLE KEYS */; +INSERT INTO `records` VALUES +(1,1,'example.com','NS','ns1.pdns',1500,0,0,NULL,1), +(2,1,'example.com','NS','ns2.pdns',1500,0,0,NULL,1), +(3,1,'example.com','SOA','a.misconfigured.dns.server.invalid hostmaster.example.com 2023030501 10800 3600 604800 3600',1500,0,0,NULL,1); +/*!40000 ALTER TABLE `records` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `supermasters` +-- + +DROP TABLE IF EXISTS `supermasters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `supermasters` ( + `ip` varchar(64) NOT NULL, + `nameserver` varchar(255) NOT NULL, + `account` varchar(40) CHARACTER SET utf8mb3 NOT NULL, + PRIMARY KEY (`ip`,`nameserver`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `supermasters` +-- + +LOCK TABLES `supermasters` WRITE; +/*!40000 ALTER TABLE `supermasters` DISABLE KEYS */; +/*!40000 ALTER TABLE `supermasters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `tsigkeys` +-- + +DROP TABLE IF EXISTS `tsigkeys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `tsigkeys` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `algorithm` varchar(50) DEFAULT NULL, + `secret` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `namealgoindex` (`name`,`algorithm`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `tsigkeys` +-- + +LOCK TABLES `tsigkeys` WRITE; +/*!40000 ALTER TABLE `tsigkeys` DISABLE KEYS */; +/*!40000 ALTER TABLE `tsigkeys` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/docker/dev/pebble-config.json b/docker/dev/pebble-config.json new file mode 100644 index 0000000..ea93790 --- /dev/null +++ b/docker/dev/pebble-config.json @@ -0,0 +1,12 @@ +{ + "pebble": { + "listenAddress": "0.0.0.0:443", + "managementListenAddress": "0.0.0.0:15000", + "certificate": "test/certs/localhost/cert.pem", + "privateKey": "test/certs/localhost/key.pem", + "httpPort": 80, + "tlsPort": 443, + "ocspResponderURL": "", + "externalAccountBindingRequired": false + } +} diff --git a/docker/dev/squid.conf b/docker/dev/squid.conf new file mode 100644 index 0000000..cdd749f --- /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.mysql.yml b/docker/docker-compose.ci.mysql.yml new file mode 100644 index 0000000..388cdb3 --- /dev/null +++ b/docker/docker-compose.ci.mysql.yml @@ -0,0 +1,27 @@ +# WARNING: This is a CI docker-compose file used for building and testing of the entire app, it should not be used for production. +services: + + fullstack: + environment: + DB_MYSQL_HOST: 'db-mysql' + DB_MYSQL_PORT: '3306' + DB_MYSQL_USER: 'npm' + DB_MYSQL_PASSWORD: 'npmpass' + DB_MYSQL_NAME: 'npm' + depends_on: + - db-mysql + + db-mysql: + image: jc21/mariadb-aria + environment: + MYSQL_ROOT_PASSWORD: 'npm' + MYSQL_DATABASE: 'npm' + MYSQL_USER: 'npm' + MYSQL_PASSWORD: 'npmpass' + volumes: + - mysql_vol:/var/lib/mysql + networks: + - fulltest + +volumes: + mysql_vol: diff --git a/docker/docker-compose.ci.sqlite.yml b/docker/docker-compose.ci.sqlite.yml new file mode 100644 index 0000000..1c5be48 --- /dev/null +++ b/docker/docker-compose.ci.sqlite.yml @@ -0,0 +1,9 @@ +# WARNING: This is a CI docker-compose file used for building and testing of the entire app, it should not be used for production. +services: + + fullstack: + environment: + DB_SQLITE_FILE: '/data/mydb.sqlite' + PUID: 1000 + PGID: 1000 + DISABLE_IPV6: 'true' diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index 66770e5..bb68858 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -1,91 +1,124 @@ -# WARNING: This is a CI docker-compose file used for building and testing of the entire app, it should not be used for production. -version: '3.8' +# WARNING: This is a CI docker-compose file used for building +# and testing of the entire app, it should not be used for production. +# This is a base compose file, it should be extended with a +# docker-compose.ci.*.yml file services: - fullstack-mysql: - image: "${IMAGE}:ci-${BUILD_NUMBER}" + fullstack: + image: "${IMAGE}:${BRANCH_LOWER}-ci-${BUILD_NUMBER}" environment: DEBUG: 'true' - LE_STAGING: 'true' FORCE_COLOR: 1 - DB_MYSQL_HOST: 'db' - DB_MYSQL_PORT: '3306' - DB_MYSQL_USER: 'npm' - DB_MYSQL_PASSWORD: 'npm' - DB_MYSQL_NAME: 'npm' + # 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_mysql:/data - - npm_le_mysql:/etc/letsencrypt - expose: - - 81 - - 80 - - 443 + - 'npm_data_ci:/data' + - 'npm_le_ci:/etc/letsencrypt' + - './dev/letsencrypt.ini:/etc/letsencrypt.ini:ro' + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + healthcheck: + test: ["CMD", "/usr/bin/check-health"] + interval: 10s + timeout: 3s + networks: + fulltest: + aliases: + - website1.example.com + - website2.example.com + - website3.example.com + + stepca: + image: jc21/testca + volumes: + - './dev/resolv.conf:/etc/resolv.conf:ro' + - '/etc/localtime:/etc/localtime:ro' + networks: + fulltest: + aliases: + - ca.internal + + 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: - - db - healthcheck: - test: ["CMD", "/usr/bin/check-health"] - interval: 10s - timeout: 3s + - pdns-db + networks: + fulltest: + aliases: + - ns1.pdns + - ns2.pdns - fullstack-sqlite: - image: "${IMAGE}:ci-${BUILD_NUMBER}" + pdns-db: + image: mariadb environment: - DEBUG: 'true' - LE_STAGING: 'true' - FORCE_COLOR: 1 - DB_SQLITE_FILE: '/data/mydb.sqlite' - PUID: 1000 - PGID: 1000 - DISABLE_IPV6: 'true' + MYSQL_ROOT_PASSWORD: 'pdns' + MYSQL_DATABASE: 'pdns' + MYSQL_USER: 'pdns' + MYSQL_PASSWORD: 'pdns' volumes: - - npm_data_sqlite:/data - - npm_le_sqlite:/etc/letsencrypt - expose: - - 81 - - 80 - - 443 - healthcheck: - test: ["CMD", "/usr/bin/check-health"] - interval: 10s - timeout: 3s + - 'pdns_mysql_vol:/var/lib/mysql' + - '/etc/localtime:/etc/localtime:ro' + - './dev/pdns-db.sql:/docker-entrypoint-initdb.d/01_init.sql:ro' + networks: + - fulltest - db: - image: jc21/mariadb-aria - environment: - MYSQL_ROOT_PASSWORD: 'npm' - MYSQL_DATABASE: 'npm' - MYSQL_USER: 'npm' - MYSQL_PASSWORD: 'npm' + dnsrouter: + image: jc21/dnsrouter volumes: - - mysql_data:/var/lib/mysql + - ./dev/dnsrouter-config.json.tmp:/dnsrouter-config.json:ro + networks: + - fulltest - cypress-mysql: + cypress: image: "${IMAGE}-cypress:ci-${BUILD_NUMBER}" build: - context: ../test/ - dockerfile: cypress/Dockerfile + context: ../ + dockerfile: test/cypress/Dockerfile environment: - CYPRESS_baseUrl: 'http://fullstack-mysql:81' + HTTP_PROXY: 'squid:3128' + HTTPS_PROXY: 'squid:3128' volumes: - - cypress_logs_mysql:/results - command: cypress run --browser chrome --config-file=${CYPRESS_CONFIG:-cypress/config/ci.json} + - '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 - cypress-sqlite: - image: "${IMAGE}-cypress:ci-${BUILD_NUMBER}" - build: - context: ../test/ - dockerfile: cypress/Dockerfile - environment: - CYPRESS_baseUrl: "http://fullstack-sqlite:81" + squid: + image: ubuntu/squid volumes: - - cypress_logs_sqlite:/results - command: cypress run --browser chrome --config-file=${CYPRESS_CONFIG:-cypress/config/ci.json} + - './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_mysql: - cypress_logs_sqlite: - npm_data_mysql: - npm_data_sqlite: - npm_le_sqlite: - npm_le_mysql: - mysql_data: + cypress_logs: + npm_data_ci: + npm_le_ci: + pdns_mysql_vol: + +networks: + fulltest: + name: "npm-${BRANCH_LOWER}-ci-${BUILD_NUMBER}" diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 6d8cf87..2bfa2b7 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -1,8 +1,7 @@ # WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. -version: '3.8' services: - npm: + fullstack: image: nginxproxymanager:dev container_name: npm_core build: @@ -13,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 @@ -30,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 @@ -55,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 @@ -62,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 275b0aa..de97729 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/etc/nginx/conf.d/include/log.conf b/docker/rootfs/etc/nginx/conf.d/include/log.conf new file mode 100644 index 0000000..0d74029 --- /dev/null +++ b/docker/rootfs/etc/nginx/conf.d/include/log.conf @@ -0,0 +1,4 @@ +log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; +log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; + +access_log /data/logs/fallback_access.log proxy; diff --git a/docker/rootfs/etc/nginx/nginx.conf b/docker/rootfs/etc/nginx/nginx.conf index 8261833..3a31e14 100644 --- a/docker/rootfs/etc/nginx/nginx.conf +++ b/docker/rootfs/etc/nginx/nginx.conf @@ -14,6 +14,9 @@ error_log /data/logs/fallback_error.log warn; # Includes files with directives to load dynamic modules. include /etc/nginx/modules/*.conf; +# Custom +include /data/nginx/custom/root_top[.]conf; + events { include /data/nginx/custom/events[.]conf; } @@ -43,10 +46,8 @@ http { proxy_cache_path /var/lib/nginx/cache/public levels=1:2 keys_zone=public-cache:30m max_size=192m; proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m; - log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; - log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; - - access_log /data/logs/fallback_access.log proxy; + # Log format and fallback log file + include /etc/nginx/conf.d/include/log.conf; # Dynamically generated resolvers file include /etc/nginx/conf.d/include/resolvers.conf; diff --git a/docker/rootfs/var/www/html/index.html b/docker/rootfs/var/www/html/index.html index 8478b47..703db88 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 cc3d08c..3e3dcba 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/advanced-config/index.md b/docs/src/advanced-config/index.md index 7d32e96..efeaefe 100644 --- a/docs/src/advanced-config/index.md +++ b/docs/src/advanced-config/index.md @@ -173,6 +173,7 @@ NPM has the ability to include different custom configuration snippets in differ You can add your custom configuration snippet files at `/data/nginx/custom` as follow: + - `/data/nginx/custom/root_top.conf`: Included at the top of nginx.conf - `/data/nginx/custom/root.conf`: Included at the very end of nginx.conf - `/data/nginx/custom/http_top.conf`: Included at the top of the main http block - `/data/nginx/custom/http.conf`: Included at the end of the main http block @@ -212,3 +213,12 @@ You can customise the logrotate configuration through a mount (if your custom co ``` For reference, the default configuration can be found [here](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/rootfs/etc/logrotate.d/nginx-proxy-manager). + +## Enabling the geoip2 module + +To enable the geoip2 module, you can create the custom configuration file `/data/nginx/custom/root_top.conf` and include the following snippet: + +``` +load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so; +load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so; +``` diff --git a/docs/src/guide/index.md b/docs/src/guide/index.md index ad350b3..fcf176f 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 9249476..01fe299 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== +"@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== -"@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== +"@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== -"@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== +"@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: - "@docsearch/react" "3.6.0" + "@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/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.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-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.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-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.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/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.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-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.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/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.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-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.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/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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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-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.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/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.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/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.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/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.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/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.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-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.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-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.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== +"@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.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": +"@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== -"@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== +"@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: - shiki "1.5.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" + hast-util-to-html "^9.0.3" -"@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/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.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.22.0" + +"@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== +"@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== -"@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== +"@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/compiler-ssr" "3.5.11" + "@vue/shared" "3.5.11" -"@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== +"@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@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== +"@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/metadata" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" -"@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/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/core" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" -"@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/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@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/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== +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== -rollup@^4.13.0: - version "4.17.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.17.2.tgz#26d1785d0144122277fdb20ab3a24729ae68301f" - integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== +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: - esbuild "^0.20.1" - postcss "^8.4.38" - rollup "^4.13.0" + "@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: + "@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== +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.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" + "@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" + minisearch "^7.1.0" + shiki "^1.22.0" + vite "^5.4.8" + vue "^3.5.11" -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-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.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== +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.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" + "@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 371f3c5..c37fc95 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 e7af469..6729842 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", @@ -35,8 +43,8 @@ "name": "Cloudflare", "package_name": "certbot-dns-cloudflare", "version": "=={{certbot-version}}", - "dependencies": "cloudflare acme=={{certbot-version}}", - "credentials": "# Cloudflare API token\ndns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567", + "dependencies": "cloudflare==2.19.* acme=={{certbot-version}}", + "credentials": "# Cloudflare API token\ndns_cloudflare_api_token=0123456789abcdef0123456789abcdef01234567", "full_plugin_name": "dns-cloudflare" }, "cloudns": { @@ -239,6 +247,14 @@ "credentials": "dns_hetzner_api_token = 0123456789abcdef0123456789abcdef", "full_plugin_name": "dns-hetzner" }, + "hover": { + "name": "Hover", + "package_name": "certbot-dns-hover", + "version": "~=1.2.1", + "dependencies": "", + "credentials": "dns_hover_hoverurl = https://www.hover.com\ndns_hover_username = hover-admin-username\ndns_hover_password = hover-admin-password\ndns_hover_totpsecret = 2fa-totp-secret", + "full_plugin_name": "dns-hover" + }, "infomaniak": { "name": "Infomaniak", "package_name": "certbot-dns-infomaniak", @@ -311,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", @@ -399,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", @@ -454,5 +486,21 @@ "dependencies": "", "credentials": "dns_websupport_identifier = \ndns_websupport_secret_key = ", "full_plugin_name": "dns-websupport" + }, + "wedos":{ + "name": "Wedos", + "package_name": "certbot-dns-wedos", + "version": "~=2.2", + "dependencies": "", + "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 3cea091..4111db3 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/frontend-build b/scripts/ci/frontend-build index f81b8e3..ef1e75d 100755 --- a/scripts/ci/frontend-build +++ b/scripts/ci/frontend-build @@ -16,7 +16,7 @@ if hash docker 2>/dev/null; then -e NODE_OPTIONS=--openssl-legacy-provider \ -v "$(pwd)/frontend:/app/frontend" \ -v "$(pwd)/global:/app/global" \ - -w /app/frontend "$DOCKER_IMAGE" \ + -w /app/frontend "${DOCKER_IMAGE}" \ sh -c "yarn install && yarn build && yarn build && chown -R $(id -u):$(id -g) /app/frontend" echo -e "${BLUE}❯ ${GREEN}Building Frontend Complete${RESET}" diff --git a/scripts/ci/fulltest-cypress b/scripts/ci/fulltest-cypress new file mode 100755 index 0000000..9101189 --- /dev/null +++ b/scripts/ci/fulltest-cypress @@ -0,0 +1,89 @@ +#!/bin/bash +set -e + +STACK="${1:-sqlite}" + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# remember this is running in "ci" folder.. + +# Some defaults for running this script outside of CI +export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-npm_local_fulltest}" +export IMAGE="${IMAGE:-nginx-proxy-manager}" +export BRANCH_LOWER="${BRANCH_LOWER:-unknown}" +export BUILD_NUMBER="${BUILD_NUMBER:-0000}" + +if [ "${COMPOSE_FILE:-}" = "" ]; then + export COMPOSE_FILE="docker/docker-compose.ci.yml:docker/docker-compose.ci.${STACK}.yml" +fi + +# Colors +BLUE='\E[1;34m' +RED='\E[1;31m' +CYAN='\E[1;36m' +GREEN='\E[1;32m' +RESET='\E[0m' +YELLOW='\E[1;33m' + +export BLUE CYAN GREEN RESET YELLOW + +echo -e "${BLUE}❯ ${CYAN}Starting fullstack cypress testing ...${RESET}" +echo -e "${BLUE}❯ $(docker-compose config)${RESET}" + +# $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" +} + +# 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-mysql || true # ok to fail +docker-compose up -d --remove-orphans --pull=never fullstack + +# wait for main container to be healthy +bash "$DIR/../wait-healthy" "$(docker-compose ps --all -q fullstack)" 120 + +# Run tests +rm -rf "$DIR/../../test/results" +docker-compose up --build cypress + +# Get results +docker cp -L "$(docker-compose ps --all -q cypress):/test/results" "$DIR/../../test/" +docker cp -L "$(docker-compose ps --all -q fullstack):/data/logs" "$DIR/../../test/results/" + +if [ "$2" = "cleanup" ]; then + echo -e "${BLUE}❯ ${CYAN}Cleaning up containers ...${RESET}" + docker-compose down --remove-orphans --volumes -t 30 +fi + +echo -e "${BLUE}❯ ${GREEN}Fullstack cypress testing complete${RESET}" + diff --git a/scripts/ci/test-and-build b/scripts/ci/test-and-build index e99ab4b..a09ac9b 100755 --- a/scripts/ci/test-and-build +++ b/scripts/ci/test-and-build @@ -3,8 +3,8 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "$DIR/../.common.sh" -DOCKER_IMAGE=nginxproxymanager/nginx-full:certbot-node -docker pull "${DOCKER_IMAGE}" +TESTING_IMAGE=nginxproxymanager/nginx-full:certbot-node +docker pull "${TESTING_IMAGE}" # Test echo -e "${BLUE}❯ ${CYAN}Testing backend ...${RESET}" @@ -12,20 +12,20 @@ docker run --rm \ -v "$(pwd)/backend:/app" \ -v "$(pwd)/global:/app/global" \ -w /app \ - "${DOCKER_IMAGE}" \ + "${TESTING_IMAGE}" \ sh -c 'yarn install && yarn eslint . && rm -rf node_modules' echo -e "${BLUE}❯ ${GREEN}Testing Complete${RESET}" # Build echo -e "${BLUE}❯ ${CYAN}Building ...${RESET}" docker build --pull --no-cache --compress \ - -t "${IMAGE}:ci-${BUILD_NUMBER}" \ + -t "${IMAGE:-nginx-proxy-manager}:${BRANCH_LOWER:-unknown}-ci-${BUILD_NUMBER:-0000}" \ -f docker/Dockerfile \ --progress=plain \ --build-arg TARGETPLATFORM=linux/amd64 \ --build-arg BUILDPLATFORM=linux/amd64 \ - --build-arg BUILD_VERSION="${BUILD_VERSION}" \ - --build-arg BUILD_COMMIT="${BUILD_COMMIT}" \ + --build-arg BUILD_VERSION="${BUILD_VERSION:-unknown}" \ + --build-arg BUILD_COMMIT="${BUILD_COMMIT:-unknown}" \ --build-arg BUILD_DATE="$(date '+%Y-%m-%d %T %Z')" \ . echo -e "${BLUE}❯ ${GREEN}Building Complete${RESET}" diff --git a/scripts/test-dev b/scripts/cypress-dev similarity index 68% rename from scripts/test-dev rename to scripts/cypress-dev index f75527b..a0c64ad 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 f064a4b..9da6ed4 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/scripts/wait-healthy b/scripts/wait-healthy index b8da5d6..503d6a9 100755 --- a/scripts/wait-healthy +++ b/scripts/wait-healthy @@ -23,9 +23,8 @@ until [ "${HEALTHY}" = "healthy" ]; do ((LOOPCOUNT++)) if [ "$LOOPCOUNT" == "$LIMIT" ]; then - echo "" - echo "" echo -e "${BLUE}❯ ${RED}Timed out waiting for healthy${RESET}" + docker logs --tail 50 "$SERVICE" exit 1 fi done diff --git a/test/.dockerignore b/test/.dockerignore deleted file mode 100644 index b512c09..0000000 --- a/test/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/test/.eslintrc.json b/test/.eslintrc.json index 6939fec..5ea6a2a 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -73,4 +73,4 @@ } ] } -} \ No newline at end of file +} diff --git a/test/.gitignore b/test/.gitignore index fccdd38..bd6b6b9 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,4 +1,2 @@ -.vscode -node_modules -results -cypress/videos +results/* +cypress/results/* diff --git a/test/cypress/Dockerfile b/test/cypress/Dockerfile index 4e602a3..6de4c24 100644 --- a/test/cypress/Dockerfile +++ b/test/cypress/Dockerfile @@ -1,13 +1,12 @@ -FROM cypress/included:9.4.1 +FROM cypress/included:13.9.0 -COPY --chown=1000 ./ /test +COPY --chown=1000 ./test /test -# mkcert -ENV MKCERT=1.4.2 -RUN wget -O /usr/bin/mkcert "https://github.com/FiloSottile/mkcert/releases/download/v${MKCERT}/mkcert-v${MKCERT}-linux-amd64" \ - && chmod +x /usr/bin/mkcert +# Disable Cypress CLI colors +ENV FORCE_COLOR=0 +ENV NO_COLOR=1 WORKDIR /test -RUN yarn install +RUN yarn install && yarn cache clean ENTRYPOINT [] CMD ["cypress", "run"] diff --git a/test/cypress/config/ci.js b/test/cypress/config/ci.js new file mode 100644 index 0000000..dc968db --- /dev/null +++ b/test/cypress/config/ci.js @@ -0,0 +1,22 @@ +const { defineConfig } = require('cypress'); + +module.exports = defineConfig({ + requestTimeout: 30000, + defaultCommandTimeout: 20000, + reporter: 'cypress-multi-reporters', + reporterOptions: { + configFile: 'multi-reporter.json' + }, + video: true, + videosFolder: 'results/videos', + screenshotsFolder: 'results/screenshots', + e2e: { + setupNodeEvents(on, config) { + return require("../plugins/index.js")(on, config); + }, + env: { + swaggerBase: '{{baseUrl}}/api/schema?ts=' + Date.now(), + }, + baseUrl: 'http://fullstack:81', + } +}); diff --git a/test/cypress/config/ci.json b/test/cypress/config/ci.json deleted file mode 100644 index e11df47..0000000 --- a/test/cypress/config/ci.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "requestTimeout": 30000, - "defaultCommandTimeout": 20000, - "reporter": "cypress-multi-reporters", - "reporterOptions": { - "configFile": "multi-reporter.json" - }, - "videosFolder": "results/videos", - "screenshotsFolder": "results/screenshots", - "env": { - "swaggerBase": "{{baseUrl}}/api/schema", - "RETRIES": 4 - } -} diff --git a/test/cypress/config/dev.json b/test/cypress/config/dev.json deleted file mode 100644 index 19492c3..0000000 --- a/test/cypress/config/dev.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "requestTimeout": 30000, - "defaultCommandTimeout": 20000, - "reporter": "cypress-multi-reporters", - "reporterOptions": { - "configFile": "multi-reporter.json" - }, - "videos": false, - "screenshotsFolder": "results/screenshots", - "env": { - "swaggerBase": "{{baseUrl}}/api/schema", - "RETRIES": 0 - } -} diff --git a/test/cypress/e2e/api/Certificates.cy.js b/test/cypress/e2e/api/Certificates.cy.js new file mode 100644 index 0000000..1e8a6fe --- /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 0000000..5ca5692 --- /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/integration/api/Health.spec.js b/test/cypress/e2e/api/Health.cy.js similarity index 76% rename from test/cypress/integration/api/Health.spec.js rename to test/cypress/e2e/api/Health.cy.js index 5538916..49881e9 100644 --- a/test/cypress/integration/api/Health.spec.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/integration/api/Hosts.spec.js b/test/cypress/e2e/api/ProxyHosts.cy.js similarity index 90% rename from test/cypress/integration/api/Hosts.spec.js rename to test/cypress/e2e/api/ProxyHosts.cy.js index 4652c8e..5bc6458 100644 --- a/test/cypress/integration/api/Hosts.spec.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 0000000..6942760 --- /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/integration/api/Users.spec.js b/test/cypress/e2e/api/Users.cy.js similarity index 96% rename from test/cypress/integration/api/Users.spec.js rename to test/cypress/e2e/api/Users.cy.js index 43303d4..06b1831 100644 --- a/test/cypress/integration/api/Users.spec.js +++ b/test/cypress/e2e/api/Users.cy.js @@ -1,4 +1,4 @@ -/// +/// describe('Users endpoints', () => { let token; diff --git a/test/cypress/fixtures/example.json b/test/cypress/fixtures/example.json deleted file mode 100644 index da18d93..0000000 --- a/test/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} \ No newline at end of file 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 0000000..307cdc3 --- /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 0000000..16340cd --- /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 29684cf..6f5f766 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,129 +19,114 @@ BackendApi.prototype.setToken = function(token) { }; /** + * @param {bool} returnOnError + */ +BackendApi.prototype._prepareOptions = function(returnOnError) { + let options = { + headers: { + Accept: 'application/json' + } + } + if (this.token) { + options.headers.Authorization = 'Bearer ' + this.token; + } + if (returnOnError) { + options.validateStatus = function () { + return true; + } + } + return options; +}; + +/** + * @param {*} response + * @param {function} resolve + * @param {function} reject + * @param {bool} returnOnError + */ +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)); + } + } else { + resolve(response.data); + } +}; + +/** + * @param {*} err + * @param {function} resolve + * @param {function} reject + * @param {bool} 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 {bool} [returnOnError] + * @param {*} [data] * @returns {Promise} */ -BackendApi.prototype.get = function(path, returnOnError) { +BackendApi.prototype.request = function (method, path, returnOnError, data) { + logger(method.toUpperCase(), path); + const options = this._prepareOptions(returnOnError); + return new Promise((resolve, reject) => { - let headers = { - Accept: 'application/json' - }; - if (this.token) { - headers.Authorization = 'Bearer ' + this.token; + let opts = { + method: method, + url: path, + ...options + } + if (data !== undefined && data !== null) { + opts.data = data; } - logger('GET ', this.config.baseUrl + path); - - restler - .get(this.config.baseUrl + path, { - headers: headers, + this.axios(opts) + .then((response) => { + this._handleResponse(response, resolve, reject, returnOnError); }) - .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); - } + .catch((err) => { + this._handleError(err, resolve, reject, returnOnError); }); }); }; /** * @param {string} path + * @param {form} form * @param {bool} [returnOnError] * @returns {Promise} */ -BackendApi.prototype.delete = function(path, returnOnError) { +BackendApi.prototype.postForm = function (path, form, returnOnError) { + logger('POST', this.config.baseUrl + path); + const options = this._prepareOptions(returnOnError); + return new Promise((resolve, reject) => { - let headers = { - Accept: 'application/json' - }; - if (this.token) { - headers.Authorization = 'Bearer ' + this.token; + const opts = { + ...options, + ...form.getHeaders(), } - logger('DELETE ', this.config.baseUrl + path); - - restler - .del(this.config.baseUrl + path, { - headers: headers, + this.axios.post(path, form, opts) + .then((response) => { + this._handleResponse(response, resolve, reject, returnOnError); }) - .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); - } + .catch((err) => { + this._handleError(err, resolve, reject, returnOnError); }); }); }; -/** - * @param {string} path - * @param {object} data - * @param {bool} [returnOnError] - * @returns {Promise} - */ -BackendApi.prototype.postJson = function(path, data, returnOnError) { - logger('POST ', this.config.baseUrl + path); - return this._putPostJson('postJson', path, data, returnOnError); -}; - -/** - * @param {string} path - * @param {object} data - * @param {bool} [returnOnError] - * @returns {Promise} - */ -BackendApi.prototype.putJson = function(path, data, returnOnError) { - logger('PUT ', this.config.baseUrl + path); - return this._putPostJson('putJson', path, data, returnOnError); -}; - -/** - * @param {string} path - * @param {object} data - * @param {bool} [returnOnError] - * @returns {Promise} - */ -BackendApi.prototype._putPostJson = function(fn, path, data, 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); - } - }); - }); -}; - module.exports = BackendApi; diff --git a/test/cypress/plugins/backendApi/logger.js b/test/cypress/plugins/backendApi/logger.js index 4c5c8fb..8920b86 100644 --- a/test/cypress/plugins/backendApi/logger.js +++ b/test/cypress/plugins/backendApi/logger.js @@ -1,8 +1,7 @@ -const _ = require('lodash'); -const chalk = require('chalk'); +const _ = require("lodash"); -module.exports = function () { - var arr = _.values(arguments); - arr.unshift(chalk.blue.bold('[') + chalk.yellow.bold('Backend API') + chalk.blue.bold(']')); +module.exports = function() { + 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 2f67902..ab9704f 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 8cf6eef..2f3e3c5 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/cypress/support/commands.js b/test/cypress/support/commands.js index ea4af02..7d602ec 100644 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -9,20 +9,32 @@ // *********************************************** // +import 'cypress-wait-until'; + +Cypress.Commands.add('randomString', (length) => { + var result = ''; + var characters = 'ABCDEFGHIJK LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}); + /** * Check the swagger schema: * * @param {string} method API Method in swagger doc, "get", "put", "post", "delete" - * @param {number} statusCode API status code in swagger doc + * @param {integer} code Swagger doc endpoint response code, exactly as defined in swagger doc * @param {string} path Swagger doc endpoint path, exactly as defined in swagger doc * @param {*} data The API response data to check against the swagger schema */ -Cypress.Commands.add('validateSwaggerSchema', (method, statusCode, path, data) => { +Cypress.Commands.add('validateSwaggerSchema', (method, code, path, data) => { cy.task('validateSwaggerSchema', { file: Cypress.env('swaggerBase'), endpoint: path, method: method, - statusCode: statusCode, + statusCode: code, responseSchema: data, verbose: true }).should('equal', null); @@ -40,3 +52,19 @@ Cypress.Commands.add('getToken', () => { cy.wrap(res.token); }); }); + +// TODO: copied from v3, is this usable? +Cypress.Commands.add('waitForCertificateStatus', (token, certID, expected, timeout = 60) => { + cy.log(`Waiting for certificate (${certID}) status (${expected}) timeout (${timeout})`); + + cy.waitUntil(() => cy.task('backendApiGet', { + token: token, + path: `/api/certificates/${certID}` + }).then((data) => { + return data.result.status === expected; + }), { + errorMsg: 'Waiting for certificate status failed', + timeout: timeout * 1000, + interval: 5000 + }); +}); diff --git a/test/cypress/support/index.js b/test/cypress/support/e2e.js similarity index 82% rename from test/cypress/support/index.js rename to test/cypress/support/e2e.js index 4fc9aaf..9f724bf 100644 --- a/test/cypress/support/index.js +++ b/test/cypress/support/e2e.js @@ -1,5 +1,3 @@ -require('cypress-plugin-retries'); - import './commands'; Cypress.on('uncaught:exception', (/*err, runnable*/) => { diff --git a/test/jsconfig.json b/test/jsconfig.json index 4cd9977..e7ebe30 100644 --- a/test/jsconfig.json +++ b/test/jsconfig.json @@ -3,4 +3,4 @@ "./node_modules/cypress", "cypress/**/*.js" ] -} \ No newline at end of file +} diff --git a/test/package.json b/test/package.json index f39e7cd..b52ecfb 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.0.9", - "@jc21/restler": "^3.4.0", - "chalk": "^4.1.0", - "cypress": "^9.4.1", - "cypress-multi-reporters": "^1.4.0", - "cypress-plugin-retries": "^1.5.2", - "eslint": "^7.6.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.2", + "eslint": "^9.12.0", "eslint-plugin-align-assignments": "^1.1.2", - "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-cypress": "^2.11.1", - "lodash": "^4.17.19", - "mocha": "^8.1.1", - "mocha-junit-reporter": "^2.0.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.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 198febe..4fa9e51 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -11,31 +11,47 @@ call-me-maybe "^1.0.1" js-yaml "^3.13.1" -"@babel/code-frame@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== +"@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: - "@babel/highlight" "^7.0.0" + "@jsdevtools/ono" "^7.1.3" + "@types/json-schema" "^7.0.15" + js-yaml "^4.1.0" -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== +"@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: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" + "@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" "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cypress/request@^2.88.10": - version "2.88.11" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.11.tgz#5a4c7399bc2d7e7ed56e92ce5acb620c8b187047" - integrity sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w== +"@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" @@ -43,16 +59,16 @@ 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.3" + qs "6.13.0" safe-buffer "^5.1.2" - tough-cookie "~2.5.0" + tough-cookie "^4.1.3" tunnel-agent "^0.6.0" uuid "^8.3.2" @@ -64,27 +80,106 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@jc21/cypress-swagger-validation@^0.0.9": - version "0.0.9" - resolved "https://registry.yarnpkg.com/@jc21/cypress-swagger-validation/-/cypress-swagger-validation-0.0.9.tgz#8bed970d8d34e081248ddac967d69ded89f2dbd6" - integrity sha512-OkqXSGd5pFMODd4s646GmDLt39afzIvqPGIZHyXbOMDyR5CsGYOIrJk9GcDVn+RTdII0BV9Or03LVyErEImaeg== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: - ajv "^6.12.3" - chalk "^4.1.0" - json-schema "^0.2.5" - json-schema-ref-parser "^9.0.5" - jsonpath "^1.0.2" - lodash "^4.17.19" + eslint-visitor-keys "^3.3.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== +"@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: - iconv-lite "0.2.11" - qs "1.2.0" - xml2js "0.4.0" - yaml "0.2.3" + "@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" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6" + integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@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== + +"@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: + 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/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== + +"@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.17.1" + axios "^1.7.7" + json-schema "^0.4.0" + jsonpath "^1.1.1" + lodash "^4.17.21" + openapi-types "^12.1.3" + picocolors "^1.1.0" "@jsdevtools/ono@^7.1.3": version "7.1.3" @@ -96,16 +191,21 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@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== + "@types/node@*": version "18.14.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.6.tgz#ae1973dd2b1eeb1825695bb11ebfb746d27e3e93" integrity sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA== -"@types/node@^14.14.31": - version "14.18.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d" - integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg== - "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" @@ -123,15 +223,20 @@ dependencies: "@types/node" "*" -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^7.3.1: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== +acorn@^8.11.3: + version "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" @@ -141,7 +246,12 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: +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.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -151,11 +261,36 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@4.1.1, ansi-colors@^4.1.1: +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== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.4.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" @@ -163,16 +298,6 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" @@ -183,13 +308,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -205,10 +323,10 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -225,15 +343,10 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -array.prototype.map@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" - integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.4" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== asn1@~0.2.3: version "0.2.4" @@ -247,11 +360,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -282,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" @@ -322,14 +439,21 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -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== +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: - fill-range "^7.0.1" + balanced-match "^1.0.0" -browser-stdout@1.3.1: +braces@~3.0.2: + 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.1.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== @@ -339,7 +463,7 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer@^5.6.0: +buffer@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -352,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" @@ -370,33 +497,16 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^2.0.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -405,30 +515,30 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -charenc@~0.0.1: +charenc@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== check-more-types@^2.24.0: version "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.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" - integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== +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.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.3.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.2" ci-info@^3.2.0: version "3.8.0" @@ -464,21 +574,14 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" color-convert@^2.0.1: version "2.0.1" @@ -487,11 +590,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -502,17 +600,17 @@ 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== dependencies: delayed-stream "~1.0.0" -commander@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== common-tags@^1.8.0: version "1.8.0" @@ -538,71 +636,69 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -crypt@~0.0.1: +crypt@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -cypress-multi-reporters@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cypress-multi-reporters/-/cypress-multi-reporters-1.4.0.tgz#5f1d0484a20959cfe782f1bf65ad16c6ad804da7" - integrity sha512-CjpQduW43KVzY45hhKC/qf8MSebRpx6JyEz6py8F+0GrYS8rE5TZ8wXv9dPUs/PaT6w+dR8KIgLSMr967Om7iA== +cypress-multi-reporters@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/cypress-multi-reporters/-/cypress-multi-reporters-1.6.4.tgz#6f9d25ed8a0d8d7fa5597977adcd2237d1249931" + integrity sha512-3xU2t6pZjZy/ORHaCvci5OT1DAboS4UuMMM8NBAizeb2C9qmHt+cgAjXgurazkwkPRdO7ccK39M5ZaPCju0r6A== dependencies: - debug "^4.1.1" - lodash "^4.17.15" + debug "^4.3.4" + lodash "^4.17.21" -cypress-plugin-retries@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/cypress-plugin-retries/-/cypress-plugin-retries-1.5.2.tgz#21d5247cd77013b95bbfdd914f2de66f91f76a2e" - integrity sha512-o1xVIGtv4WvNVxoVJ2X08eAuvditPHrePRzHqhwwHbMKu3C2rtxCdanRCZdO5fjh8ww+q4v4V0e9GmysbOvu3A== - dependencies: - chalk "^3.0.0" +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@^9.4.1: - version "9.7.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.7.0.tgz#bf55b2afd481f7a113ef5604aa8b693564b5e744" - integrity sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q== +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" "^2.88.10" + "@cypress/request" "^3.0.4" "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" "@types/sinonjs__fake-timers" "8.1.1" "@types/sizzle" "^2.3.2" arch "^2.2.0" blob-util "^2.0.2" bluebird "^3.7.2" - buffer "^5.6.0" + buffer "^5.7.1" cachedir "^2.3.0" chalk "^4.1.0" check-more-types "^2.24.0" cli-cursor "^3.1.0" cli-table3 "~0.6.1" - commander "^5.1.0" + commander "^6.2.1" common-tags "^1.8.0" dayjs "^1.10.4" - debug "^4.3.2" + debug "^4.3.4" enquirer "^2.3.6" - eventemitter2 "^6.4.3" + eventemitter2 "6.4.7" execa "4.1.0" executable "^4.1.1" extract-zip "2.0.1" figures "^3.2.0" fs-extra "^9.1.0" getos "^3.2.1" - is-ci "^3.0.0" + is-ci "^3.0.1" is-installed-globally "~0.4.0" lazy-ass "^1.6.0" listr2 "^3.8.3" lodash "^4.17.21" log-symbols "^4.0.0" - minimist "^1.2.6" + minimist "^1.2.8" ospath "^1.2.2" pretty-bytes "^5.6.0" + process "^0.11.10" proxy-from-env "1.0.0" request-progress "^3.0.0" - semver "^7.3.2" + 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" @@ -618,67 +714,62 @@ dayjs@^1.10.4: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== -debug@3.2.6, debug@^3.1.0: +debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.0.1, debug@^4.1.1: +debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== dependencies: ms "^2.1.1" -debug@^4.3.2: +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" -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +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" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-is@^0.1.3, deep-is@~0.1.3: version "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-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== +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: - object-keys "^1.0.12" + 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@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" +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" @@ -688,11 +779,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -705,79 +791,40 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enquirer@^2.3.5, enquirer@^2.3.6: +enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" -es-abstract@^1.17.0-next.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" - integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-array-method-boxes-properly@^1.0.0: +es-define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-get-iterator@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" - integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== dependencies: - es-abstract "^1.17.4" - has-symbols "^1.0.1" - is-arguments "^1.0.4" - is-map "^2.0.1" - is-set "^2.0.1" - is-string "^1.0.5" - isarray "^2.0.5" + get-intrinsic "^1.2.4" -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" +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== -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: +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@^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" @@ -795,93 +842,99 @@ 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.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.6.0.tgz#54052fab79302ed0cea76ab997351ea4809bfb77" - integrity sha512-Uvvv1gkbRGp/qfN15B0kQyQWg+oFA8buDSqrwmW3egNSk/FpqH2MjQqKOuKwmEL6w4QIQrIjDp+gg6kGGmD3oQ== +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@^2.11.1: - version "2.11.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.11.1.tgz#a945e2774b88211e2c706a059d431e262b5c2862" - integrity sha512-MxMYoReSO5+IZMGgpBZHHSx64zYPSPTpXDwsgW7ChlJTF/sA+obqRbHplxD6sBStE+g4Mi0LCLkG4t9liu//mQ== +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 "^11.12.0" + globals "^13.20.0" -eslint-scope@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== +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.1.0" - estraverse "^4.1.1" + esrecurse "^4.3.0" + estraverse "^5.2.0" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-visitor-keys@^3.3.0: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint-visitor-keys@^4.0.0: + version "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-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-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - -eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint@^7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" - integrity sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" + "@eslint-community/eslint-utils" "^4.2.0" + "@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.12.0" + "@eslint/plugin-kit" "^0.2.0" + "@humanfs/node" "^0.16.5" + "@humanwhocodes/module-importer" "^1.0.1" + "@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.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.0" - eslint-utils "^2.1.0" - eslint-visitor-keys "^1.3.0" - espree "^7.2.0" - esquery "^1.2.0" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.1.0" + eslint-visitor-keys "^4.1.0" + espree "^10.2.0" + esquery "^1.5.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.19" - minimatch "^3.0.4" + lodash.merge "^4.6.2" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^5.2.3" + optionator "^0.9.3" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.2.0.tgz#1c263d5b513dbad0ac30c4991b93ac354e948d69" - integrity sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g== +espree@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.0.1.tgz#600e60404157412751ba4a6f3a2ee1a42433139f" + integrity sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww== dependencies: - acorn "^7.3.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.3.0" + acorn "^8.11.3" + 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" @@ -898,21 +951,21 @@ 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.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== +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" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -922,15 +975,20 @@ estraverse@^5.1.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -eventemitter2@^6.4.3: - version "6.4.9" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125" - integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== execa@4.1.0: version "4.1.0" @@ -980,7 +1038,7 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -995,6 +1053,11 @@ 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= +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" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -1009,68 +1072,72 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== dependencies: - flat-cache "^2.0.1" + 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@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== +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== dependencies: - locate-path "^5.0.0" + locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== dependencies: - locate-path "^3.0.0" + flatted "^3.2.9" + keyv "^4.5.4" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" - integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== - dependencies: - is-buffer "~2.0.3" +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== +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.6" + 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.8" mime-types "^2.1.12" fs-extra@^9.1.0: @@ -1088,34 +1155,31 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.2: + version "2.3.3" + 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== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -get-caller-file@^2.0.1: +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" @@ -1138,24 +1202,30 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.0: +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@7.1.6, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +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== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^5.0.1" once "^1.3.0" - path-is-absolute "^1.0.0" global-dirs@^3.0.0: version "3.0.1" @@ -1164,93 +1234,92 @@ global-dirs@^3.0.0: dependencies: ini "2.0.0" -globals@^11.12.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" - integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== +globals@^13.20.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: - type-fest "^0.8.1" + type-fest "^0.20.2" + +globals@^14.0.0: + version "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" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +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" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -1283,11 +1352,6 @@ ini@2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1295,48 +1359,23 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@~1.1.1: +is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - -is-callable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== - -is-ci@^3.0.0: +is-ci@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== dependencies: ci-info "^3.2.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -1349,6 +1388,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-installed-globally@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" @@ -1357,11 +1403,6 @@ is-installed-globally@~0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" - integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1372,47 +1413,16 @@ is-path-inside@^3.0.2: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - -is-regex@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - -is-set@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" - integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -1423,11 +1433,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -1438,25 +1443,7 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -iterate-iterator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" - integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== - -iterate-value@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" - integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== - dependencies: - es-get-iterator "^1.0.2" - iterate-iterator "^1.0.1" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@3.13.1, js-yaml@^3.13.1: +js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -1464,33 +1451,38 @@ js-yaml@3.13.1, 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" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -json-schema-ref-parser@^9.0.5: - version "9.0.6" - resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#fc89a5e6b853f2abe8c0af30d3874196526adb60" - integrity sha512-z0JGv7rRD3CnJbZY/qCpscyArdtLJhr/wRBmFUdoZ8xMjsFyNdILSprG2degqRLjBjyhZHAEBpGOxniO9rKTxA== - dependencies: - "@apidevtools/json-schema-ref-parser" "9.0.6" +json-buffer@3.0.1: + version "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-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.4.0: +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0, json-schema@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== -json-schema@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b" - integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -1510,14 +1502,14 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonpath@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-1.0.2.tgz#e6aae681d03e9a77b4651d5d96eac5fc63b1fd13" - integrity sha512-rmzlgFZiQPc6q4HDyK8s9Qb4oxBnI5sF61y/Co5PV0lc3q2bIuRsNdueVbhoSHdKM4fxeimphOAtfz47yjCfeA== +jsonpath@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-1.1.1.tgz#0ca1ed8fb65bb3309248cc9d5466d12d5b0b9901" + integrity sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w== dependencies: esprima "1.2.2" static-eval "2.0.2" - underscore "1.7.0" + underscore "1.12.1" jsprim@^2.0.2: version "2.0.2" @@ -1529,6 +1521,13 @@ jsprim@^2.0.2: json-schema "0.4.0" verror "1.10.0" +keyv@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" @@ -1564,39 +1563,29 @@ listr2@^3.8.3: through "^2.3.8" wrap-ansi "^7.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" + p-locate "^5.0.0" -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.once@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - -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== @@ -1614,21 +1603,14 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== dependencies: - yallist "^4.0.0" - -md5@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" - integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= - dependencies: - charenc "~0.0.1" - crypt "~0.0.1" - is-buffer "~1.1.1" + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" merge-stream@^2.0.0: version "2.0.0" @@ -1652,82 +1634,77 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@3.0.4, 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== +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" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= +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== + dependencies: + brace-expansion "^2.0.1" -minimist@^1.2.6: +minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" +mkdirp@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== -mocha-junit-reporter@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-2.0.0.tgz#3bf990fce7a42c0d2b718f188553a25d9f24b9a2" - integrity sha512-20HoWh2HEfhqmigfXOKUhZQyX23JImskc37ZOhIjBKoBEsb+4cAFRJpAVhFpnvsztLklW/gFVzsrobjLwmX4lA== +mocha-junit-reporter@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-2.2.1.tgz#739f5595d0f051d07af9d74e32c416e13a41cde5" + integrity sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw== dependencies: - debug "^2.2.0" - md5 "^2.1.0" - mkdirp "~0.5.1" - strip-ansi "^4.0.0" - xml "^1.0.0" + debug "^4.3.4" + md5 "^2.3.0" + mkdirp "^3.0.0" + strip-ansi "^6.0.1" + xml "^1.0.1" -mocha@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.1.1.tgz#1de1ba4e9a2c955d96b84e469d7540848223592d" - integrity sha512-p7FuGlYH8t7gaiodlFreseLxEmxTgvyG9RgPHODFPySNhwUehu8NIb0vdSt3WFckSneswZ0Un5typYcWElk7HQ== +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.1" - browser-stdout "1.3.1" - chokidar "3.3.1" - debug "3.2.6" - diff "4.0.2" - escape-string-regexp "1.0.5" - find-up "4.1.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - ms "2.1.2" - object.assign "4.1.0" - promise.allsettled "1.0.2" - serialize-javascript "4.0.0" - strip-json-comments "3.0.1" - supports-color "7.1.0" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.0.0" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + 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: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -1745,30 +1722,10 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -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-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@4.1.0, object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" +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" @@ -1784,6 +1741,11 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +openapi-types@^12.1.3: + version "12.1.3" + resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" + integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -1796,50 +1758,36 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" + word-wrap "^1.2.5" ospath@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= -p-limit@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-try "^2.0.0" + yocto-queue "^0.1.0" -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" + p-limit "^3.0.2" p-map@^4.0.0: version "4.0.0" @@ -1848,11 +1796,6 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -1860,21 +1803,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - path-exists@^4.0.0: version "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" @@ -1890,11 +1823,21 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.7: +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" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -1915,31 +1858,25 @@ pretty-bytes@^5.6.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise.allsettled@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9" - integrity sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg== - dependencies: - array.prototype.map "^1.0.1" - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - iterate-value "^1.0.0" +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== proxy-from-env@1.0.0: version "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== -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +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" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== pump@^3.0.0: version "3.0.0" @@ -1954,17 +1891,17 @@ 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.3: - version "6.10.5" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" - integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== +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== randombytes@^2.1.0: version "2.1.0" @@ -1973,17 +1910,12 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -readdirp@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" - integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: - picomatch "^2.0.7" - -regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + picomatch "^2.2.1" request-progress@^3.0.0: version "3.0.0" @@ -1997,10 +1929,15 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== resolve-from@^4.0.0: version "4.0.0" @@ -2020,20 +1957,6 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -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" - rxjs@^7.5.1: version "7.8.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" @@ -2056,29 +1979,29 @@ 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== -semver@^7.2.1, semver@^7.3.2: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -serialize-javascript@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== +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-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +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" @@ -2092,29 +2015,21 @@ 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" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -2143,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" @@ -2165,23 +2080,6 @@ static-eval@2.0.2: dependencies: escodegen "^1.8.1" -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -2200,52 +2098,6 @@ string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -2265,30 +2117,18 @@ 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.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" - integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== - -strip-json-comments@^3.1.0: +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@7.1.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== dependencies: has-flag "^4.0.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.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" @@ -2296,16 +2136,6 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.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" @@ -2321,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" @@ -2335,13 +2163,15 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== +tough-cookie@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== dependencies: - psl "^1.1.28" + psl "^1.1.33" punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" tslib@^2.1.0: version "2.5.0" @@ -2374,20 +2204,25 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +underscore@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" + integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== -underscore@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" - integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk= +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: version "2.0.0" @@ -2406,16 +2241,26 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +uri-js@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" - integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== - verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -2425,43 +2270,27 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2, which@^2.0.1: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@~1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -workerpool@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.0.0.tgz#85aad67fa1a2c8ef9386a1b43539900f61d03d58" - integrity sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" +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" @@ -2486,105 +2315,43 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -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.0: +xml@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + 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== -y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== +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== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -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@13.1.2, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== +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== dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" -yargs-parser@^15.0.1: - version "15.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" - integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw== +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== dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-unparser@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.1.tgz#bd4b0ee05b4c94d058929c32cb09e3fce71d3c5f" - integrity sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA== - dependencies: - camelcase "^5.3.1" - decamelize "^1.2.0" - flat "^4.1.0" - is-plain-obj "^1.1.0" - yargs "^14.2.3" - -yargs@13.3.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@^14.2.3: - version "14.2.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" - integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^15.0.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" yauzl@^2.10.0: version "2.10.0" @@ -2593,3 +2360,8 @@ yauzl@^2.10.0: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==