├── .gitignore ├── LICENSE ├── README.md ├── block.example.txt ├── blocks.example.json ├── config.example.json ├── defaultFile.example.txt ├── main.js ├── package-lock.json ├── package.json ├── public └── config.js └── static ├── edit ├── index.html └── main.js ├── favicon.ico ├── index.html ├── lib ├── guiLoader.js ├── icon │ ├── favicon.png │ └── favicon.svg ├── main.css └── materialUIOverwrite.css ├── login ├── index.html └── main.js └── main.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | config.json 107 | nginxConfig.json 108 | block.txt 109 | defaultFile.txt 110 | blocks.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Proxtx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx-config-gui 2 | This is a Web-Interface to configure nginx. 3 | 4 | # videodemo 5 | https://www.reddit.com/r/selfhosted/comments/y71ktz/small_project_i_created_a_web_gui_to_configure/ 6 | Post about the project with video 7 | 8 | # quick setup 9 | If you just want to manage subdomains with proxy_passes: 10 | Follow the setup but you can skip step 10,11 and 12. In step 2 you only need to update example.de to your own domain. Same goes for step 4. 11 | 12 | # setup 13 | 1. copy block.exmaple.txt to block.txt 14 | 2. in block.txt change the configuration to match your standardized server-block. Replace everything that should be changeable via the gui with a "$" for example "$subDomain" 15 | 3. copy defaultFile.example.txt to defaultFile.txt 16 | 4. edit defaultFile.txt to match your main nginx configuration. Place "$customBlocks" where you want the serverblocks generated by the gui to be added. 17 | 5. copy blocks.exmaple.json to blocks.json 18 | 6. copy config.example.json to config.json 19 | 7. edit config.json: 20 | 8. change the port-attribute to the port you want to webgui to listen on 21 | 9. change the pwd-attribute to the password you want to use to enter the webgui 22 | 10. fill the replace array with objects connected to the variables you added to the block.txt configuration. These objects need to follow the syntax presented in the example. 'name' for the display name in the gui, replace for the key you want to replace in the block.txt configuration file and optionally default for the default value in the field. 23 | 11. change result file if you dont want to edit the default nginx configuration file 24 | 12 change the restart nginx field if you have a different command of programm to restart nginx 25 | 13. run npm i 26 | 14. run node . 27 | -------------------------------------------------------------------------------- /block.example.txt: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | server_name $subDomain.example.de; 4 | location / { 5 | proxy_pass $proxy_pass; 6 | proxy_http_version 1.1; 7 | proxy_set_header Upgrade $http_upgrade; 8 | proxy_set_header Connection "upgrade"; 9 | } 10 | 11 | listen 80; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /blocks.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "blocks": [] 3 | } 4 | -------------------------------------------------------------------------------- /config.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3000, 3 | "pwd": "1234", 4 | "replace": [ 5 | { 6 | "name": "Subdomain", 7 | "replace": "$subDomain" 8 | }, 9 | { 10 | "name": "Proxy Pass", 11 | "default": "http://localhost:", 12 | "replace": "$proxy_pass" 13 | } 14 | ], 15 | "resultFile": "/etc/nginx/sites-available/default", 16 | "restartNginx": "service nginx restart" 17 | } 18 | -------------------------------------------------------------------------------- /defaultFile.example.txt: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | listen [::]:80 default_server; 4 | 5 | root /var/www/html; 6 | index index.html index.htm index.nginx-debian.html; 7 | 8 | server_name example.de; 9 | 10 | location / { 11 | try_files $uri $uri/ =404; 12 | } 13 | } 14 | 15 | $customBlocks -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import { listen } from "@proxtx/framework"; 2 | import config from "@proxtx/config"; 3 | 4 | await listen(config.port); 5 | 6 | console.log("Server Started. Port:", config.port); 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nginx-config-gui", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "nginx-config-gui", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@proxtx/config": "^1.0.2", 13 | "@proxtx/framework": "^1.4.3", 14 | "@proxtx/material": "^1.0.865" 15 | } 16 | }, 17 | "node_modules/@proxtx/combine": { 18 | "version": "3.1.4", 19 | "resolved": "https://registry.npmjs.org/@proxtx/combine/-/combine-3.1.4.tgz", 20 | "integrity": "sha512-7IR2HRO0pGps1TuaaZ+LNsK2sVGd1CTvgRYPrQDeAVmZ+AcLl3Hyt05CDxHPr0hPDTGHRWeu//bsfHT0jthSzg==" 21 | }, 22 | "node_modules/@proxtx/combine-iframe": { 23 | "version": "1.0.3", 24 | "resolved": "https://registry.npmjs.org/@proxtx/combine-iframe/-/combine-iframe-1.0.3.tgz", 25 | "integrity": "sha512-t63M/ZC7k0GMRbE3IRzbeb4u21w9t2uyU9UVNtYakLy7HF6f7buVdbPtNy9q9AxYvcwWz28yXZuPEKl24SLKlQ==", 26 | "dependencies": { 27 | "@proxtx/combine": "^3.1.4" 28 | } 29 | }, 30 | "node_modules/@proxtx/combine-rest": { 31 | "version": "1.0.4", 32 | "resolved": "https://registry.npmjs.org/@proxtx/combine-rest/-/combine-rest-1.0.4.tgz", 33 | "integrity": "sha512-fExRiVR7X4jDVUtLxgaB8fyc/cA7enC8AH38HupkSzwaJ8Pqqmexk1nArkEx6ba33s8WmNA7ISS7/YZhL9NIiA==", 34 | "dependencies": { 35 | "@proxtx/combine": "^3.1.4", 36 | "express": "^4.17.2", 37 | "node-fetch": "^3.2.0" 38 | } 39 | }, 40 | "node_modules/@proxtx/combine-ws": { 41 | "version": "1.1.5", 42 | "resolved": "https://registry.npmjs.org/@proxtx/combine-ws/-/combine-ws-1.1.5.tgz", 43 | "integrity": "sha512-8X+ZJ5WBWQ0aH9pUUwZ3cbyTaHyS8pj3DN8aeKYeMAej9jedUznGfXtFvGQWb/HDeTNv6nFet/4gQcDLNnuqww==", 44 | "dependencies": { 45 | "ws": "^8.5.0" 46 | } 47 | }, 48 | "node_modules/@proxtx/config": { 49 | "version": "1.0.2", 50 | "resolved": "https://registry.npmjs.org/@proxtx/config/-/config-1.0.2.tgz", 51 | "integrity": "sha512-Ml648+TM9IwnxnuHTmO4A9s7yOiqXwH2DRlirorWQcRZYeaO5rD45A3A8xjotaRtfQ4v4saDI0ateu7BeffzLg==" 52 | }, 53 | "node_modules/@proxtx/cookie-parser": { 54 | "version": "1.0.2", 55 | "resolved": "https://registry.npmjs.org/@proxtx/cookie-parser/-/cookie-parser-1.0.2.tgz", 56 | "integrity": "sha512-tew422oOHvIhTo6/b/EE+y0vS/vbvyvKMytg9YxCQGHu5+Uba+ADOOqx1le1q4cxNZHeO6DZjhYJmCzs+sf8lw==" 57 | }, 58 | "node_modules/@proxtx/dom": { 59 | "version": "1.1.4", 60 | "resolved": "https://registry.npmjs.org/@proxtx/dom/-/dom-1.1.4.tgz", 61 | "integrity": "sha512-dXey0fUFlarDIDG/VOilToIXVC5m9cpiiOhxHUvhfoEEFxrmcN0fZtktapb+weBe3je5g5FL4aUinkHj5Pm4jA==", 62 | "dependencies": { 63 | "@proxtx/html": "^1.0.8", 64 | "@proxtx/watcher": "^1.0.7" 65 | } 66 | }, 67 | "node_modules/@proxtx/framework": { 68 | "version": "1.4.3", 69 | "resolved": "https://registry.npmjs.org/@proxtx/framework/-/framework-1.4.3.tgz", 70 | "integrity": "sha512-XgYtgNgUsN+VCrFQSfL08pch1Mj0J/1bl2Xs+9XhAvrvqcjlLKfLJzlbq97nIX1Z18MAhSMoCD7X7jCDxCdI/w==", 71 | "dependencies": { 72 | "@proxtx/combine": "^3.1.4", 73 | "@proxtx/combine-iframe": "^1.0.3", 74 | "@proxtx/combine-rest": "^1.0.4", 75 | "@proxtx/combine-ws": "^1.1.5", 76 | "@proxtx/cookie-parser": "^1.0.2", 77 | "@proxtx/dom": "^1.1.4", 78 | "@proxtx/html": "^1.0.8", 79 | "cookie-parser": "^1.4.6", 80 | "express": "^4.17.1" 81 | } 82 | }, 83 | "node_modules/@proxtx/html": { 84 | "version": "1.1.0", 85 | "resolved": "https://registry.npmjs.org/@proxtx/html/-/html-1.1.0.tgz", 86 | "integrity": "sha512-t9baEJ0SS/E0AfrnjB4MLO8brP8CYxAFoUPRpsROiyp2HBkfvov5A9We4PdLKC+wai9Csn+POSFMffUkmoBdKw==" 87 | }, 88 | "node_modules/@proxtx/material": { 89 | "version": "1.0.865", 90 | "resolved": "https://registry.npmjs.org/@proxtx/material/-/material-1.0.865.tgz", 91 | "integrity": "sha512-PxRTj/daS/5Ef81o88ow47uABnaEEEs46wOKbI1HWAHT6PaTSYnzGaZsObaIELK0Mp/sLPgn/Syj8hOXhivzgQ==", 92 | "dependencies": { 93 | "@proxtx/uibuilder": "^1.1.3" 94 | } 95 | }, 96 | "node_modules/@proxtx/uibuilder": { 97 | "version": "1.1.3", 98 | "resolved": "https://registry.npmjs.org/@proxtx/uibuilder/-/uibuilder-1.1.3.tgz", 99 | "integrity": "sha512-C4U5hyIk/udMfARytCC3Twqr7Eb6vmRL8rv7bWY7aIKsrYA4sfEdVRk5AltbVSUIV7XkQrGBtSetbtkx1VvRRg==" 100 | }, 101 | "node_modules/@proxtx/watcher": { 102 | "version": "1.0.7", 103 | "resolved": "https://registry.npmjs.org/@proxtx/watcher/-/watcher-1.0.7.tgz", 104 | "integrity": "sha512-+ANiPE4G/5CHMJ05uYA6CsBrp1+2NJqlhmPFgqY5s303goEvDEe0+piFzqgkWa5pgH6cu41YGiVXU+VqKt3Deg==" 105 | }, 106 | "node_modules/accepts": { 107 | "version": "1.3.8", 108 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 109 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 110 | "dependencies": { 111 | "mime-types": "~2.1.34", 112 | "negotiator": "0.6.3" 113 | }, 114 | "engines": { 115 | "node": ">= 0.6" 116 | } 117 | }, 118 | "node_modules/array-flatten": { 119 | "version": "1.1.1", 120 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 121 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 122 | }, 123 | "node_modules/body-parser": { 124 | "version": "1.20.0", 125 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 126 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 127 | "dependencies": { 128 | "bytes": "3.1.2", 129 | "content-type": "~1.0.4", 130 | "debug": "2.6.9", 131 | "depd": "2.0.0", 132 | "destroy": "1.2.0", 133 | "http-errors": "2.0.0", 134 | "iconv-lite": "0.4.24", 135 | "on-finished": "2.4.1", 136 | "qs": "6.10.3", 137 | "raw-body": "2.5.1", 138 | "type-is": "~1.6.18", 139 | "unpipe": "1.0.0" 140 | }, 141 | "engines": { 142 | "node": ">= 0.8", 143 | "npm": "1.2.8000 || >= 1.4.16" 144 | } 145 | }, 146 | "node_modules/bytes": { 147 | "version": "3.1.2", 148 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 149 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 150 | "engines": { 151 | "node": ">= 0.8" 152 | } 153 | }, 154 | "node_modules/call-bind": { 155 | "version": "1.0.2", 156 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 157 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 158 | "dependencies": { 159 | "function-bind": "^1.1.1", 160 | "get-intrinsic": "^1.0.2" 161 | }, 162 | "funding": { 163 | "url": "https://github.com/sponsors/ljharb" 164 | } 165 | }, 166 | "node_modules/content-disposition": { 167 | "version": "0.5.4", 168 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 169 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 170 | "dependencies": { 171 | "safe-buffer": "5.2.1" 172 | }, 173 | "engines": { 174 | "node": ">= 0.6" 175 | } 176 | }, 177 | "node_modules/content-type": { 178 | "version": "1.0.4", 179 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 180 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 181 | "engines": { 182 | "node": ">= 0.6" 183 | } 184 | }, 185 | "node_modules/cookie": { 186 | "version": "0.4.1", 187 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", 188 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", 189 | "engines": { 190 | "node": ">= 0.6" 191 | } 192 | }, 193 | "node_modules/cookie-parser": { 194 | "version": "1.4.6", 195 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", 196 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", 197 | "dependencies": { 198 | "cookie": "0.4.1", 199 | "cookie-signature": "1.0.6" 200 | }, 201 | "engines": { 202 | "node": ">= 0.8.0" 203 | } 204 | }, 205 | "node_modules/cookie-signature": { 206 | "version": "1.0.6", 207 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 208 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 209 | }, 210 | "node_modules/data-uri-to-buffer": { 211 | "version": "4.0.0", 212 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", 213 | "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", 214 | "engines": { 215 | "node": ">= 12" 216 | } 217 | }, 218 | "node_modules/debug": { 219 | "version": "2.6.9", 220 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 221 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 222 | "dependencies": { 223 | "ms": "2.0.0" 224 | } 225 | }, 226 | "node_modules/depd": { 227 | "version": "2.0.0", 228 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 229 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 230 | "engines": { 231 | "node": ">= 0.8" 232 | } 233 | }, 234 | "node_modules/destroy": { 235 | "version": "1.2.0", 236 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 237 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 238 | "engines": { 239 | "node": ">= 0.8", 240 | "npm": "1.2.8000 || >= 1.4.16" 241 | } 242 | }, 243 | "node_modules/ee-first": { 244 | "version": "1.1.1", 245 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 246 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 247 | }, 248 | "node_modules/encodeurl": { 249 | "version": "1.0.2", 250 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 251 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 252 | "engines": { 253 | "node": ">= 0.8" 254 | } 255 | }, 256 | "node_modules/escape-html": { 257 | "version": "1.0.3", 258 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 259 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 260 | }, 261 | "node_modules/etag": { 262 | "version": "1.8.1", 263 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 264 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 265 | "engines": { 266 | "node": ">= 0.6" 267 | } 268 | }, 269 | "node_modules/express": { 270 | "version": "4.18.1", 271 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", 272 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", 273 | "dependencies": { 274 | "accepts": "~1.3.8", 275 | "array-flatten": "1.1.1", 276 | "body-parser": "1.20.0", 277 | "content-disposition": "0.5.4", 278 | "content-type": "~1.0.4", 279 | "cookie": "0.5.0", 280 | "cookie-signature": "1.0.6", 281 | "debug": "2.6.9", 282 | "depd": "2.0.0", 283 | "encodeurl": "~1.0.2", 284 | "escape-html": "~1.0.3", 285 | "etag": "~1.8.1", 286 | "finalhandler": "1.2.0", 287 | "fresh": "0.5.2", 288 | "http-errors": "2.0.0", 289 | "merge-descriptors": "1.0.1", 290 | "methods": "~1.1.2", 291 | "on-finished": "2.4.1", 292 | "parseurl": "~1.3.3", 293 | "path-to-regexp": "0.1.7", 294 | "proxy-addr": "~2.0.7", 295 | "qs": "6.10.3", 296 | "range-parser": "~1.2.1", 297 | "safe-buffer": "5.2.1", 298 | "send": "0.18.0", 299 | "serve-static": "1.15.0", 300 | "setprototypeof": "1.2.0", 301 | "statuses": "2.0.1", 302 | "type-is": "~1.6.18", 303 | "utils-merge": "1.0.1", 304 | "vary": "~1.1.2" 305 | }, 306 | "engines": { 307 | "node": ">= 0.10.0" 308 | } 309 | }, 310 | "node_modules/express/node_modules/cookie": { 311 | "version": "0.5.0", 312 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 313 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 314 | "engines": { 315 | "node": ">= 0.6" 316 | } 317 | }, 318 | "node_modules/fetch-blob": { 319 | "version": "3.1.5", 320 | "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz", 321 | "integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==", 322 | "funding": [ 323 | { 324 | "type": "github", 325 | "url": "https://github.com/sponsors/jimmywarting" 326 | }, 327 | { 328 | "type": "paypal", 329 | "url": "https://paypal.me/jimmywarting" 330 | } 331 | ], 332 | "dependencies": { 333 | "node-domexception": "^1.0.0", 334 | "web-streams-polyfill": "^3.0.3" 335 | }, 336 | "engines": { 337 | "node": "^12.20 || >= 14.13" 338 | } 339 | }, 340 | "node_modules/finalhandler": { 341 | "version": "1.2.0", 342 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 343 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 344 | "dependencies": { 345 | "debug": "2.6.9", 346 | "encodeurl": "~1.0.2", 347 | "escape-html": "~1.0.3", 348 | "on-finished": "2.4.1", 349 | "parseurl": "~1.3.3", 350 | "statuses": "2.0.1", 351 | "unpipe": "~1.0.0" 352 | }, 353 | "engines": { 354 | "node": ">= 0.8" 355 | } 356 | }, 357 | "node_modules/formdata-polyfill": { 358 | "version": "4.0.10", 359 | "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", 360 | "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", 361 | "dependencies": { 362 | "fetch-blob": "^3.1.2" 363 | }, 364 | "engines": { 365 | "node": ">=12.20.0" 366 | } 367 | }, 368 | "node_modules/forwarded": { 369 | "version": "0.2.0", 370 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 371 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 372 | "engines": { 373 | "node": ">= 0.6" 374 | } 375 | }, 376 | "node_modules/fresh": { 377 | "version": "0.5.2", 378 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 379 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 380 | "engines": { 381 | "node": ">= 0.6" 382 | } 383 | }, 384 | "node_modules/function-bind": { 385 | "version": "1.1.1", 386 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 387 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 388 | }, 389 | "node_modules/get-intrinsic": { 390 | "version": "1.1.2", 391 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", 392 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", 393 | "dependencies": { 394 | "function-bind": "^1.1.1", 395 | "has": "^1.0.3", 396 | "has-symbols": "^1.0.3" 397 | }, 398 | "funding": { 399 | "url": "https://github.com/sponsors/ljharb" 400 | } 401 | }, 402 | "node_modules/has": { 403 | "version": "1.0.3", 404 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 405 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 406 | "dependencies": { 407 | "function-bind": "^1.1.1" 408 | }, 409 | "engines": { 410 | "node": ">= 0.4.0" 411 | } 412 | }, 413 | "node_modules/has-symbols": { 414 | "version": "1.0.3", 415 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 416 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 417 | "engines": { 418 | "node": ">= 0.4" 419 | }, 420 | "funding": { 421 | "url": "https://github.com/sponsors/ljharb" 422 | } 423 | }, 424 | "node_modules/http-errors": { 425 | "version": "2.0.0", 426 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 427 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 428 | "dependencies": { 429 | "depd": "2.0.0", 430 | "inherits": "2.0.4", 431 | "setprototypeof": "1.2.0", 432 | "statuses": "2.0.1", 433 | "toidentifier": "1.0.1" 434 | }, 435 | "engines": { 436 | "node": ">= 0.8" 437 | } 438 | }, 439 | "node_modules/iconv-lite": { 440 | "version": "0.4.24", 441 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 442 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 443 | "dependencies": { 444 | "safer-buffer": ">= 2.1.2 < 3" 445 | }, 446 | "engines": { 447 | "node": ">=0.10.0" 448 | } 449 | }, 450 | "node_modules/inherits": { 451 | "version": "2.0.4", 452 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 453 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 454 | }, 455 | "node_modules/ipaddr.js": { 456 | "version": "1.9.1", 457 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 458 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 459 | "engines": { 460 | "node": ">= 0.10" 461 | } 462 | }, 463 | "node_modules/media-typer": { 464 | "version": "0.3.0", 465 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 466 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 467 | "engines": { 468 | "node": ">= 0.6" 469 | } 470 | }, 471 | "node_modules/merge-descriptors": { 472 | "version": "1.0.1", 473 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 474 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 475 | }, 476 | "node_modules/methods": { 477 | "version": "1.1.2", 478 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 479 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 480 | "engines": { 481 | "node": ">= 0.6" 482 | } 483 | }, 484 | "node_modules/mime": { 485 | "version": "1.6.0", 486 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 487 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 488 | "bin": { 489 | "mime": "cli.js" 490 | }, 491 | "engines": { 492 | "node": ">=4" 493 | } 494 | }, 495 | "node_modules/mime-db": { 496 | "version": "1.52.0", 497 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 498 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 499 | "engines": { 500 | "node": ">= 0.6" 501 | } 502 | }, 503 | "node_modules/mime-types": { 504 | "version": "2.1.35", 505 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 506 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 507 | "dependencies": { 508 | "mime-db": "1.52.0" 509 | }, 510 | "engines": { 511 | "node": ">= 0.6" 512 | } 513 | }, 514 | "node_modules/ms": { 515 | "version": "2.0.0", 516 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 517 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 518 | }, 519 | "node_modules/negotiator": { 520 | "version": "0.6.3", 521 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 522 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 523 | "engines": { 524 | "node": ">= 0.6" 525 | } 526 | }, 527 | "node_modules/node-domexception": { 528 | "version": "1.0.0", 529 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 530 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 531 | "funding": [ 532 | { 533 | "type": "github", 534 | "url": "https://github.com/sponsors/jimmywarting" 535 | }, 536 | { 537 | "type": "github", 538 | "url": "https://paypal.me/jimmywarting" 539 | } 540 | ], 541 | "engines": { 542 | "node": ">=10.5.0" 543 | } 544 | }, 545 | "node_modules/node-fetch": { 546 | "version": "3.2.6", 547 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", 548 | "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", 549 | "dependencies": { 550 | "data-uri-to-buffer": "^4.0.0", 551 | "fetch-blob": "^3.1.4", 552 | "formdata-polyfill": "^4.0.10" 553 | }, 554 | "engines": { 555 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 556 | }, 557 | "funding": { 558 | "type": "opencollective", 559 | "url": "https://opencollective.com/node-fetch" 560 | } 561 | }, 562 | "node_modules/object-inspect": { 563 | "version": "1.12.2", 564 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 565 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 566 | "funding": { 567 | "url": "https://github.com/sponsors/ljharb" 568 | } 569 | }, 570 | "node_modules/on-finished": { 571 | "version": "2.4.1", 572 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 573 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 574 | "dependencies": { 575 | "ee-first": "1.1.1" 576 | }, 577 | "engines": { 578 | "node": ">= 0.8" 579 | } 580 | }, 581 | "node_modules/parseurl": { 582 | "version": "1.3.3", 583 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 584 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 585 | "engines": { 586 | "node": ">= 0.8" 587 | } 588 | }, 589 | "node_modules/path-to-regexp": { 590 | "version": "0.1.7", 591 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 592 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 593 | }, 594 | "node_modules/proxy-addr": { 595 | "version": "2.0.7", 596 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 597 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 598 | "dependencies": { 599 | "forwarded": "0.2.0", 600 | "ipaddr.js": "1.9.1" 601 | }, 602 | "engines": { 603 | "node": ">= 0.10" 604 | } 605 | }, 606 | "node_modules/qs": { 607 | "version": "6.10.3", 608 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 609 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 610 | "dependencies": { 611 | "side-channel": "^1.0.4" 612 | }, 613 | "engines": { 614 | "node": ">=0.6" 615 | }, 616 | "funding": { 617 | "url": "https://github.com/sponsors/ljharb" 618 | } 619 | }, 620 | "node_modules/range-parser": { 621 | "version": "1.2.1", 622 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 623 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 624 | "engines": { 625 | "node": ">= 0.6" 626 | } 627 | }, 628 | "node_modules/raw-body": { 629 | "version": "2.5.1", 630 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 631 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 632 | "dependencies": { 633 | "bytes": "3.1.2", 634 | "http-errors": "2.0.0", 635 | "iconv-lite": "0.4.24", 636 | "unpipe": "1.0.0" 637 | }, 638 | "engines": { 639 | "node": ">= 0.8" 640 | } 641 | }, 642 | "node_modules/safe-buffer": { 643 | "version": "5.2.1", 644 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 645 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 646 | "funding": [ 647 | { 648 | "type": "github", 649 | "url": "https://github.com/sponsors/feross" 650 | }, 651 | { 652 | "type": "patreon", 653 | "url": "https://www.patreon.com/feross" 654 | }, 655 | { 656 | "type": "consulting", 657 | "url": "https://feross.org/support" 658 | } 659 | ] 660 | }, 661 | "node_modules/safer-buffer": { 662 | "version": "2.1.2", 663 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 664 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 665 | }, 666 | "node_modules/send": { 667 | "version": "0.18.0", 668 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 669 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 670 | "dependencies": { 671 | "debug": "2.6.9", 672 | "depd": "2.0.0", 673 | "destroy": "1.2.0", 674 | "encodeurl": "~1.0.2", 675 | "escape-html": "~1.0.3", 676 | "etag": "~1.8.1", 677 | "fresh": "0.5.2", 678 | "http-errors": "2.0.0", 679 | "mime": "1.6.0", 680 | "ms": "2.1.3", 681 | "on-finished": "2.4.1", 682 | "range-parser": "~1.2.1", 683 | "statuses": "2.0.1" 684 | }, 685 | "engines": { 686 | "node": ">= 0.8.0" 687 | } 688 | }, 689 | "node_modules/send/node_modules/ms": { 690 | "version": "2.1.3", 691 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 692 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 693 | }, 694 | "node_modules/serve-static": { 695 | "version": "1.15.0", 696 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 697 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 698 | "dependencies": { 699 | "encodeurl": "~1.0.2", 700 | "escape-html": "~1.0.3", 701 | "parseurl": "~1.3.3", 702 | "send": "0.18.0" 703 | }, 704 | "engines": { 705 | "node": ">= 0.8.0" 706 | } 707 | }, 708 | "node_modules/setprototypeof": { 709 | "version": "1.2.0", 710 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 711 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 712 | }, 713 | "node_modules/side-channel": { 714 | "version": "1.0.4", 715 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 716 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 717 | "dependencies": { 718 | "call-bind": "^1.0.0", 719 | "get-intrinsic": "^1.0.2", 720 | "object-inspect": "^1.9.0" 721 | }, 722 | "funding": { 723 | "url": "https://github.com/sponsors/ljharb" 724 | } 725 | }, 726 | "node_modules/statuses": { 727 | "version": "2.0.1", 728 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 729 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 730 | "engines": { 731 | "node": ">= 0.8" 732 | } 733 | }, 734 | "node_modules/toidentifier": { 735 | "version": "1.0.1", 736 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 737 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 738 | "engines": { 739 | "node": ">=0.6" 740 | } 741 | }, 742 | "node_modules/type-is": { 743 | "version": "1.6.18", 744 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 745 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 746 | "dependencies": { 747 | "media-typer": "0.3.0", 748 | "mime-types": "~2.1.24" 749 | }, 750 | "engines": { 751 | "node": ">= 0.6" 752 | } 753 | }, 754 | "node_modules/unpipe": { 755 | "version": "1.0.0", 756 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 757 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 758 | "engines": { 759 | "node": ">= 0.8" 760 | } 761 | }, 762 | "node_modules/utils-merge": { 763 | "version": "1.0.1", 764 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 765 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 766 | "engines": { 767 | "node": ">= 0.4.0" 768 | } 769 | }, 770 | "node_modules/vary": { 771 | "version": "1.1.2", 772 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 773 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 774 | "engines": { 775 | "node": ">= 0.8" 776 | } 777 | }, 778 | "node_modules/web-streams-polyfill": { 779 | "version": "3.2.1", 780 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", 781 | "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", 782 | "engines": { 783 | "node": ">= 8" 784 | } 785 | }, 786 | "node_modules/ws": { 787 | "version": "8.8.0", 788 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", 789 | "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", 790 | "engines": { 791 | "node": ">=10.0.0" 792 | }, 793 | "peerDependencies": { 794 | "bufferutil": "^4.0.1", 795 | "utf-8-validate": "^5.0.2" 796 | }, 797 | "peerDependenciesMeta": { 798 | "bufferutil": { 799 | "optional": true 800 | }, 801 | "utf-8-validate": { 802 | "optional": true 803 | } 804 | } 805 | } 806 | }, 807 | "dependencies": { 808 | "@proxtx/combine": { 809 | "version": "3.1.4", 810 | "resolved": "https://registry.npmjs.org/@proxtx/combine/-/combine-3.1.4.tgz", 811 | "integrity": "sha512-7IR2HRO0pGps1TuaaZ+LNsK2sVGd1CTvgRYPrQDeAVmZ+AcLl3Hyt05CDxHPr0hPDTGHRWeu//bsfHT0jthSzg==" 812 | }, 813 | "@proxtx/combine-iframe": { 814 | "version": "1.0.3", 815 | "resolved": "https://registry.npmjs.org/@proxtx/combine-iframe/-/combine-iframe-1.0.3.tgz", 816 | "integrity": "sha512-t63M/ZC7k0GMRbE3IRzbeb4u21w9t2uyU9UVNtYakLy7HF6f7buVdbPtNy9q9AxYvcwWz28yXZuPEKl24SLKlQ==", 817 | "requires": { 818 | "@proxtx/combine": "^3.1.4" 819 | } 820 | }, 821 | "@proxtx/combine-rest": { 822 | "version": "1.0.4", 823 | "resolved": "https://registry.npmjs.org/@proxtx/combine-rest/-/combine-rest-1.0.4.tgz", 824 | "integrity": "sha512-fExRiVR7X4jDVUtLxgaB8fyc/cA7enC8AH38HupkSzwaJ8Pqqmexk1nArkEx6ba33s8WmNA7ISS7/YZhL9NIiA==", 825 | "requires": { 826 | "@proxtx/combine": "^3.1.4", 827 | "express": "^4.17.2", 828 | "node-fetch": "^3.2.0" 829 | } 830 | }, 831 | "@proxtx/combine-ws": { 832 | "version": "1.1.5", 833 | "resolved": "https://registry.npmjs.org/@proxtx/combine-ws/-/combine-ws-1.1.5.tgz", 834 | "integrity": "sha512-8X+ZJ5WBWQ0aH9pUUwZ3cbyTaHyS8pj3DN8aeKYeMAej9jedUznGfXtFvGQWb/HDeTNv6nFet/4gQcDLNnuqww==", 835 | "requires": { 836 | "ws": "^8.5.0" 837 | } 838 | }, 839 | "@proxtx/config": { 840 | "version": "1.0.2", 841 | "resolved": "https://registry.npmjs.org/@proxtx/config/-/config-1.0.2.tgz", 842 | "integrity": "sha512-Ml648+TM9IwnxnuHTmO4A9s7yOiqXwH2DRlirorWQcRZYeaO5rD45A3A8xjotaRtfQ4v4saDI0ateu7BeffzLg==" 843 | }, 844 | "@proxtx/cookie-parser": { 845 | "version": "1.0.2", 846 | "resolved": "https://registry.npmjs.org/@proxtx/cookie-parser/-/cookie-parser-1.0.2.tgz", 847 | "integrity": "sha512-tew422oOHvIhTo6/b/EE+y0vS/vbvyvKMytg9YxCQGHu5+Uba+ADOOqx1le1q4cxNZHeO6DZjhYJmCzs+sf8lw==" 848 | }, 849 | "@proxtx/dom": { 850 | "version": "1.1.4", 851 | "resolved": "https://registry.npmjs.org/@proxtx/dom/-/dom-1.1.4.tgz", 852 | "integrity": "sha512-dXey0fUFlarDIDG/VOilToIXVC5m9cpiiOhxHUvhfoEEFxrmcN0fZtktapb+weBe3je5g5FL4aUinkHj5Pm4jA==", 853 | "requires": { 854 | "@proxtx/html": "^1.0.8", 855 | "@proxtx/watcher": "^1.0.7" 856 | } 857 | }, 858 | "@proxtx/framework": { 859 | "version": "1.4.3", 860 | "resolved": "https://registry.npmjs.org/@proxtx/framework/-/framework-1.4.3.tgz", 861 | "integrity": "sha512-XgYtgNgUsN+VCrFQSfL08pch1Mj0J/1bl2Xs+9XhAvrvqcjlLKfLJzlbq97nIX1Z18MAhSMoCD7X7jCDxCdI/w==", 862 | "requires": { 863 | "@proxtx/combine": "^3.1.4", 864 | "@proxtx/combine-iframe": "^1.0.3", 865 | "@proxtx/combine-rest": "^1.0.4", 866 | "@proxtx/combine-ws": "^1.1.5", 867 | "@proxtx/cookie-parser": "^1.0.2", 868 | "@proxtx/dom": "^1.1.4", 869 | "@proxtx/html": "^1.0.8", 870 | "cookie-parser": "^1.4.6", 871 | "express": "^4.17.1" 872 | } 873 | }, 874 | "@proxtx/html": { 875 | "version": "1.1.0", 876 | "resolved": "https://registry.npmjs.org/@proxtx/html/-/html-1.1.0.tgz", 877 | "integrity": "sha512-t9baEJ0SS/E0AfrnjB4MLO8brP8CYxAFoUPRpsROiyp2HBkfvov5A9We4PdLKC+wai9Csn+POSFMffUkmoBdKw==" 878 | }, 879 | "@proxtx/material": { 880 | "version": "1.0.865", 881 | "resolved": "https://registry.npmjs.org/@proxtx/material/-/material-1.0.865.tgz", 882 | "integrity": "sha512-PxRTj/daS/5Ef81o88ow47uABnaEEEs46wOKbI1HWAHT6PaTSYnzGaZsObaIELK0Mp/sLPgn/Syj8hOXhivzgQ==", 883 | "requires": { 884 | "@proxtx/uibuilder": "^1.1.3" 885 | } 886 | }, 887 | "@proxtx/uibuilder": { 888 | "version": "1.1.3", 889 | "resolved": "https://registry.npmjs.org/@proxtx/uibuilder/-/uibuilder-1.1.3.tgz", 890 | "integrity": "sha512-C4U5hyIk/udMfARytCC3Twqr7Eb6vmRL8rv7bWY7aIKsrYA4sfEdVRk5AltbVSUIV7XkQrGBtSetbtkx1VvRRg==" 891 | }, 892 | "@proxtx/watcher": { 893 | "version": "1.0.7", 894 | "resolved": "https://registry.npmjs.org/@proxtx/watcher/-/watcher-1.0.7.tgz", 895 | "integrity": "sha512-+ANiPE4G/5CHMJ05uYA6CsBrp1+2NJqlhmPFgqY5s303goEvDEe0+piFzqgkWa5pgH6cu41YGiVXU+VqKt3Deg==" 896 | }, 897 | "accepts": { 898 | "version": "1.3.8", 899 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 900 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 901 | "requires": { 902 | "mime-types": "~2.1.34", 903 | "negotiator": "0.6.3" 904 | } 905 | }, 906 | "array-flatten": { 907 | "version": "1.1.1", 908 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 909 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 910 | }, 911 | "body-parser": { 912 | "version": "1.20.0", 913 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 914 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 915 | "requires": { 916 | "bytes": "3.1.2", 917 | "content-type": "~1.0.4", 918 | "debug": "2.6.9", 919 | "depd": "2.0.0", 920 | "destroy": "1.2.0", 921 | "http-errors": "2.0.0", 922 | "iconv-lite": "0.4.24", 923 | "on-finished": "2.4.1", 924 | "qs": "6.10.3", 925 | "raw-body": "2.5.1", 926 | "type-is": "~1.6.18", 927 | "unpipe": "1.0.0" 928 | } 929 | }, 930 | "bytes": { 931 | "version": "3.1.2", 932 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 933 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 934 | }, 935 | "call-bind": { 936 | "version": "1.0.2", 937 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 938 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 939 | "requires": { 940 | "function-bind": "^1.1.1", 941 | "get-intrinsic": "^1.0.2" 942 | } 943 | }, 944 | "content-disposition": { 945 | "version": "0.5.4", 946 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 947 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 948 | "requires": { 949 | "safe-buffer": "5.2.1" 950 | } 951 | }, 952 | "content-type": { 953 | "version": "1.0.4", 954 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 955 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 956 | }, 957 | "cookie": { 958 | "version": "0.4.1", 959 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", 960 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" 961 | }, 962 | "cookie-parser": { 963 | "version": "1.4.6", 964 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", 965 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", 966 | "requires": { 967 | "cookie": "0.4.1", 968 | "cookie-signature": "1.0.6" 969 | } 970 | }, 971 | "cookie-signature": { 972 | "version": "1.0.6", 973 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 974 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 975 | }, 976 | "data-uri-to-buffer": { 977 | "version": "4.0.0", 978 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", 979 | "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==" 980 | }, 981 | "debug": { 982 | "version": "2.6.9", 983 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 984 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 985 | "requires": { 986 | "ms": "2.0.0" 987 | } 988 | }, 989 | "depd": { 990 | "version": "2.0.0", 991 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 992 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 993 | }, 994 | "destroy": { 995 | "version": "1.2.0", 996 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 997 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 998 | }, 999 | "ee-first": { 1000 | "version": "1.1.1", 1001 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1002 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 1003 | }, 1004 | "encodeurl": { 1005 | "version": "1.0.2", 1006 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1007 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 1008 | }, 1009 | "escape-html": { 1010 | "version": "1.0.3", 1011 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1012 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 1013 | }, 1014 | "etag": { 1015 | "version": "1.8.1", 1016 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1017 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 1018 | }, 1019 | "express": { 1020 | "version": "4.18.1", 1021 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", 1022 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", 1023 | "requires": { 1024 | "accepts": "~1.3.8", 1025 | "array-flatten": "1.1.1", 1026 | "body-parser": "1.20.0", 1027 | "content-disposition": "0.5.4", 1028 | "content-type": "~1.0.4", 1029 | "cookie": "0.5.0", 1030 | "cookie-signature": "1.0.6", 1031 | "debug": "2.6.9", 1032 | "depd": "2.0.0", 1033 | "encodeurl": "~1.0.2", 1034 | "escape-html": "~1.0.3", 1035 | "etag": "~1.8.1", 1036 | "finalhandler": "1.2.0", 1037 | "fresh": "0.5.2", 1038 | "http-errors": "2.0.0", 1039 | "merge-descriptors": "1.0.1", 1040 | "methods": "~1.1.2", 1041 | "on-finished": "2.4.1", 1042 | "parseurl": "~1.3.3", 1043 | "path-to-regexp": "0.1.7", 1044 | "proxy-addr": "~2.0.7", 1045 | "qs": "6.10.3", 1046 | "range-parser": "~1.2.1", 1047 | "safe-buffer": "5.2.1", 1048 | "send": "0.18.0", 1049 | "serve-static": "1.15.0", 1050 | "setprototypeof": "1.2.0", 1051 | "statuses": "2.0.1", 1052 | "type-is": "~1.6.18", 1053 | "utils-merge": "1.0.1", 1054 | "vary": "~1.1.2" 1055 | }, 1056 | "dependencies": { 1057 | "cookie": { 1058 | "version": "0.5.0", 1059 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 1060 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 1061 | } 1062 | } 1063 | }, 1064 | "fetch-blob": { 1065 | "version": "3.1.5", 1066 | "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz", 1067 | "integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==", 1068 | "requires": { 1069 | "node-domexception": "^1.0.0", 1070 | "web-streams-polyfill": "^3.0.3" 1071 | } 1072 | }, 1073 | "finalhandler": { 1074 | "version": "1.2.0", 1075 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 1076 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 1077 | "requires": { 1078 | "debug": "2.6.9", 1079 | "encodeurl": "~1.0.2", 1080 | "escape-html": "~1.0.3", 1081 | "on-finished": "2.4.1", 1082 | "parseurl": "~1.3.3", 1083 | "statuses": "2.0.1", 1084 | "unpipe": "~1.0.0" 1085 | } 1086 | }, 1087 | "formdata-polyfill": { 1088 | "version": "4.0.10", 1089 | "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", 1090 | "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", 1091 | "requires": { 1092 | "fetch-blob": "^3.1.2" 1093 | } 1094 | }, 1095 | "forwarded": { 1096 | "version": "0.2.0", 1097 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1098 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 1099 | }, 1100 | "fresh": { 1101 | "version": "0.5.2", 1102 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1103 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 1104 | }, 1105 | "function-bind": { 1106 | "version": "1.1.1", 1107 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1108 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 1109 | }, 1110 | "get-intrinsic": { 1111 | "version": "1.1.2", 1112 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", 1113 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", 1114 | "requires": { 1115 | "function-bind": "^1.1.1", 1116 | "has": "^1.0.3", 1117 | "has-symbols": "^1.0.3" 1118 | } 1119 | }, 1120 | "has": { 1121 | "version": "1.0.3", 1122 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1123 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1124 | "requires": { 1125 | "function-bind": "^1.1.1" 1126 | } 1127 | }, 1128 | "has-symbols": { 1129 | "version": "1.0.3", 1130 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1131 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 1132 | }, 1133 | "http-errors": { 1134 | "version": "2.0.0", 1135 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1136 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1137 | "requires": { 1138 | "depd": "2.0.0", 1139 | "inherits": "2.0.4", 1140 | "setprototypeof": "1.2.0", 1141 | "statuses": "2.0.1", 1142 | "toidentifier": "1.0.1" 1143 | } 1144 | }, 1145 | "iconv-lite": { 1146 | "version": "0.4.24", 1147 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1148 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1149 | "requires": { 1150 | "safer-buffer": ">= 2.1.2 < 3" 1151 | } 1152 | }, 1153 | "inherits": { 1154 | "version": "2.0.4", 1155 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1156 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1157 | }, 1158 | "ipaddr.js": { 1159 | "version": "1.9.1", 1160 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1161 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 1162 | }, 1163 | "media-typer": { 1164 | "version": "0.3.0", 1165 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1166 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 1167 | }, 1168 | "merge-descriptors": { 1169 | "version": "1.0.1", 1170 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1171 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1172 | }, 1173 | "methods": { 1174 | "version": "1.1.2", 1175 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1176 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 1177 | }, 1178 | "mime": { 1179 | "version": "1.6.0", 1180 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1181 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1182 | }, 1183 | "mime-db": { 1184 | "version": "1.52.0", 1185 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1186 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 1187 | }, 1188 | "mime-types": { 1189 | "version": "2.1.35", 1190 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1191 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1192 | "requires": { 1193 | "mime-db": "1.52.0" 1194 | } 1195 | }, 1196 | "ms": { 1197 | "version": "2.0.0", 1198 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1199 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1200 | }, 1201 | "negotiator": { 1202 | "version": "0.6.3", 1203 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1204 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 1205 | }, 1206 | "node-domexception": { 1207 | "version": "1.0.0", 1208 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 1209 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" 1210 | }, 1211 | "node-fetch": { 1212 | "version": "3.2.6", 1213 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", 1214 | "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", 1215 | "requires": { 1216 | "data-uri-to-buffer": "^4.0.0", 1217 | "fetch-blob": "^3.1.4", 1218 | "formdata-polyfill": "^4.0.10" 1219 | } 1220 | }, 1221 | "object-inspect": { 1222 | "version": "1.12.2", 1223 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 1224 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 1225 | }, 1226 | "on-finished": { 1227 | "version": "2.4.1", 1228 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1229 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1230 | "requires": { 1231 | "ee-first": "1.1.1" 1232 | } 1233 | }, 1234 | "parseurl": { 1235 | "version": "1.3.3", 1236 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1237 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1238 | }, 1239 | "path-to-regexp": { 1240 | "version": "0.1.7", 1241 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1242 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1243 | }, 1244 | "proxy-addr": { 1245 | "version": "2.0.7", 1246 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1247 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1248 | "requires": { 1249 | "forwarded": "0.2.0", 1250 | "ipaddr.js": "1.9.1" 1251 | } 1252 | }, 1253 | "qs": { 1254 | "version": "6.10.3", 1255 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 1256 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 1257 | "requires": { 1258 | "side-channel": "^1.0.4" 1259 | } 1260 | }, 1261 | "range-parser": { 1262 | "version": "1.2.1", 1263 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1264 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1265 | }, 1266 | "raw-body": { 1267 | "version": "2.5.1", 1268 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1269 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1270 | "requires": { 1271 | "bytes": "3.1.2", 1272 | "http-errors": "2.0.0", 1273 | "iconv-lite": "0.4.24", 1274 | "unpipe": "1.0.0" 1275 | } 1276 | }, 1277 | "safe-buffer": { 1278 | "version": "5.2.1", 1279 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1280 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1281 | }, 1282 | "safer-buffer": { 1283 | "version": "2.1.2", 1284 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1285 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1286 | }, 1287 | "send": { 1288 | "version": "0.18.0", 1289 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1290 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1291 | "requires": { 1292 | "debug": "2.6.9", 1293 | "depd": "2.0.0", 1294 | "destroy": "1.2.0", 1295 | "encodeurl": "~1.0.2", 1296 | "escape-html": "~1.0.3", 1297 | "etag": "~1.8.1", 1298 | "fresh": "0.5.2", 1299 | "http-errors": "2.0.0", 1300 | "mime": "1.6.0", 1301 | "ms": "2.1.3", 1302 | "on-finished": "2.4.1", 1303 | "range-parser": "~1.2.1", 1304 | "statuses": "2.0.1" 1305 | }, 1306 | "dependencies": { 1307 | "ms": { 1308 | "version": "2.1.3", 1309 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1310 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1311 | } 1312 | } 1313 | }, 1314 | "serve-static": { 1315 | "version": "1.15.0", 1316 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1317 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1318 | "requires": { 1319 | "encodeurl": "~1.0.2", 1320 | "escape-html": "~1.0.3", 1321 | "parseurl": "~1.3.3", 1322 | "send": "0.18.0" 1323 | } 1324 | }, 1325 | "setprototypeof": { 1326 | "version": "1.2.0", 1327 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1328 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1329 | }, 1330 | "side-channel": { 1331 | "version": "1.0.4", 1332 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1333 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1334 | "requires": { 1335 | "call-bind": "^1.0.0", 1336 | "get-intrinsic": "^1.0.2", 1337 | "object-inspect": "^1.9.0" 1338 | } 1339 | }, 1340 | "statuses": { 1341 | "version": "2.0.1", 1342 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1343 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 1344 | }, 1345 | "toidentifier": { 1346 | "version": "1.0.1", 1347 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1348 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1349 | }, 1350 | "type-is": { 1351 | "version": "1.6.18", 1352 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1353 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1354 | "requires": { 1355 | "media-typer": "0.3.0", 1356 | "mime-types": "~2.1.24" 1357 | } 1358 | }, 1359 | "unpipe": { 1360 | "version": "1.0.0", 1361 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1362 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1363 | }, 1364 | "utils-merge": { 1365 | "version": "1.0.1", 1366 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1367 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1368 | }, 1369 | "vary": { 1370 | "version": "1.1.2", 1371 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1372 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1373 | }, 1374 | "web-streams-polyfill": { 1375 | "version": "3.2.1", 1376 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", 1377 | "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" 1378 | }, 1379 | "ws": { 1380 | "version": "8.8.0", 1381 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", 1382 | "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", 1383 | "requires": {} 1384 | } 1385 | } 1386 | } 1387 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nginx-config-gui", 3 | "version": "1.0.0", 4 | "description": "This is a Web-Interface for nginx. However: I will only use this to create subdomains for my services.", 5 | "main": "main.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "nodemon ." 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Proxtx/nginx-config-gui.git" 13 | }, 14 | "author": "Proxtx", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/Proxtx/nginx-config-gui/issues" 18 | }, 19 | "homepage": "https://github.com/Proxtx/nginx-config-gui#readme", 20 | "dependencies": { 21 | "@proxtx/config": "^1.0.2", 22 | "@proxtx/framework": "^1.4.3", 23 | "@proxtx/material": "^1.0.865" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/config.js: -------------------------------------------------------------------------------- 1 | import config from "@proxtx/config"; 2 | import fs from "fs/promises"; 3 | import { exec } from "child_process"; 4 | 5 | export const checkPwd = (pwd) => { 6 | if (pwd == config.pwd) return true; 7 | return false; 8 | }; 9 | 10 | export const saveConfigFile = async (pwd) => { 11 | if (!checkPwd(pwd)) return; 12 | let blocks = await loadBlocks(); 13 | let blockTemplate = await loadTextFile("block.txt"); 14 | let defaultFile = await loadTextFile("defaultFile.txt"); 15 | 16 | let finalBlocksConfig = ""; 17 | for (let block of blocks) { 18 | let blockData = blockTemplate; 19 | for (let overwrite of block.overwrites) { 20 | blockData = blockData.replace(overwrite.overwrite, overwrite.data); 21 | } 22 | finalBlocksConfig += blockData; 23 | } 24 | 25 | let finalConfigFile = defaultFile.replace("$customBlocks", finalBlocksConfig); 26 | await saveTextFile(config.resultFile, finalConfigFile); 27 | 28 | reloadNginx(); 29 | }; 30 | 31 | const reloadNginx = () => { 32 | exec( 33 | config.restartNginx, 34 | (error) => { 35 | console.log(error); 36 | }, 37 | (stdOut) => { 38 | console.log(stdOut); 39 | }, 40 | (stdErr) => { 41 | console.log(stdErr); 42 | } 43 | ); 44 | }; 45 | 46 | export const loadBlock = async (pwd, name) => { 47 | if (!checkPwd(pwd)) return; 48 | let blocks = await loadBlocks(); 49 | for (let block of blocks) { 50 | if (block.name == name) return block; 51 | } 52 | }; 53 | 54 | export const saveBlock = async (pwd, block) => { 55 | if (!checkPwd(pwd)) return; 56 | let blocks = await loadBlocks(); 57 | for (let blockIndex in blocks) { 58 | if (blocks[blockIndex].name == block.name) blocks[blockIndex] = block; 59 | } 60 | 61 | await saveBlocks(blocks); 62 | }; 63 | 64 | export const createBlock = async (pwd, name) => { 65 | if (!checkPwd(pwd)) return; 66 | let blocks = await loadBlocks(); 67 | blocks.push({ 68 | name, 69 | overwrites: [], 70 | }); 71 | 72 | await saveBlocks(blocks); 73 | }; 74 | 75 | export const deleteBlock = async (pwd, name) => { 76 | if (!checkPwd(pwd)) return; 77 | let blocks = await loadBlocks(); 78 | for (let blockIndex in blocks) { 79 | if (blocks[blockIndex].name == name) blocks.splice(blockIndex, 1); 80 | } 81 | 82 | await saveBlocks(blocks); 83 | reloadNginx(); 84 | }; 85 | 86 | export const listBlocks = async (pwd) => { 87 | if (!checkPwd(pwd)) return; 88 | let blocks = await loadBlocks(); 89 | let blockNames = []; 90 | for (let block of blocks) { 91 | blockNames.push(block.name); 92 | } 93 | 94 | return blockNames; 95 | }; 96 | 97 | export const blockAttributes = (pwd) => { 98 | if (!checkPwd(pwd)) return; 99 | return config.replace; 100 | }; 101 | 102 | const loadBlocks = async () => { 103 | return JSON.parse(await fs.readFile("blocks.json", "utf-8")).blocks; 104 | }; 105 | 106 | const saveBlocks = async (blocks) => { 107 | await fs.writeFile("blocks.json", JSON.stringify({ blocks })); 108 | }; 109 | 110 | const loadTextFile = async (name) => { 111 | return await fs.readFile(name, "utf-8"); 112 | }; 113 | 114 | const saveTextFile = async (name, data) => { 115 | await fs.writeFile(name, data); 116 | }; 117 | -------------------------------------------------------------------------------- /static/edit/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Edit Config 8 | 9 | 10 | 11 | 17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 | BackDeleteSave Changes 28 |
29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /static/edit/main.js: -------------------------------------------------------------------------------- 1 | let config = await framework.load("config.js"); 2 | 3 | let block = await config.loadBlock(cookie.pwd, cookie.name); 4 | let attributes = await config.blockAttributes(cookie.pwd); 5 | 6 | document.getElementById("name").innerText = cookie.name; 7 | 8 | let inputWrap = document.getElementById("inputWrap"); 9 | 10 | const generateAttribute = async (attribute) => { 11 | let matchingOverwrite; 12 | 13 | for (let overwrite of block.overwrites) { 14 | if (overwrite.overwrite == attribute.replace) { 15 | matchingOverwrite = overwrite; 16 | } 17 | } 18 | 19 | if (!matchingOverwrite) { 20 | matchingOverwrite = { 21 | data: "", 22 | overwrite: attribute.replace, 23 | }; 24 | block.overwrites.push(matchingOverwrite); 25 | } 26 | 27 | let input = document.createElement("m-text-input"); 28 | input.setAttribute("placeholder", attribute.name); 29 | input.setAttribute( 30 | "value", 31 | matchingOverwrite.data 32 | ? matchingOverwrite.data 33 | : attribute.default 34 | ? attribute.default 35 | : "" 36 | ); 37 | 38 | inputWrap.appendChild(input); 39 | 40 | input.addEventListener("change", () => { 41 | matchingOverwrite.data = input.component.value; 42 | }); 43 | 44 | return { attribute, overwrite: matchingOverwrite, input }; 45 | }; 46 | 47 | let attributesGenerated = []; 48 | 49 | for (let attribute of attributes) { 50 | attributesGenerated.push(generateAttribute(attribute)); 51 | } 52 | 53 | const deleteBlock = async () => { 54 | await new Promise((r) => setTimeout(r, 500)); 55 | await config.deleteBlock(cookie.pwd, cookie.name); 56 | await config.saveConfigFile(cookie.pwd); 57 | location.pathname += "../"; 58 | }; 59 | 60 | window.goBack = async () => { 61 | await new Promise((r) => setTimeout(r, 500)); 62 | location.pathname += "../"; 63 | }; 64 | 65 | window.deleteBlock = deleteBlock; 66 | 67 | const saveBlock = async () => { 68 | await new Promise((r) => setTimeout(r, 500)); 69 | await config.saveBlock(cookie.pwd, block); 70 | await config.saveConfigFile(cookie.pwd); 71 | location.pathname += "../"; 72 | }; 73 | 74 | window.saveBlock = saveBlock; 75 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Proxtx/nginx-config-gui/dae466b2fae93912df39299a595a5a8516a038ec/static/favicon.ico -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Nginx Config 8 | 9 | 10 | 11 | 17 |
18 |
19 |
20 | Logout 21 | Create New 22 |
23 |
24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /static/lib/guiLoader.js: -------------------------------------------------------------------------------- 1 | window.guiLoaded = []; 2 | 3 | import { loadPack } from "/modules/uibuilder/main.js"; 4 | 5 | await loadPack("/modules/material/components/pack.json", { 6 | urlPrefix: "/modules/material/", 7 | customStyleSheets: ["../../lib/materialUIOverwrite.css"], 8 | }); 9 | 10 | for (let i of guiLoaded) { 11 | i(); 12 | } 13 | -------------------------------------------------------------------------------- /static/lib/icon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Proxtx/nginx-config-gui/dae466b2fae93912df39299a595a5a8516a038ec/static/lib/icon/favicon.png -------------------------------------------------------------------------------- /static/lib/icon/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 36 | 38 | 42 | 50 | 52 | 55 | 63 | 70 | 71 | 74 | 82 | 89 | 90 | 93 | 101 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /static/lib/main.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --accentColor: #009639; 3 | 4 | --darkGrey: #565656; 5 | --grey: #c2c2c2; 6 | --lightGrey: #d9d9d9; 7 | 8 | --text-color: black; 9 | --titleColor: white; 10 | 11 | --headerHeight: 120px; 12 | --borderRadius: 6px; 13 | } 14 | 15 | body { 16 | margin: 0; 17 | color: var(--text-color); 18 | font-family: sans-serif; 19 | background-color: var(--lightGrey); 20 | } 21 | 22 | #header { 23 | width: 100%; 24 | height: var(--headerHeight); 25 | background-color: var(--darkGrey); 26 | display: flex; 27 | align-items: center; 28 | justify-content: center; 29 | } 30 | 31 | #titleWrap { 32 | display: flex; 33 | align-items: center; 34 | justify-content: center; 35 | gap: 10px; 36 | } 37 | 38 | #title1 { 39 | color: var(--accentColor); 40 | } 41 | 42 | #title2 { 43 | color: var(--titleColor); 44 | } 45 | 46 | .contentWrap { 47 | padding: 20px; 48 | width: 100%; 49 | height: calc(100% - var(--headerHeight)); 50 | box-sizing: border-box; 51 | display: flex; 52 | flex-direction: column; 53 | gap: 15px; 54 | } 55 | 56 | .table { 57 | background-color: var(--grey); 58 | border-radius: var(--borderRadius); 59 | display: flex; 60 | flex-direction: column; 61 | width: 100%; 62 | position: relative; 63 | overflow: hidden; 64 | } 65 | 66 | .tableEntry { 67 | padding: 15px; 68 | width: 100%; 69 | border-bottom: 1px solid var(--darkGrey); 70 | box-sizing: border-box; 71 | cursor: pointer; 72 | } 73 | 74 | .toRight { 75 | display: flex; 76 | flex-direction: row; 77 | gap: 10px; 78 | justify-content: flex-end; 79 | width: 100%; 80 | } 81 | 82 | m-text-input { 83 | display: inline-block; 84 | margin: 7px; 85 | } 86 | -------------------------------------------------------------------------------- /static/lib/materialUIOverwrite.css: -------------------------------------------------------------------------------- 1 | :host { 2 | --accentColor: #009639; 3 | --backgroundColor: #d9d9d9; 4 | } 5 | -------------------------------------------------------------------------------- /static/login/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login 8 | 9 | 10 | 11 | 17 |
18 |

