feature: port check with online services

damienzonly committed Aug 15, 2023 at 23:14 UTC 6c8fe50d5e679bdcf00d9aa158bdbadbaada9620
5 files changed +357 -11
central.json
+22 -1
@@ -1 +1,22 @@
1 -{}
\ No newline at end of file
1 +{
2 + "checkServerServices": [
3 + {
4 + "url": "https://ports.yougetsignal.com/check-port.php",
5 + "headers": {"content-type": "application/x-www-form-urlencoded"},
6 + "method": "POST",
7 + "selector": "p:nth-child(1)",
8 + "body": "remoteAddress=$IP&portNumber=$PORT",
9 + "regexpFailure": "is closed",
10 + "regexpSuccess": "is open"
11 + },
12 + {
13 + "url": "https://canyouseeme.org/",
14 + "headers": {"content-type": "application/x-www-form-urlencoded"},
15 + "method": "POST",
16 + "selector": "div.tool > p:nth-child(1)",
17 + "body": "port=$PORT",
18 + "regexpFailure": "I could not see your service",
19 + "regexpSuccess": "I can see your service"
20 + }
21 + ]
22 +}
package-lock.json
+284 -8
@@ -31,6 +31,8 @@
31 "limiter": "^2.1.0",
32 "lodash": "^4.17.21",
33 "minimist": "^1.2.6",
34 + "nat-upnp": "github:kaden-sharpin/node-nat-upnp",
35 + "node-html-parser": "^6.1.5",
36 "open": "^8.4.0",
37 "tssrp6a": "^3.0.0",
38 "unzip-stream": "^0.3.1",
@@ -105,6 +107,31 @@
107 "vite-plugin-babel-import": "github:rejetto/vite-plugin-babel-import"
108 }
109 },
110 + "admin/node_modules/@mui/icons-material": {
111 + "version": "5.8.4",
112 + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz",
113 + "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==",
114 + "dependencies": {
115 + "@babel/runtime": "^7.17.2"
116 + },
117 + "engines": {
118 + "node": ">=12.0.0"
119 + },
120 + "funding": {
121 + "type": "opencollective",
122 + "url": "https://opencollective.com/mui"
123 + },
124 + "peerDependencies": {
125 + "@mui/material": "^5.0.0",
126 + "@types/react": "^17.0.0 || ^18.0.0",
127 + "react": "^17.0.0 || ^18.0.0"
128 + },
129 + "peerDependenciesMeta": {
130 + "@types/react": {
131 + "optional": true
132 + }
133 + }
134 + },
135 "frontend": {
136 "name": "@hfs/frontend",
137 "dependencies": {
@@ -2184,7 +2211,6 @@
2211 "version": "0.24.0",
2212 "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
2213 "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
2187 - "dev": true,
2214 "dependencies": {
2215 "follow-redirects": "^1.14.4"
2216 }
@@ -2304,6 +2330,11 @@
2330 "node": ">= 6"
2331 }
2332 },
2333 + "node_modules/boolbase": {
2334 + "version": "1.0.0",
2335 + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
2336 + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
2337 + },
2338 "node_modules/brace-expansion": {
2339 "version": "1.1.11",
2340 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2781,6 +2812,32 @@
2812 "node": ">= 8"
2813 }
2814 },
2815 + "node_modules/css-select": {
2816 + "version": "5.1.0",
2817 + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
2818 + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
2819 + "dependencies": {
2820 + "boolbase": "^1.0.0",
2821 + "css-what": "^6.1.0",
2822 + "domhandler": "^5.0.2",
2823 + "domutils": "^3.0.1",
2824 + "nth-check": "^2.0.1"
2825 + },
2826 + "funding": {
2827 + "url": "https://github.com/sponsors/fb55"
2828 + }
2829 + },
2830 + "node_modules/css-what": {
2831 + "version": "6.1.0",
2832 + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
2833 + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
2834 + "engines": {
2835 + "node": ">= 6"
2836 + },
2837 + "funding": {
2838 + "url": "https://github.com/sponsors/fb55"
2839 + }
2840 + },
2841 "node_modules/csstype": {
2842 "version": "3.1.2",
2843 "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
@@ -2943,6 +3000,57 @@
3000 "csstype": "^3.0.2"
3001 }
3002 },
3003 + "node_modules/dom-serializer": {
3004 + "version": "2.0.0",
3005 + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
3006 + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
3007 + "dependencies": {
3008 + "domelementtype": "^2.3.0",
3009 + "domhandler": "^5.0.2",
3010 + "entities": "^4.2.0"
3011 + },
3012 + "funding": {
3013 + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
3014 + }
3015 + },
3016 + "node_modules/domelementtype": {
3017 + "version": "2.3.0",
3018 + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
3019 + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
3020 + "funding": [
3021 + {
3022 + "type": "github",
3023 + "url": "https://github.com/sponsors/fb55"
3024 + }
3025 + ]
3026 + },
3027 + "node_modules/domhandler": {
3028 + "version": "5.0.3",
3029 + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
3030 + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
3031 + "dependencies": {
3032 + "domelementtype": "^2.3.0"
3033 + },
3034 + "engines": {
3035 + "node": ">= 4"
3036 + },
3037 + "funding": {
3038 + "url": "https://github.com/fb55/domhandler?sponsor=1"
3039 + }
3040 + },
3041 + "node_modules/domutils": {
3042 + "version": "3.1.0",
3043 + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
3044 + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
3045 + "dependencies": {
3046 + "dom-serializer": "^2.0.0",
3047 + "domelementtype": "^2.3.0",
3048 + "domhandler": "^5.0.3"
3049 + },
3050 + "funding": {
3051 + "url": "https://github.com/fb55/domutils?sponsor=1"
3052 + }
3053 + },
3054 "node_modules/dot-case": {
3055 "version": "3.0.4",
3056 "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
@@ -2999,6 +3107,17 @@
3107 "node": ">=8.6"
3108 }
3109 },
3110 + "node_modules/entities": {
3111 + "version": "4.5.0",
3112 + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
3113 + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
3114 + "engines": {
3115 + "node": ">=0.12"
3116 + },
3117 + "funding": {
3118 + "url": "https://github.com/fb55/entities?sponsor=1"
3119 + }
3120 + },
3121 "node_modules/error-ex": {
3122 "version": "1.3.2",
3123 "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3099,6 +3218,27 @@
3218 "node": ">=8.6.0"
3219 }
3220 },
3221 + "node_modules/fast-xml-parser": {
3222 + "version": "4.2.7",
3223 + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
3224 + "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
3225 + "funding": [
3226 + {
3227 + "type": "paypal",
3228 + "url": "https://paypal.me/naturalintelligence"
3229 + },
3230 + {
3231 + "type": "github",
3232 + "url": "https://github.com/sponsors/NaturalIntelligence"
3233 + }
3234 + ],
3235 + "dependencies": {
3236 + "strnum": "^1.0.5"
3237 + },
3238 + "bin": {
3239 + "fxparser": "src/cli/cli.js"
3240 + }
3241 + },
3242 "node_modules/fastq": {
3243 "version": "1.15.0",
3244 "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@@ -3165,7 +3305,6 @@
3305 "version": "1.15.2",
3306 "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
3307 "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
3168 - "dev": true,
3308 "funding": [
3309 {
3310 "type": "individual",
@@ -3432,7 +3571,6 @@
3571 "version": "1.2.0",
3572 "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
3573 "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
3435 - "dev": true,
3574 "bin": {
3575 "he": "bin/he"
3576 }
@@ -4514,6 +4652,14 @@
4652 "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
4653 "dev": true
4654 },
4655 + "node_modules/nat-upnp": {
4656 + "version": "2.0.0",
4657 + "resolved": "git+ssh://git@github.com/kaden-sharpin/node-nat-upnp.git#b669e33632ef5f3ec49203de82e684d255534746",
4658 + "dependencies": {
4659 + "axios": "^0.24.0",
4660 + "fast-xml-parser": "^4.0.0-beta.8"
4661 + }
4662 + },
4663 "node_modules/negotiator": {
4664 "version": "0.6.3",
4665 "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -4599,6 +4745,15 @@
4745 }
4746 }
4747 },
4748 + "node_modules/node-html-parser": {
4749 + "version": "6.1.5",
4750 + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
4751 + "integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
4752 + "dependencies": {
4753 + "css-select": "^5.1.0",
4754 + "he": "1.2.0"
4755 + }
4756 + },
4757 "node_modules/nodemon": {
4758 "version": "2.0.22",
4759 "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
@@ -4723,6 +4878,17 @@
4878 "node": ">=0.10.0"
4879 }
4880 },
4881 + "node_modules/nth-check": {
4882 + "version": "2.1.1",
4883 + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
4884 + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
4885 + "dependencies": {
4886 + "boolbase": "^1.0.0"
4887 + },
4888 + "funding": {
4889 + "url": "https://github.com/fb55/nth-check?sponsor=1"
4890 + }
4891 + },
4892 "node_modules/object-assign": {
4893 "version": "4.1.1",
4894 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -6061,6 +6227,11 @@
6227 "url": "https://github.com/sponsors/sindresorhus"
6228 }
6229 },
6230 + "node_modules/strnum": {
6231 + "version": "1.0.5",
6232 + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
6233 + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
6234 + },
6235 "node_modules/stylis": {
6236 "version": "4.1.3",
6237 "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
@@ -7345,6 +7516,16 @@
7516 "vite": "^4.0.4",
7517 "vite-plugin-babel-import": "github:rejetto/vite-plugin-babel-import",
7518 "web-vitals": "^2.1.4"
7519 + },
7520 + "dependencies": {
7521 + "@mui/icons-material": {
7522 + "version": "5.8.4",
7523 + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz",
7524 + "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==",
7525 + "requires": {
7526 + "@babel/runtime": "^7.17.2"
7527 + }
7528 + }
7529 }
7530 },
7531 "@hfs/frontend": {
@@ -8191,7 +8372,6 @@
8372 "version": "0.24.0",
8373 "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
8374 "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
8194 - "dev": true,
8375 "requires": {
8376 "follow-redirects": "^1.14.4"
8377 }
@@ -8273,6 +8453,11 @@
8453 }
8454 }
8455 },
8456 + "boolbase": {
8457 + "version": "1.0.0",
8458 + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
8459 + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
8460 + },
8461 "brace-expansion": {
8462 "version": "1.1.11",
8463 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -8626,6 +8811,23 @@
8811 "which": "^2.0.1"
8812 }
8813 },
8814 + "css-select": {
8815 + "version": "5.1.0",
8816 + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
8817 + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
8818 + "requires": {
8819 + "boolbase": "^1.0.0",
8820 + "css-what": "^6.1.0",
8821 + "domhandler": "^5.0.2",
8822 + "domutils": "^3.0.1",
8823 + "nth-check": "^2.0.1"
8824 + }
8825 + },
8826 + "css-what": {
8827 + "version": "6.1.0",
8828 + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
8829 + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
8830 + },
8831 "csstype": {
8832 "version": "3.1.2",
8833 "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
@@ -8742,6 +8944,39 @@
8944 "csstype": "^3.0.2"
8945 }
8946 },
8947 + "dom-serializer": {
8948 + "version": "2.0.0",
8949 + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
8950 + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
8951 + "requires": {
8952 + "domelementtype": "^2.3.0",
8953 + "domhandler": "^5.0.2",
8954 + "entities": "^4.2.0"
8955 + }
8956 + },
8957 + "domelementtype": {
8958 + "version": "2.3.0",
8959 + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
8960 + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
8961 + },
8962 + "domhandler": {
8963 + "version": "5.0.3",
8964 + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
8965 + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
8966 + "requires": {
8967 + "domelementtype": "^2.3.0"
8968 + }
8969 + },
8970 + "domutils": {
8971 + "version": "3.1.0",
8972 + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
8973 + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
8974 + "requires": {
8975 + "dom-serializer": "^2.0.0",
8976 + "domelementtype": "^2.3.0",
8977 + "domhandler": "^5.0.3"
8978 + }
8979 + },
8980 "dot-case": {
8981 "version": "3.0.4",
8982 "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
@@ -8792,6 +9027,11 @@
9027 "ansi-colors": "^4.1.1"
9028 }
9029 },
9030 + "entities": {
9031 + "version": "4.5.0",
9032 + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
9033 + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
9034 + },
9035 "error-ex": {
9036 "version": "1.3.2",
9037 "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -8870,6 +9110,14 @@
9110 "micromatch": "^4.0.4"
9111 }
9112 },
9113 + "fast-xml-parser": {
9114 + "version": "4.2.7",
9115 + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
9116 + "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
9117 + "requires": {
9118 + "strnum": "^1.0.5"
9119 + }
9120 + },
9121 "fastq": {
9122 "version": "1.15.0",
9123 "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@@ -8920,8 +9168,7 @@
9168 "follow-redirects": {
9169 "version": "1.15.2",
9170 "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
8923 - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
8924 - "dev": true
9171 + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
9172 },
9173 "formidable": {
9174 "version": "2.1.2",
@@ -9111,8 +9358,7 @@
9358 "he": {
9359 "version": "1.2.0",
9360 "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
9114 - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
9115 - "dev": true
9361 + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
9362 },
9363 "header-case": {
9364 "version": "2.0.4",
@@ -9914,6 +10160,14 @@
10160 "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
10161 "dev": true
10162 },
10163 + "nat-upnp": {
10164 + "version": "git+ssh://git@github.com/kaden-sharpin/node-nat-upnp.git#b669e33632ef5f3ec49203de82e684d255534746",
10165 + "from": "nat-upnp@github:kaden-sharpin/node-nat-upnp",
10166 + "requires": {
10167 + "axios": "^0.24.0",
10168 + "fast-xml-parser": "^4.0.0-beta.8"
10169 + }
10170 + },
10171 "negotiator": {
10172 "version": "0.6.3",
10173 "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -9972,6 +10226,15 @@
10226 "whatwg-url": "^5.0.0"
10227 }
10228 },
10229 + "node-html-parser": {
10230 + "version": "6.1.5",
10231 + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
10232 + "integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
10233 + "requires": {
10234 + "css-select": "^5.1.0",
10235 + "he": "1.2.0"
10236 + }
10237 + },
10238 "nodemon": {
10239 "version": "2.0.22",
10240 "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
@@ -10063,6 +10326,14 @@
10326 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
10327 "dev": true
10328 },
10329 + "nth-check": {
10330 + "version": "2.1.1",
10331 + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
10332 + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
10333 + "requires": {
10334 + "boolbase": "^1.0.0"
10335 + }
10336 + },
10337 "object-assign": {
10338 "version": "4.1.1",
10339 "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -11047,6 +11318,11 @@
11318 "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
11319 "dev": true
11320 },
11321 + "strnum": {
11322 + "version": "1.0.5",
11323 + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
11324 + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
11325 + },
11326 "stylis": {
11327 "version": "4.1.3",
11328 "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
package.json
+7 -1
@@ -9,7 +9,12 @@
9 "homepage": "https://rejetto.com/hfs",
10 "license": "GPL-3.0",
11 "author": "Massimo Melina <a@rejetto.com>",
12 - "workspaces": [ "admin", "frontend", "shared", "mui-grid-form" ],
12 + "workspaces": [
13 + "admin",
14 + "frontend",
15 + "shared",
16 + "mui-grid-form"
17 + ],
18 "scripts": {
19 "watch-server": "cross-env DEV=1 nodemon --ignore tests/ --watch src -e ts,tsx --exec ts-node src",
20 "watch-server-proxied": "cross-env FRONTEND_PROXY=3005 ADMIN_PROXY=3006 npm run watch-server",
@@ -78,6 +83,7 @@
83 "lodash": "^4.17.21",
84 "minimist": "^1.2.6",
85 "nat-upnp": "github:kaden-sharpin/node-nat-upnp",
86 + "node-html-parser": "^6.1.5",
87 "open": "^8.4.0",
88 "tssrp6a": "^3.0.0",
89 "unzip-stream": "^0.3.1",
src/api.net.ts
+43 -1
@@ -1,7 +1,23 @@
1 // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 -import { ApiHandlers } from './apiMiddleware'
3 +import { ApiError, ApiHandlers } from './apiMiddleware'
4 import { Client } from 'nat-upnp'
5 +import { HTTP_SERVICE_UNAVAILABLE } from './const'
6 +import axios from 'axios'
7 +import {parse} from 'node-html-parser'
8 +import _ from 'lodash'
9 +import { getServerStatus } from './listen'
10 +import { getProjectInfo } from './github'
11 +
12 +export interface PortScannerService {
13 + url: string
14 + headers: {[k: string]: any}
15 + method: string
16 + selector: string
17 + body?: string
18 + regexpFailure: string
19 + regexpSuccess: string
20 +}
21
22 const apis: ApiHandlers = {
23
@@ -15,6 +31,32 @@ const apis: ApiHandlers = {
31 }
32 },
33
34 + async check_server() {
35 + const noop = () => null;
36 + const client = new Client()
37 + const publicIp = await client.getPublicIp().catch(noop)
38 + if (publicIp === null) return new ApiError(HTTP_SERVICE_UNAVAILABLE, 'cannot detect public ip')
39 + const {http, https} = await getServerStatus()
40 + const port = https.port > 0 ? https.port : http.port
41 + const prjInfo = await getProjectInfo()
42 + for (const svc of _.shuffle<PortScannerService>(prjInfo.checkServerServices)) {
43 + const api = (axios as any)[svc.method.toLowerCase()]
44 + const body = (svc.body || "")
45 + .replace('$IP', publicIp)
46 + .replace('$PORT', port)
47 + const res = await api(svc.url, body, {headers: svc.headers}).catch(noop)
48 + if (res == null) continue
49 + const parsed = parse(res.data).querySelector(svc.selector)?.innerText
50 + if (!parsed) continue
51 + const result = new RegExp(svc.regexpSuccess).test(parsed)
52 + const ftest = new RegExp(svc.regexpFailure).test(parsed)
53 + if (result === ftest) continue;
54 + const service = new URL(svc.url).hostname
55 + return {result, service}
56 + }
57 + return new ApiError(HTTP_SERVICE_UNAVAILABLE, 'no service available to detect upnp mapping')
58 + }
59 +
60 }
61
62 export default apis
\ No newline at end of file
src/const.ts
+1
@@ -45,6 +45,7 @@ export const HTTP_RANGE_NOT_SATISFIABLE = 416
45 export const HTTP_FOOL = 418
46 export const HTTP_FAILED_DEPENDENCY = 424
47 export const HTTP_SERVER_ERROR = 500
48 +export const HTTP_SERVICE_UNAVAILABLE = 503
49
50 export const IS_WINDOWS = process.platform === 'win32'
51 export const IS_BINARY = !basename(process.execPath).includes('node') // this won't be node if pkg was used