Login

19 | Login 25 |
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /static/login/main.js: -------------------------------------------------------------------------------- 1 | let config = await framework.load("config.js"); 2 | 3 | let input = document.getElementById("input"); 4 | 5 | window.login = async () => { 6 | await new Promise((r) => setTimeout(r, 500)); 7 | cookie.pwd = input.component.value; 8 | if (await config.checkPwd(input.component.value)) location.pathname += "../"; 9 | input.component.value = ""; 10 | }; 11 | -------------------------------------------------------------------------------- /static/main.js: -------------------------------------------------------------------------------- 1 | let config = await framework.load("config.js"); 2 | 3 | if (!(await config.checkPwd(cookie.pwd))) location.href = "login"; 4 | 5 | let blockNames = await config.listBlocks(cookie.pwd); 6 | 7 | let table = document.getElementById("table"); 8 | 9 | for (let blockName of blockNames) { 10 | let localName = blockName; 11 | let wrap = document.createElement("div"); 12 | wrap.className = "tableEntry"; 13 | let name = document.createElement("a"); 14 | name.innerText = blockName; 15 | wrap.appendChild(name); 16 | wrap.addEventListener("click", () => { 17 | openEdit(localName); 18 | }); 19 | table.appendChild(wrap); 20 | } 21 | 22 | const openEdit = (name) => { 23 | cookie.name = name; 24 | location.pathname += "edit"; 25 | }; 26 | 27 | const createNew = async () => { 28 | await new Promise((r) => setTimeout(r, 500)); 29 | let name = prompt("Name"); 30 | await config.createBlock(cookie.pwd, name); 31 | openEdit(name); 32 | }; 33 | 34 | window.createNew = createNew; 35 | 36 | window.logout = async () => { 37 | await new Promise((r) => setTimeout(r, 500)); 38 | cookie.pwd = ""; 39 | location.href = location.href; 40 | }; 41 | --------------------------------------------------------------------------------